Commit b5cbcb35 authored by titzer's avatar titzer Committed by Commit bot

[asm.js] (Re)use temporaries in asm->wasm conversion.

This CL is a prequisite for the stack machine changes, which will need
to use temporaries in various places due to the stack height requirements
on blocks.

R=ahaas@chromium.org,bradnelson@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2280063002
Cr-Commit-Position: refs/heads/master@{#39001}
parent 88d603bb
......@@ -1099,11 +1099,11 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
}
case AsmTyper::kMathAbs: {
if (call_type == kAstI32) {
uint32_t tmp = current_function_builder_->AddLocal(kAstI32);
WasmTemporary tmp(current_function_builder_, kAstI32);
// if set_local(tmp, x) < 0
Visit(call->arguments()->at(0));
current_function_builder_->EmitSetLocal(tmp);
current_function_builder_->EmitSetLocal(tmp.index());
byte code[] = {WASM_I8(0)};
current_function_builder_->EmitCode(code, sizeof(code));
current_function_builder_->Emit(kExprI32LtS);
......@@ -1111,12 +1111,12 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
// then (0 - tmp)
current_function_builder_->EmitCode(code, sizeof(code));
current_function_builder_->EmitGetLocal(tmp);
current_function_builder_->EmitGetLocal(tmp.index());
current_function_builder_->Emit(kExprI32Sub);
// else tmp
current_function_builder_->Emit(kExprElse);
current_function_builder_->EmitGetLocal(tmp);
current_function_builder_->EmitGetLocal(tmp.index());
// end
current_function_builder_->Emit(kExprEnd);
......@@ -1134,25 +1134,25 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
case AsmTyper::kMathMin: {
// TODO(bradnelson): Change wasm to match Math.min in asm.js mode.
if (call_type == kAstI32) {
uint32_t tmp_x = current_function_builder_->AddLocal(kAstI32);
uint32_t tmp_y = current_function_builder_->AddLocal(kAstI32);
WasmTemporary tmp_x(current_function_builder_, kAstI32);
WasmTemporary tmp_y(current_function_builder_, kAstI32);
// if set_local(tmp_x, x) < set_local(tmp_y, y)
Visit(call->arguments()->at(0));
current_function_builder_->EmitSetLocal(tmp_x);
current_function_builder_->EmitSetLocal(tmp_x.index());
Visit(call->arguments()->at(1));
current_function_builder_->EmitSetLocal(tmp_y);
current_function_builder_->EmitSetLocal(tmp_y.index());
current_function_builder_->Emit(kExprI32LeS);
current_function_builder_->Emit(kExprIf);
// then tmp_x
current_function_builder_->EmitGetLocal(tmp_x);
current_function_builder_->EmitGetLocal(tmp_x.index());
// else tmp_y
current_function_builder_->Emit(kExprElse);
current_function_builder_->EmitGetLocal(tmp_y);
current_function_builder_->EmitGetLocal(tmp_y.index());
current_function_builder_->Emit(kExprEnd);
} else if (call_type == kAstF32) {
......@@ -1169,26 +1169,26 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
case AsmTyper::kMathMax: {
// TODO(bradnelson): Change wasm to match Math.max in asm.js mode.
if (call_type == kAstI32) {
uint32_t tmp_x = current_function_builder_->AddLocal(kAstI32);
uint32_t tmp_y = current_function_builder_->AddLocal(kAstI32);
WasmTemporary tmp_x(current_function_builder_, kAstI32);
WasmTemporary tmp_y(current_function_builder_, kAstI32);
// if set_local(tmp_x, x) < set_local(tmp_y, y)
Visit(call->arguments()->at(0));
current_function_builder_->EmitSetLocal(tmp_x);
current_function_builder_->EmitSetLocal(tmp_x.index());
Visit(call->arguments()->at(1));
current_function_builder_->EmitSetLocal(tmp_y);
current_function_builder_->EmitSetLocal(tmp_y.index());
current_function_builder_->Emit(kExprI32LeS);
current_function_builder_->Emit(kExprIf);
// then tmp_y
current_function_builder_->EmitGetLocal(tmp_y);
current_function_builder_->EmitGetLocal(tmp_y.index());
// else tmp_x
current_function_builder_->Emit(kExprElse);
current_function_builder_->EmitGetLocal(tmp_x);
current_function_builder_->EmitGetLocal(tmp_x.index());
current_function_builder_->Emit(kExprEnd);
} else if (call_type == kAstF32) {
......
......@@ -56,7 +56,11 @@ WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder)
signature_index_(0),
exported_(0),
body_(builder->zone()),
name_(builder->zone()) {}
name_(builder->zone()),
i32_temps_(builder->zone()),
i64_temps_(builder->zone()),
f32_temps_(builder->zone()),
f64_temps_(builder->zone()) {}
void WasmFunctionBuilder::EmitVarInt(uint32_t val) {
byte buffer[8];
......
......@@ -136,12 +136,56 @@ class WasmFunctionBuilder : public ZoneObject {
private:
explicit WasmFunctionBuilder(WasmModuleBuilder* builder);
friend class WasmModuleBuilder;
friend class WasmTemporary;
WasmModuleBuilder* builder_;
LocalDeclEncoder locals_;
uint32_t signature_index_;
bool exported_;
ZoneVector<uint8_t> body_;
ZoneVector<char> name_;
ZoneVector<uint32_t> i32_temps_;
ZoneVector<uint32_t> i64_temps_;
ZoneVector<uint32_t> f32_temps_;
ZoneVector<uint32_t> f64_temps_;
};
class WasmTemporary {
public:
WasmTemporary(WasmFunctionBuilder* builder, LocalType type) {
switch (type) {
case kAstI32:
temporary_ = &builder->i32_temps_;
break;
case kAstI64:
temporary_ = &builder->i64_temps_;
break;
case kAstF32:
temporary_ = &builder->f32_temps_;
break;
case kAstF64:
temporary_ = &builder->f64_temps_;
break;
default:
UNREACHABLE();
temporary_ = nullptr;
}
if (temporary_->size() == 0) {
// Allocate a new temporary.
index_ = builder->AddLocal(type);
} else {
// Reuse a previous temporary.
index_ = temporary_->back();
temporary_->pop_back();
}
}
~WasmTemporary() {
temporary_->push_back(index_); // return the temporary to the list.
}
uint32_t index() { return index_; }
private:
ZoneVector<uint32_t>* temporary_;
uint32_t index_;
};
// TODO(titzer): kill!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment