diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-04-22 16:22:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-22 16:22:10 -0700 |
commit | 7fe2701d3bcbea625405f7b8c852aa3154face6b (patch) | |
tree | ad4f4228f293dcbbb4ccb29afaee218d3910c268 /src | |
parent | 831a774641b63bc4980eb6e71b1c59d92d19fb4d (diff) | |
download | binaryen-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.cpp | 120 | ||||
-rw-r--r-- | src/wasm2js.h | 50 |
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) { |