summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2019-04-22 16:22:10 -0700
committerGitHub <noreply@github.com>2019-04-22 16:22:10 -0700
commit7fe2701d3bcbea625405f7b8c852aa3154face6b (patch)
treead4f4228f293dcbbb4ccb29afaee218d3910c268 /src
parent831a774641b63bc4980eb6e71b1c59d92d19fb4d (diff)
downloadbinaryen-7fe2701d3bcbea625405f7b8c852aa3154face6b.tar.gz
binaryen-7fe2701d3bcbea625405f7b8c852aa3154face6b.tar.bz2
binaryen-7fe2701d3bcbea625405f7b8c852aa3154face6b.zip
wasm2js: remove more code we don't need since we have flat IR (#2039)
Also run remove-unused-names which became more noticeably necessary after this change.
Diffstat (limited to 'src')
-rw-r--r--src/passes/I64ToI32Lowering.cpp120
-rw-r--r--src/wasm2js.h50
2 files changed, 13 insertions, 157 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index f16003745..731b42d3a 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -160,7 +160,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
if (!builder) builder = make_unique<Builder>(*getModule());
indexMap.clear();
highBitVars.clear();
- labelHighBitVars.clear();
freeTemps.clear();
Module temp;
auto* oldFunc = ModuleUtils::copyFunction(func, temp);
@@ -221,124 +220,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
}
- void visitBlock(Block* curr) {
- if (curr->list.size() == 0) return;
- if (handleUnreachable(curr)) return;
- if (curr->type == i64) curr->type = i32;
- auto highBitsIt = labelHighBitVars.find(curr->name);
- if (!hasOutParam(curr->list.back())) {
- if (highBitsIt != labelHighBitVars.end()) {
- setOutParam(curr, std::move(highBitsIt->second));
- }
- return;
- }
- TempVar lastHighBits = fetchOutParam(curr->list.back());
- if (highBitsIt == labelHighBitVars.end() ||
- highBitsIt->second == lastHighBits) {
- setOutParam(curr, std::move(lastHighBits));
- if (highBitsIt != labelHighBitVars.end()) {
- labelHighBitVars.erase(highBitsIt);
- }
- return;
- }
- TempVar highBits = std::move(highBitsIt->second);
- TempVar tmp = getTemp();
- labelHighBitVars.erase(highBitsIt);
- SetLocal* setLow = builder->makeSetLocal(tmp, curr->list.back());
- SetLocal* setHigh = builder->makeSetLocal(
- highBits,
- builder->makeGetLocal(lastHighBits, i32)
- );
- GetLocal* getLow = builder->makeGetLocal(tmp, i32);
- curr->list.back() = builder->blockify(setLow, setHigh, getLow);
- setOutParam(curr, std::move(highBits));
- }
-
- void visitIf(If* curr) {
- if (!hasOutParam(curr->ifTrue)) return;
- assert(curr->ifFalse != nullptr && "Nullable ifFalse found");
- TempVar highBits = fetchOutParam(curr->ifTrue);
- TempVar falseBits = fetchOutParam(curr->ifFalse);
- TempVar tmp = getTemp();
- curr->type = i32;
- curr->ifFalse = builder->blockify(
- builder->makeSetLocal(tmp, curr->ifFalse),
- builder->makeSetLocal(
- highBits,
- builder->makeGetLocal(falseBits, i32)
- ),
- builder->makeGetLocal(tmp, i32)
- );
- setOutParam(curr, std::move(highBits));
- }
-
- void visitLoop(Loop* curr) {
- // TODO: in flat IR, no chance for an out param
- assert(labelHighBitVars.find(curr->name) == labelHighBitVars.end());
- if (curr->type != i64) return;
- curr->type = i32;
- setOutParam(curr, fetchOutParam(curr->body));
- }
-
- void visitBreak(Break* curr) {
- // TODO: in flat IR, no chance for an out param
- if (!hasOutParam(curr->value)) return;
- assert(curr->value != nullptr);
- TempVar valHighBits = fetchOutParam(curr->value);
- auto blockHighBitsIt = labelHighBitVars.find(curr->name);
- if (blockHighBitsIt == labelHighBitVars.end()) {
- labelHighBitVars.emplace(curr->name, std::move(valHighBits));
- curr->type = i32;
- return;
- }
- TempVar blockHighBits = std::move(blockHighBitsIt->second);
- TempVar tmp = getTemp();
- SetLocal* setLow = builder->makeSetLocal(tmp, curr->value);
- SetLocal* setHigh = builder->makeSetLocal(
- blockHighBits,
- builder->makeGetLocal(valHighBits, i32)
- );
- curr->value = builder->makeGetLocal(tmp, i32);
- curr->type = i32;
- replaceCurrent(builder->blockify(setLow, setHigh, curr));
- }
-
- void visitSwitch(Switch* curr) {
- // TODO: in flat IR, no chance for an out param
- if (!hasOutParam(curr->value)) return;
- TempVar outParam = fetchOutParam(curr->value);
- TempVar tmp = getTemp();
- Expression* result = curr;
- std::vector<Name> targets;
- size_t blockID = 0;
- auto processTarget = [&](Name target) -> Name {
- auto labelIt = labelHighBitVars.find(target);
- if (labelIt == labelHighBitVars.end()) {
- labelHighBitVars.emplace(target, getTemp());
- labelIt = labelHighBitVars.find(target);
- }
- Name newLabel("$i64toi32_" + std::string(target.c_str()) +
- "_" + std::to_string(blockID++));
- Block* trampoline = builder->makeBlock(newLabel, result);
- trampoline->type = i32;
- result = builder->blockify(
- builder->makeSetLocal(tmp, trampoline),
- builder->makeSetLocal(
- labelIt->second,
- builder->makeGetLocal(outParam, i32)
- ),
- builder->makeBreak(target, builder->makeGetLocal(tmp, i32))
- );
- return newLabel;
- };
- for (auto target : curr->targets) {
- targets.push_back(processTarget(target));
- }
- curr->targets.set(targets);
- curr->default_ = processTarget(curr->default_);
- replaceCurrent(result);
- }
-
template<typename T>
using BuilderFunc = std::function<T*(std::vector<Expression*>&, Type)>;
@@ -1615,7 +1496,6 @@ private:
std::unordered_map<Index, Index> indexMap;
std::unordered_map<int, std::vector<Index>> freeTemps;
std::unordered_map<Expression*, TempVar> highBitVars;
- std::unordered_map<Name, TempVar> labelHighBitVars;
std::unordered_map<Index, Type> tempTypes;
std::unordered_set<Name> originallyI64Globals;
Index nextTemp;
diff --git a/src/wasm2js.h b/src/wasm2js.h
index b2a35d5cb..cedf3f8e3 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -136,10 +136,7 @@ public:
// The second pass on an expression: process it fully, generating
// JS
- // @param result Whether the context we are in receives a value,
- // and its type, or if not, then we can drop our return,
- // if we have one.
- Ref processFunctionBody(Module* m, Function* func, IString result);
+ Ref processFunctionBody(Module* m, Function* func);
// Get a temp var.
IString getTemp(Type type, Function* func) {
@@ -274,6 +271,7 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
runner.add("flatten");
runner.add("simplify-locals-notee-nostructure");
runner.add("reorder-locals");
+ runner.add("remove-unused-names");
runner.add("vacuum");
runner.add("remove-unused-module-elements");
runner.setDebug(flags.debug);
@@ -632,6 +630,7 @@ Ref Wasm2JSBuilder::processFunction(Module* m, Function* func, bool standaloneFu
runner.add("flatten");
runner.add("simplify-locals-notee-nostructure");
runner.add("reorder-locals");
+ runner.add("remove-unused-names");
runner.add("vacuum");
runner.runOnFunction(func);
}
@@ -665,7 +664,7 @@ Ref Wasm2JSBuilder::processFunction(Module* m, Function* func, bool standaloneFu
size_t theVarIndex = ret[3]->size();
ret[3]->push_back(theVar);
// body
- flattenAppend(ret, processFunctionBody(m, func, NO_RESULT));
+ flattenAppend(ret, processFunctionBody(m, func));
// vars, including new temp vars
for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) {
ValueBuilder::appendToVar(
@@ -684,7 +683,7 @@ Ref Wasm2JSBuilder::processFunction(Module* m, Function* func, bool standaloneFu
return ret;
}
-Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString result) {
+Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func) {
struct ExpressionProcessor : public Visitor<ExpressionProcessor, Ref> {
Wasm2JSBuilder* parent;
IString result; // TODO: remove
@@ -741,14 +740,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
}
Ref visitAndAssign(Expression* curr, IString result) {
+ assert(result != NO_RESULT);
Ref ret = visit(curr, result);
- // if it's not already a statement, then it's an expression, and we need to assign it
- // (if it is a statement, it already assigns to the result var)
- if (result != NO_RESULT) {
- ret = ValueBuilder::makeStatement(
- ValueBuilder::makeBinary(ValueBuilder::makeName(result), SET, ret));
- }
- return ret;
+ return ValueBuilder::makeStatement(ValueBuilder::makeBinary(ValueBuilder::makeName(result), SET, ret));
}
Ref visitAndAssign(Expression* curr, ScopedTemp& temp) {
@@ -768,10 +762,6 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
return ret;
}
- // For spooky return-at-a-distance/break-with-result, this tells us
- // what the result var is for a specific label.
- std::map<Name, IString> breakResults;
-
// Breaks to the top of a loop should be emitted as continues, to that loop's main label
std::unordered_set<Name> continueLabels;
@@ -782,7 +772,6 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
// Visitors
Ref visitBlock(Block* curr) {
- breakResults[curr->name] = result;
Ref ret = ValueBuilder::makeBlock();
size_t size = curr->list.size();
auto noResults = result == NO_RESULT ? size : size-1;
@@ -799,20 +788,13 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
}
Ref visitIf(If* curr) {
- IString temp;
Ref condition = visit(curr->condition, EXPRESSION_RESULT);
- Ref ifTrue = ValueBuilder::makeStatement(visitAndAssign(curr->ifTrue, result));
+ Ref ifTrue = visit(curr->ifTrue, NO_RESULT);
Ref ifFalse;
if (curr->ifFalse) {
- ifFalse = ValueBuilder::makeStatement(visitAndAssign(curr->ifFalse, result));
- }
- if (temp.isNull()) {
- return ValueBuilder::makeIf(condition, ifTrue, ifFalse); // simple if
+ ifFalse = visit(curr->ifFalse, NO_RESULT);
}
- condition = blockify(condition);
- // just add an if to the block
- condition[1]->push_back(ValueBuilder::makeIf(ValueBuilder::makeName(temp), ifTrue, ifFalse));
- return condition;
+ return ValueBuilder::makeIf(condition, ifTrue, ifFalse); // simple if
}
Ref visitLoop(Loop* curr) {
@@ -842,13 +824,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
fakeIf.ifTrue = &fakeBreak;
return visit(&fakeIf, result);
}
- Ref theBreak = makeBreakOrContinue(curr->name);
- if (!curr->value) return theBreak;
- // generate the value, including assigning to the result, and then do the break
- Ref ret = visitAndAssign(curr->value, breakResults[curr->name]);
- ret = blockify(ret);
- ret[1]->push_back(theBreak);
- return ret;
+ return makeBreakOrContinue(curr->name);
}
Expression* defaultBody = nullptr; // default must be last in asm.js
@@ -1141,7 +1117,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
}
Ref visitDrop(Drop* curr) {
- return visitAndAssign(curr->value, result);
+ return visit(curr->value, NO_RESULT);
}
Ref visitConst(Const* curr) {
@@ -1587,7 +1563,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
}
};
- return ExpressionProcessor(this, m, func).visit(func->body, result);
+ return ExpressionProcessor(this, m, func).visit(func->body, NO_RESULT);
}
void Wasm2JSBuilder::addMemoryGrowthFuncs(Ref ast, Module* wasm) {