diff options
106 files changed, 5323 insertions, 1740 deletions
@@ -48,6 +48,8 @@ There are a few differences between Binaryen IR and the WebAssembly language: As a result, you might notice that round-trip conversions (wasm => Binaryen IR => wasm) change code a little in some corner cases. + * When optimizing Binaryen uses an additional IR, Stack IR (see `src/wasm-stack.h`). Stack IR allows a bunch of optimizations that are tailored for the stack machine form of WebAssembly's binary format (but Stack IR is less efficient for general optimizations than the main Binaryen IR). If you have a wasm file that has been particularly well-optimized, a simple round-trip conversion (just read and write, without optimization) may cause more noticeable differences, as Binaryen fits it into Binaryen IR's more structured format. If you also optimize during the round-trip conversion then Stack IR opts will be run and the final wasm will be better optimized. + Notes when working with Binaryen IR: * As mentioned above, Binaryen IR has a tree structure. As a result, each expression should have exactly one parent - you should not "reuse" a node by having it appear more than once in the tree. The motivation for this limitation is that when we optimize we modify nodes, so if they appear more than once in the tree, a change in one place can appear in another incorrectly. diff --git a/build-js.sh b/build-js.sh index 763062a19..e39b19520 100755 --- a/build-js.sh +++ b/build-js.sh @@ -131,6 +131,7 @@ echo "building shared bitcode" $BINARYEN_SRC/passes/SimplifyLocals.cpp \ $BINARYEN_SRC/passes/SpillPointers.cpp \ $BINARYEN_SRC/passes/SSAify.cpp \ + $BINARYEN_SRC/passes/StackIR.cpp \ $BINARYEN_SRC/passes/TrapMode.cpp \ $BINARYEN_SRC/passes/Untee.cpp \ $BINARYEN_SRC/passes/Vacuum.cpp \ diff --git a/src/ir/hashed.h b/src/ir/hashed.h index 0771da6ec..2aaa98db2 100644 --- a/src/ir/hashed.h +++ b/src/ir/hashed.h @@ -58,8 +58,6 @@ class HashedExpressionMap : public std::unordered_map<HashedExpression, T, Expre struct FunctionHasher : public WalkerPass<PostWalker<FunctionHasher>> { bool isFunctionParallel() override { return true; } - typedef uint32_t HashType; - struct Map : public std::map<Function*, HashType> {}; FunctionHasher(Map* output) : output(output) {} diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 83625809f..4205514e5 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -52,6 +52,23 @@ struct BinaryIndexes { } }; +inline Function* copyFunction(Function* func, Module& out) { + auto* ret = new Function(); + ret->name = func->name; + ret->result = func->result; + ret->params = func->params; + ret->vars = func->vars; + ret->type = Name(); // start with no named type; the names in the other module may differ + ret->localNames = func->localNames; + ret->localIndices = func->localIndices; + ret->debugLocations = func->debugLocations; + ret->body = ExpressionManipulator::copy(func->body, out); + // TODO: copy Stack IR + assert(!func->stackIR); + out.addFunction(ret); + return ret; +} + inline void copyModule(Module& in, Module& out) { // we use names throughout, not raw points, so simple copying is fine // for everything *but* expressions @@ -65,9 +82,7 @@ inline void copyModule(Module& in, Module& out) { out.addExport(new Export(*curr)); } for (auto& curr : in.functions) { - auto* func = new Function(*curr); - func->body = ExpressionManipulator::copy(func->body, out); - out.addFunction(func); + copyFunction(curr.get(), out); } for (auto& curr : in.globals) { out.addGlobal(new Global(*curr)); @@ -85,19 +100,6 @@ inline void copyModule(Module& in, Module& out) { out.debugInfoFileNames = in.debugInfoFileNames; } -inline Function* copyFunction(Module& in, Module& out, Name name) { - Function *ret = out.getFunctionOrNull(name); - if (ret != nullptr) { - return ret; - } - auto* curr = in.getFunction(name); - auto* func = new Function(*curr); - func->body = ExpressionManipulator::copy(func->body, out); - func->type = Name(); - out.addFunction(func); - return func; -} - } // namespace ModuleUtils } // namespace wasm diff --git a/src/ir/utils.h b/src/ir/utils.h index fa08122b5..92bfcdab3 100644 --- a/src/ir/utils.h +++ b/src/ir/utils.h @@ -88,7 +88,7 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R std::map<Name, Type> breakValues; - void visitBlock(Block *curr) { + void visitBlock(Block* curr) { if (curr->list.size() == 0) { curr->type = none; return; @@ -129,13 +129,13 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R } } } - void visitIf(If *curr) { curr->finalize(); } - void visitLoop(Loop *curr) { curr->finalize(); } - void visitBreak(Break *curr) { + void visitIf(If* curr) { curr->finalize(); } + void visitLoop(Loop* curr) { curr->finalize(); } + void visitBreak(Break* curr) { curr->finalize(); updateBreakValueType(curr->name, getValueType(curr->value)); } - void visitSwitch(Switch *curr) { + void visitSwitch(Switch* curr) { curr->finalize(); auto valueType = getValueType(curr->value); for (auto target : curr->targets) { @@ -143,28 +143,28 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R } updateBreakValueType(curr->default_, valueType); } - void visitCall(Call *curr) { curr->finalize(); } - void visitCallImport(CallImport *curr) { curr->finalize(); } - void visitCallIndirect(CallIndirect *curr) { curr->finalize(); } - void visitGetLocal(GetLocal *curr) { curr->finalize(); } - void visitSetLocal(SetLocal *curr) { curr->finalize(); } - void visitGetGlobal(GetGlobal *curr) { curr->finalize(); } - void visitSetGlobal(SetGlobal *curr) { curr->finalize(); } - void visitLoad(Load *curr) { curr->finalize(); } - void visitStore(Store *curr) { curr->finalize(); } - void visitAtomicRMW(AtomicRMW *curr) { curr->finalize(); } - void visitAtomicCmpxchg(AtomicCmpxchg *curr) { curr->finalize(); } + void visitCall(Call* curr) { curr->finalize(); } + void visitCallImport(CallImport* curr) { curr->finalize(); } + void visitCallIndirect(CallIndirect* curr) { curr->finalize(); } + void visitGetLocal(GetLocal* curr) { curr->finalize(); } + void visitSetLocal(SetLocal* curr) { curr->finalize(); } + void visitGetGlobal(GetGlobal* curr) { curr->finalize(); } + void visitSetGlobal(SetGlobal* curr) { curr->finalize(); } + void visitLoad(Load* curr) { curr->finalize(); } + void visitStore(Store* curr) { curr->finalize(); } + void visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); } + void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void visitAtomicWake(AtomicWake* curr) { curr->finalize(); } - void visitConst(Const *curr) { curr->finalize(); } - void visitUnary(Unary *curr) { curr->finalize(); } - void visitBinary(Binary *curr) { curr->finalize(); } - void visitSelect(Select *curr) { curr->finalize(); } - void visitDrop(Drop *curr) { curr->finalize(); } - void visitReturn(Return *curr) { curr->finalize(); } - void visitHost(Host *curr) { curr->finalize(); } - void visitNop(Nop *curr) { curr->finalize(); } - void visitUnreachable(Unreachable *curr) { curr->finalize(); } + void visitConst(Const* curr) { curr->finalize(); } + void visitUnary(Unary* curr) { curr->finalize(); } + void visitBinary(Binary* curr) { curr->finalize(); } + void visitSelect(Select* curr) { curr->finalize(); } + void visitDrop(Drop* curr) { curr->finalize(); } + void visitReturn(Return* curr) { curr->finalize(); } + void visitHost(Host* curr) { curr->finalize(); } + void visitNop(Nop* curr) { curr->finalize(); } + void visitUnreachable(Unreachable* curr) { curr->finalize(); } void visitFunction(Function* curr) { // we may have changed the body from unreachable to none, which might be bad @@ -197,33 +197,33 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R // Re-finalize a single node. This is slow, if you want to refinalize // an entire ast, use ReFinalize struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> { - void visitBlock(Block *curr) { curr->finalize(); } - void visitIf(If *curr) { curr->finalize(); } - void visitLoop(Loop *curr) { curr->finalize(); } - void visitBreak(Break *curr) { curr->finalize(); } - void visitSwitch(Switch *curr) { curr->finalize(); } - void visitCall(Call *curr) { curr->finalize(); } - void visitCallImport(CallImport *curr) { curr->finalize(); } - void visitCallIndirect(CallIndirect *curr) { curr->finalize(); } - void visitGetLocal(GetLocal *curr) { curr->finalize(); } - void visitSetLocal(SetLocal *curr) { curr->finalize(); } - void visitGetGlobal(GetGlobal *curr) { curr->finalize(); } - void visitSetGlobal(SetGlobal *curr) { curr->finalize(); } - void visitLoad(Load *curr) { curr->finalize(); } - void visitStore(Store *curr) { curr->finalize(); } + void visitBlock(Block* curr) { curr->finalize(); } + void visitIf(If* curr) { curr->finalize(); } + void visitLoop(Loop* curr) { curr->finalize(); } + void visitBreak(Break* curr) { curr->finalize(); } + void visitSwitch(Switch* curr) { curr->finalize(); } + void visitCall(Call* curr) { curr->finalize(); } + void visitCallImport(CallImport* curr) { curr->finalize(); } + void visitCallIndirect(CallIndirect* curr) { curr->finalize(); } + void visitGetLocal(GetLocal* curr) { curr->finalize(); } + void visitSetLocal(SetLocal* curr) { curr->finalize(); } + void visitGetGlobal(GetGlobal* curr) { curr->finalize(); } + void visitSetGlobal(SetGlobal* curr) { curr->finalize(); } + void visitLoad(Load* curr) { curr->finalize(); } + void visitStore(Store* curr) { curr->finalize(); } void visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); } void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void visitAtomicWake(AtomicWake* curr) { curr->finalize(); } - void visitConst(Const *curr) { curr->finalize(); } - void visitUnary(Unary *curr) { curr->finalize(); } - void visitBinary(Binary *curr) { curr->finalize(); } - void visitSelect(Select *curr) { curr->finalize(); } - void visitDrop(Drop *curr) { curr->finalize(); } - void visitReturn(Return *curr) { curr->finalize(); } - void visitHost(Host *curr) { curr->finalize(); } - void visitNop(Nop *curr) { curr->finalize(); } - void visitUnreachable(Unreachable *curr) { curr->finalize(); } + void visitConst(Const* curr) { curr->finalize(); } + void visitUnary(Unary* curr) { curr->finalize(); } + void visitBinary(Binary* curr) { curr->finalize(); } + void visitSelect(Select* curr) { curr->finalize(); } + void visitDrop(Drop* curr) { curr->finalize(); } + void visitReturn(Return* curr) { curr->finalize(); } + void visitHost(Host* curr) { curr->finalize(); } + void visitNop(Nop* curr) { curr->finalize(); } + void visitUnreachable(Unreachable* curr) { curr->finalize(); } void visitFunctionType(FunctionType* curr) { WASM_UNREACHABLE(); } void visitImport(Import* curr) { WASM_UNREACHABLE(); } diff --git a/src/pass.h b/src/pass.h index 30e16761d..384dcf791 100644 --- a/src/pass.h +++ b/src/pass.h @@ -76,6 +76,10 @@ struct PassOptions { ret.setDefaultOptimizationOptions(); return ret; } + + static PassOptions getWithoutOptimization() { + return PassOptions(); // defaults are to not optimize + } }; // @@ -137,6 +141,9 @@ struct PassRunner { // Adds the default optimization passes that work on // entire modules as a whole, and make sense to // run after function passes. + // This is run at the very end of the optimization + // process - you can assume no other opts will be run + // afterwards. void addDefaultGlobalOptimizationPostPasses(); // Run the passes on the module @@ -174,7 +181,16 @@ protected: private: void doAdd(Pass* pass); + void runPass(Pass* pass); void runPassOnFunction(Pass* pass, Function* func); + + // After running a pass, handle any changes due to + // how the pass is defined, such as clearing away any + // temporary data structures that the pass declares it + // invalidates. + // If a function is passed, we operate just on that function; + // otherwise, the whole module. + void handleAfterEffects(Pass* pass, Function* func=nullptr); }; // @@ -223,6 +239,14 @@ public: // this will create the parent class. virtual Pass* create() { WASM_UNREACHABLE(); } + // Whether this pass modifies the Binaryen IR in the module. This is true for + // most passes, except for passes that have no side effects, or passes that + // only modify other things than Binaryen IR (for example, the Stack IR + // passes only modify that IR). + // This property is important as if Binaryen IR is modified, we need to throw + // out any Stack IR - it would need to be regenerated and optimized. + virtual bool modifiesBinaryenIR() { return true; } + std::string name; protected: diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index bbb2a4610..25a1828dc 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -32,6 +32,7 @@ SET(passes_SOURCES Precompute.cpp Print.cpp PrintCallGraph.cpp + StackIR.cpp RedundantSetElimination.cpp RelooperJumpThreading.cpp ReReloop.cpp diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index e501107bd..2986deb9f 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -27,6 +27,7 @@ #include "emscripten-optimizer/istring.h" #include "support/name.h" #include "wasm-builder.h" +#include "ir/module-utils.h" #include "ir/names.h" #include "asmjs/shared-constants.h" @@ -143,19 +144,20 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { highBitVars.clear(); labelHighBitVars.clear(); freeTemps.clear(); - Function oldFunc(*func); + Module temp; + auto* oldFunc = ModuleUtils::copyFunction(func, temp); func->params.clear(); func->vars.clear(); func->localNames.clear(); func->localIndices.clear(); Index newIdx = 0; - Names::ensureNames(&oldFunc); - for (Index i = 0; i < oldFunc.getNumLocals(); ++i) { - assert(oldFunc.hasLocalName(i)); - Name lowName = oldFunc.getLocalName(i); + Names::ensureNames(oldFunc); + for (Index i = 0; i < oldFunc->getNumLocals(); ++i) { + assert(oldFunc->hasLocalName(i)); + Name lowName = oldFunc->getLocalName(i); Name highName = makeHighName(lowName); - Type paramType = oldFunc.getLocalType(i); - auto builderFunc = (i < oldFunc.getVarIndexBase()) ? + Type paramType = oldFunc->getLocalType(i); + auto builderFunc = (i < oldFunc->getVarIndexBase()) ? Builder::addParam : static_cast<Index (*)(Function*, Name, Type)>(Builder::addVar); if (paramType == i64) { diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp index 1ba004886..c7b20c582 100644 --- a/src/passes/MemoryPacking.cpp +++ b/src/passes/MemoryPacking.cpp @@ -24,6 +24,8 @@ namespace wasm { const Index OVERHEAD = 8; struct MemoryPacking : public Pass { + bool modifiesBinaryenIR() override { return false; } + void run(PassRunner* runner, Module* module) override { if (!module->memory.exists) return; std::vector<Memory::Segment> packed; diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp index 8cbf96db5..81706042b 100644 --- a/src/passes/Metrics.cpp +++ b/src/passes/Metrics.cpp @@ -32,6 +32,8 @@ static Counts lastCounts; // Prints metrics between optimization passes. struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor<Metrics>>> { + bool modifiesBinaryenIR() override { return false; } + bool byFunction; Counts counts; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index b1082dcc1..dfdfa46d4 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -725,6 +725,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> { } o << " (; " << functionIndexes[curr->name] << " ;)"; } + if (curr->stackIR && !minify) { + o << " (; has Stack IR ;)"; + } if (curr->type.is()) { o << maybeSpace << "(type " << curr->type << ')'; } @@ -888,6 +891,8 @@ public: Printer() : o(std::cout) {} Printer(std::ostream* o) : o(*o) {} + bool modifiesBinaryenIR() override { return false; } + void run(PassRunner* runner, Module* module) override { PrintSExpression print(o); print.visitModule(module); diff --git a/src/passes/PrintCallGraph.cpp b/src/passes/PrintCallGraph.cpp index ac11dfb8b..fa58e3859 100644 --- a/src/passes/PrintCallGraph.cpp +++ b/src/passes/PrintCallGraph.cpp @@ -29,6 +29,8 @@ namespace wasm { struct PrintCallGraph : public Pass { + bool modifiesBinaryenIR() override { return false; } + void run(PassRunner* runner, Module* module) override { std::ostream &o = std::cout; o << "digraph call {\n" diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp index 76c9528cb..ef8c7531c 100644 --- a/src/passes/RemoveNonJSOps.cpp +++ b/src/passes/RemoveNonJSOps.cpp @@ -89,7 +89,11 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> { // copy we then walk the function to rewrite any non-js operations it has // as well. for (auto &name : neededFunctions) { - doWalkFunction(ModuleUtils::copyFunction(intrinsicsModule, *module, name)); + auto* func = module->getFunctionOrNull(name); + if (!func) { + func = ModuleUtils::copyFunction(intrinsicsModule.getFunction(name), *module); + } + doWalkFunction(func); } neededFunctions.clear(); } diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp new file mode 100644 index 000000000..43c95608e --- /dev/null +++ b/src/passes/StackIR.cpp @@ -0,0 +1,393 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Operations on Stack IR. +// + +#include "wasm.h" +#include "pass.h" +#include "wasm-stack.h" +#include "ir/iteration.h" +#include "ir/local-graph.h" + +namespace wasm { + +// Generate Stack IR from Binaryen IR + +struct GenerateStackIR : public WalkerPass<PostWalker<GenerateStackIR>> { + bool isFunctionParallel() override { return true; } + + Pass* create() override { return new GenerateStackIR; } + + bool modifiesBinaryenIR() override { return false; } + + void doWalkFunction(Function* func) { + BufferWithRandomAccess buffer; + // a shim for the parent that a stackWriter expects - we don't need + // it to do anything, as we are just writing to Stack IR + struct Parent { + Module* module; + Parent(Module* module) : module(module) {} + + Module* getModule() { + return module; + } + void writeDebugLocation(Expression* curr, Function* func) { + WASM_UNREACHABLE(); + } + Index getFunctionIndex(Name name) { + WASM_UNREACHABLE(); + } + Index getFunctionTypeIndex(Name name) { + WASM_UNREACHABLE(); + } + Index getGlobalIndex(Name name) { + WASM_UNREACHABLE(); + } + } parent(getModule()); + StackWriter<StackWriterMode::Binaryen2Stack, Parent> stackWriter(parent, buffer, false); + stackWriter.setFunction(func); + stackWriter.visitPossibleBlockContents(func->body); + func->stackIR = make_unique<StackIR>(); + func->stackIR->swap(stackWriter.stackIR); + } +}; + +Pass* createGenerateStackIRPass() { + return new GenerateStackIR(); +} + +// Print (for debugging purposes) + +struct PrintStackIR : public WalkerPass<PostWalker<PrintStackIR>> { + // Not parallel: this pass is just for testing and debugging; keep the output + // sorted by function order. + bool isFunctionParallel() override { return false; } + + Pass* create() override { return new PrintStackIR; } + + bool modifiesBinaryenIR() override { return false; } + + void doWalkFunction(Function* func) { + std::cout << func->name << ":\n"; + if (func->stackIR) { + std::cout << *func->stackIR; + } else { + std::cout << " (no stack ir)"; + } + std::cout << '\n'; + } +}; + +Pass* createPrintStackIRPass() { + return new PrintStackIR(); +} + +// Optimize + +class StackIROptimizer { + Function* func; + PassOptions& passOptions; + StackIR& insts; + +public: + StackIROptimizer(Function* func, PassOptions& passOptions) : + func(func), passOptions(passOptions), insts(*func->stackIR.get()) { + assert(func->stackIR); + } + + void run() { + dce(); + // FIXME: local2Stack is currently rather slow (due to localGraph), + // so for now run it only when really optimizing + if (passOptions.optimizeLevel >= 3 || passOptions.shrinkLevel >= 1) { + local2Stack(); + } + removeUnneededBlocks(); + dce(); + } + +private: + // Passes. + + // Remove unreachable code. + void dce() { + bool inUnreachableCode = false; + for (Index i = 0; i < insts.size(); i++) { + auto* inst = insts[i]; + if (!inst) continue; + if (inUnreachableCode) { + // Does the unreachable code end here? + if (isControlFlowBarrier(inst)) { + inUnreachableCode = false; + } else { + // We can remove this. + removeAt(i); + } + } else if (inst->type == unreachable) { + inUnreachableCode = true; + } + } + } + + // If ordered properly, we can avoid a set_local/get_local pair, + // and use the value directly from the stack, for example + // [..produce a value on the stack..] + // set_local $x + // [..much code..] + // get_local $x + // call $foo ;; use the value, foo(value) + // As long as the code in between does not modify $x, and has + // no control flow branching out, we can remove both the set + // and the get. + void local2Stack() { + // We use the localGraph to tell us if a get-set pair is indeed + // a set that is read by that get, and only that get. Note that we run + // this on the Binaryen IR, so we are assuming that no previous opt + // has changed the interaction of local operations. + // TODO: we can do this a lot faster, as we just care about linear + // control flow. + LocalGraph localGraph(func); + localGraph.computeInfluences(); + // We maintain a stack of relevant values. This contains: + // * a null for each actual value that the value stack would have + // * an index of each SetLocal that *could* be on the value + // stack at that location. + const Index null = -1; + std::vector<Index> values; + // We also maintain a stack of values vectors for control flow, + // saving the stack as we enter and restoring it when we exit. + std::vector<std::vector<Index>> savedValues; +#ifdef STACK_OPT_DEBUG + std::cout << "func: " << func->name << '\n' << insts << '\n'; +#endif + for (Index i = 0; i < insts.size(); i++) { + auto* inst = insts[i]; + if (!inst) continue; + // First, consume values from the stack as required. + auto consumed = getNumConsumedValues(inst); +#ifdef STACK_OPT_DEBUG + std::cout << " " << i << " : " << *inst << ", " << values.size() << " on stack, will consume " << consumed << "\n "; + for (auto s : values) std::cout << s << ' '; + std::cout << '\n'; +#endif + // TODO: currently we run dce before this, but if we didn't, we'd need + // to handle unreachable code here - it's ok to pop multiple values + // there even if the stack is at size 0. + while (consumed > 0) { + assert(values.size() > 0); + // Whenever we hit a possible stack value, kill it - it would + // be consumed here, so we can never optimize to it. + while (values.back() != null) { + values.pop_back(); + assert(values.size() > 0); + } + // Finally, consume the actual value that is consumed here. + values.pop_back(); + consumed--; + } + // After consuming, we can see what to do with this. First, handle + // control flow. + if (isControlFlowBegin(inst)) { + // Save the stack for when we end this control flow. + savedValues.push_back(values); // TODO: optimize copies + values.clear(); + } else if (isControlFlowEnd(inst)) { + assert(!savedValues.empty()); + values = savedValues.back(); + savedValues.pop_back(); + } else if (isControlFlow(inst)) { + // Otherwise, in the middle of control flow, just clear it + values.clear(); + } + // This is something we should handle, look into it. + if (isConcreteType(inst->type)) { + bool optimized = false; + if (auto* get = inst->origin->dynCast<GetLocal>()) { + // This is a potential optimization opportunity! See if we + // can reach the set. + if (values.size() > 0) { + Index j = values.size() - 1; + while (1) { + // If there's an actual value in the way, we've failed. + auto index = values[j]; + if (index == null) break; + auto* set = insts[index]->origin->cast<SetLocal>(); + if (set->index == get->index) { + // This might be a proper set-get pair, where the set is + // used by this get and nothing else, check that. + auto& sets = localGraph.getSetses[get]; + if (sets.size() == 1 && *sets.begin() == set) { + auto& setInfluences = localGraph.setInfluences[set]; + if (setInfluences.size() == 1) { + assert(*setInfluences.begin() == get); + // Do it! The set and the get can go away, the proper + // value is on the stack. +#ifdef STACK_OPT_DEBUG + std::cout << " stackify the get\n"; +#endif + insts[index] = nullptr; + insts[i] = nullptr; + // Continuing on from here, replace this on the stack + // with a null, representing a regular value. We + // keep possible values above us active - they may + // be optimized later, as they would be pushed after + // us, and used before us, so there is no conflict. + values[j] = null; + optimized = true; + break; + } + } + } + // We failed here. Can we look some more? + if (j == 0) break; + j--; + } + } + } + if (!optimized) { + // This is an actual regular value on the value stack. + values.push_back(null); + } + } else if (inst->origin->is<SetLocal>() && inst->type == none) { + // This set is potentially optimizable later, add to stack. + values.push_back(i); + } + } + } + + // There may be unnecessary blocks we can remove: blocks + // without branches to them are always ok to remove. + // TODO: a branch to a block in an if body can become + // a branch to that if body + void removeUnneededBlocks() { + for (auto*& inst : insts) { + if (!inst) continue; + if (auto* block = inst->origin->dynCast<Block>()) { + if (!BranchUtils::BranchSeeker::hasNamed(block, block->name)) { + // TODO optimize, maybe run remove-unused-names + inst = nullptr; + } + } + } + } + + // Utilities. + + // A control flow "barrier" - a point where stack machine + // unreachability ends. + bool isControlFlowBarrier(StackInst* inst) { + switch (inst->op) { + case StackInst::BlockEnd: + case StackInst::IfElse: + case StackInst::IfEnd: + case StackInst::LoopEnd: { + return true; + } + default: { + return false; + } + } + } + + // A control flow beginning. + bool isControlFlowBegin(StackInst* inst) { + switch (inst->op) { + case StackInst::BlockBegin: + case StackInst::IfBegin: + case StackInst::LoopBegin: { + return true; + } + default: { + return false; + } + } + } + + // A control flow ending. + bool isControlFlowEnd(StackInst* inst) { + switch (inst->op) { + case StackInst::BlockEnd: + case StackInst::IfEnd: + case StackInst::LoopEnd: { + return true; + } + default: { + return false; + } + } + } + + bool isControlFlow(StackInst* inst) { + return inst->op != StackInst::Basic; + } + + // Remove the instruction at index i. If the instruction + // is control flow, and so has been expanded to multiple + // instructions, remove them as well. + void removeAt(Index i) { + auto* inst = insts[i]; + insts[i] = nullptr; + if (inst->op == StackInst::Basic) { + return; // that was it + } + auto* origin = inst->origin; + while (1) { + i++; + assert(i < insts.size()); + inst = insts[i]; + insts[i] = nullptr; + if (inst && inst->origin == origin && isControlFlowEnd(inst)) { + return; // that's it, we removed it all + } + } + } + + Index getNumConsumedValues(StackInst* inst) { + if (isControlFlow(inst)) { + // If consumes 1; that's it. + if (inst->op == StackInst::IfBegin) { + return 1; + } + return 0; + } + // Otherwise, for basic instructions, just count the expression children. + return ChildIterator(inst->origin).children.size(); + } +}; + +struct OptimizeStackIR : public WalkerPass<PostWalker<OptimizeStackIR>> { + bool isFunctionParallel() override { return true; } + + Pass* create() override { return new OptimizeStackIR; } + + bool modifiesBinaryenIR() override { return false; } + + void doWalkFunction(Function* func) { + if (!func->stackIR) { + return; + } + StackIROptimizer(func, getPassOptions()).run(); + } +}; + +Pass* createOptimizeStackIRPass() { + return new OptimizeStackIR(); +} + +} // namespace wasm + diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index c0354524d..97151f847 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -22,6 +22,7 @@ #include <pass.h> #include <wasm-validator.h> #include <wasm-io.h> +#include "ir/hashed.h" namespace wasm { @@ -76,6 +77,7 @@ void PassRegistry::registerPasses() { registerPass("flatten", "flattens out code, removing nesting", createFlattenPass); registerPass("fpcast-emu", "emulates function pointer casts, allowing incorrect indirect calls to (sometimes) work", createFuncCastEmulationPass); registerPass("func-metrics", "reports function metrics", createFunctionMetricsPass); + registerPass("generate-stack-ir", "generate Stack IR", createGenerateStackIRPass); registerPass("inlining", "inline functions (you probably want inlining-optimizing)", createInliningPass); registerPass("inlining-optimizing", "inline functions and optimizes where we inlined", createInliningOptimizingPass); registerPass("legalize-js-interface", "legalizes i64 types on the import/export boundary", createLegalizeJSInterfacePass); @@ -90,6 +92,7 @@ void PassRegistry::registerPasses() { registerPass("metrics", "reports metrics", createMetricsPass); registerPass("nm", "name list", createNameListPass); registerPass("optimize-instructions", "optimizes instruction combinations", createOptimizeInstructionsPass); + registerPass("optimize-stack-ir", "optimize Stack IR", createOptimizeStackIRPass); registerPass("pick-load-signs", "pick load signs based on their uses", createPickLoadSignsPass); registerPass("post-emscripten", "miscellaneous optimizations for Emscripten-generated code", createPostEmscriptenPass); registerPass("precompute", "computes compile-time evaluatable expressions", createPrecomputePass); @@ -98,6 +101,7 @@ void PassRegistry::registerPasses() { registerPass("print-minified", "print in minified s-expression format", createMinifiedPrinterPass); registerPass("print-full", "print in full s-expression format", createFullPrinterPass); registerPass("print-call-graph", "print call graph", createPrintCallGraphPass); + registerPass("print-stack-ir", "print out Stack IR (useful for internal debugging)", createPrintStackIRPass); registerPass("relooper-jump-threading", "thread relooper jumps (fastcomp output only)", createRelooperJumpThreadingPass); registerPass("remove-non-js-ops", "removes operations incompatible with js", createRemoveNonJSOpsPass); registerPass("remove-imports", "removes imports and replaces them with nops", createRemoveImportsPass); @@ -201,6 +205,12 @@ void PassRunner::addDefaultGlobalOptimizationPostPasses() { add("duplicate-function-elimination"); // optimizations show more functions as duplicate add("remove-unused-module-elements"); add("memory-packing"); + // perform Stack IR optimizations here, at the very end of the + // optimization pipeline + if (options.optimizeLevel >= 2 || options.shrinkLevel >= 1) { + add("generate-stack-ir"); + add("optimize-stack-ir"); + } } static void dumpWast(Name name, Module* wasm) { @@ -252,7 +262,7 @@ void PassRunner::run() { runPassOnFunction(pass, func.get()); } } else { - pass->run(this, wasm); + runPass(pass); } auto after = std::chrono::steady_clock::now(); std::chrono::duration<double> diff = after - before; @@ -320,7 +330,7 @@ void PassRunner::run() { stack.push_back(pass); } else { flush(); - pass->run(this, wasm); + runPass(pass); } } flush(); @@ -347,11 +357,135 @@ void PassRunner::doAdd(Pass* pass) { pass->prepareToRun(this, wasm); } +// Checks that the state is valid before and after a +// pass runs on a function. We run these extra checks when +// pass-debug mode is enabled. +struct AfterEffectFunctionChecker { + Function* func; + Name name; + + // Check Stack IR state: if the main IR changes, there should be no + // stack IR, as the stack IR would be wrong. + bool beganWithStackIR; + HashType originalFunctionHash; + + // In the creator we can scan the state of the module and function before the + // pass runs. + AfterEffectFunctionChecker(Function* func) : func(func), name(func->name) { + beganWithStackIR = func->stackIR != nullptr; + if (beganWithStackIR) { + originalFunctionHash = FunctionHasher::hashFunction(func); + } + } + + // This is called after the pass is run, at which time we can check things. + void check() { + assert(func->name == name); // no global module changes should have occurred + if (beganWithStackIR && func->stackIR) { + auto after = FunctionHasher::hashFunction(func); + if (after != originalFunctionHash) { + Fatal() << "[PassRunner] PASS_DEBUG check failed: had Stack IR before and after the pass ran, and the pass modified the main IR, which invalidates Stack IR - pass should have been marked 'modifiesBinaryenIR'"; + } + } + } +}; + +// Runs checks on the entire module, in a non-function-parallel pass. +// In particular, in such a pass functions may be removed or renamed, track that. +struct AfterEffectModuleChecker { + Module* module; + + std::vector<AfterEffectFunctionChecker> checkers; + + bool beganWithAnyStackIR; + + AfterEffectModuleChecker(Module* module) : module(module) { + for (auto& func : module->functions) { + checkers.emplace_back(func.get()); + } + beganWithAnyStackIR = hasAnyStackIR(); + } + + void check() { + if (beganWithAnyStackIR && hasAnyStackIR()) { + // If anything changed to the functions, that's not good. + if (checkers.size() != module->functions.size()) { + error(); + } + for (Index i = 0; i < checkers.size(); i++) { + // Did a pointer change? (a deallocated function could cause that) + if (module->functions[i].get() != checkers[i].func || + module->functions[i]->body != checkers[i].func->body) { + error(); + } + // Did a name change? + if (module->functions[i]->name != checkers[i].name) { + error(); + } + } + // Global function state appears to not have been changed: the same + // functions are there. Look into their contents. + for (auto& checker : checkers) { + checker.check(); + } + } + } + + void error() { + Fatal() << "[PassRunner] PASS_DEBUG check failed: had Stack IR before and after the pass ran, and the pass modified global function state - pass should have been marked 'modifiesBinaryenIR'"; + } + + bool hasAnyStackIR() { + for (auto& func : module->functions) { + if (func->stackIR) { + return true; + } + } + return false; + } +}; + +void PassRunner::runPass(Pass* pass) { + std::unique_ptr<AfterEffectModuleChecker> checker; + if (getPassDebug()) { + checker = std::unique_ptr<AfterEffectModuleChecker>( + new AfterEffectModuleChecker(wasm)); + } + pass->run(this, wasm); + handleAfterEffects(pass); + if (getPassDebug()) { + checker->check(); + } +} + void PassRunner::runPassOnFunction(Pass* pass, Function* func) { assert(pass->isFunctionParallel()); // function-parallel passes get a new instance per function auto instance = std::unique_ptr<Pass>(pass->create()); + std::unique_ptr<AfterEffectFunctionChecker> checker; + if (getPassDebug()) { + checker = std::unique_ptr<AfterEffectFunctionChecker>( + new AfterEffectFunctionChecker(func)); + } instance->runOnFunction(this, wasm, func); + handleAfterEffects(pass, func); + if (getPassDebug()) { + checker->check(); + } +} + +void PassRunner::handleAfterEffects(Pass* pass, Function* func) { + if (pass->modifiesBinaryenIR()) { + // If Binaryen IR is modified, Stack IR must be cleared - it would + // be out of sync in a potentially dangerous way. + if (func) { + func->stackIR.reset(nullptr); + } else { + for (auto& func : wasm->functions) { + func->stackIR.reset(nullptr); + } + } + } } int PassRunner::getPassDebug() { diff --git a/src/passes/passes.h b/src/passes/passes.h index 7a96799b3..1e26dc777 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -34,6 +34,7 @@ Pass* createFlattenPass(); Pass* createFuncCastEmulationPass(); Pass* createFullPrinterPass(); Pass* createFunctionMetricsPass(); +Pass* createGenerateStackIRPass(); Pass* createI64ToI32LoweringPass(); Pass* createInliningPass(); Pass* createInliningOptimizingPass(); @@ -49,12 +50,14 @@ Pass* createMinifiedPrinterPass(); Pass* createMetricsPass(); Pass* createNameListPass(); Pass* createOptimizeInstructionsPass(); +Pass* createOptimizeStackIRPass(); Pass* createPickLoadSignsPass(); Pass* createPostEmscriptenPass(); Pass* createPrecomputePass(); Pass* createPrecomputePropagatePass(); Pass* createPrinterPass(); Pass* createPrintCallGraphPass(); +Pass* createPrintStackIRPass(); Pass* createRelooperJumpThreadingPass(); Pass* createRemoveNonJSOpsPass(); Pass* createRemoveImportsPass(); diff --git a/src/support/hash.h b/src/support/hash.h index 158f20773..98d7ceead 100644 --- a/src/support/hash.h +++ b/src/support/hash.h @@ -22,9 +22,11 @@ namespace wasm { -inline uint32_t rehash(uint32_t x, uint32_t y) { +typedef uint32_t HashType; + +inline HashType rehash(HashType x, HashType y) { // see http://www.cse.yorku.ca/~oz/hash.html and https://stackoverflow.com/a/2595226/1176841 - uint32_t hash = 5381; + HashType hash = 5381; while (x) { hash = ((hash << 5) + hash) ^ (x & 0xff); x >>= 8; @@ -37,9 +39,9 @@ inline uint32_t rehash(uint32_t x, uint32_t y) { } inline uint64_t rehash(uint64_t x, uint64_t y) { - auto ret = rehash(uint32_t(x), uint32_t(x >> 32)); - ret = rehash(ret, uint32_t(y)); - return rehash(ret, uint32_t(y >> 32)); + auto ret = rehash(HashType(x), HashType(x >> 32)); + ret = rehash(ret, HashType(y)); + return rehash(ret, HashType(y >> 32)); } } // namespace wasm diff --git a/src/wasm-binary.h b/src/wasm-binary.h index cdac878c1..670084401 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -652,96 +652,14 @@ inline S32LEB binaryType(Type type) { return S32LEB(ret); } -class WasmBinaryWriter; - -// Writes out binary format stack machine code for a Binaryen IR expression - -class StackWriter : public Visitor<StackWriter> { -public: - // Without a function (offset for a global thing, etc.) - StackWriter(WasmBinaryWriter& parent, BufferWithRandomAccess& o, bool debug=false) - : func(nullptr), parent(parent), o(o), sourceMap(false), debug(debug) {} - - // With a function - one is created for the entire function - StackWriter(Function* func, WasmBinaryWriter& parent, BufferWithRandomAccess& o, bool sourceMap=false, bool debug=false) - : func(func), parent(parent), o(o), sourceMap(sourceMap), debug(debug) { - mapLocals(); - } - - std::map<Type, size_t> numLocalsByType; // type => number of locals of that type in the compact form - - // visits a node, emitting the proper code for it - void visit(Expression* curr); - // emits a node, but if it is a block with no name, emit a list of its contents - void visitPossibleBlockContents(Expression* curr); - - void visitBlock(Block *curr); - void visitIf(If *curr); - void visitLoop(Loop *curr); - void visitBreak(Break *curr); - void visitSwitch(Switch *curr); - void visitCall(Call *curr); - void visitCallImport(CallImport *curr); - void visitCallIndirect(CallIndirect *curr); - void visitGetLocal(GetLocal *curr); - void visitSetLocal(SetLocal *curr); - void visitGetGlobal(GetGlobal *curr); - void visitSetGlobal(SetGlobal *curr); - void visitLoad(Load *curr); - void visitStore(Store *curr); - void visitAtomicRMW(AtomicRMW *curr); - void visitAtomicCmpxchg(AtomicCmpxchg *curr); - void visitAtomicWait(AtomicWait *curr); - void visitAtomicWake(AtomicWake *curr); - void visitConst(Const *curr); - void visitUnary(Unary *curr); - void visitBinary(Binary *curr); - void visitSelect(Select *curr); - void visitReturn(Return *curr); - void visitHost(Host *curr); - void visitNop(Nop *curr); - void visitUnreachable(Unreachable *curr); - void visitDrop(Drop *curr); - -private: - Function* func; - WasmBinaryWriter& parent; - BufferWithRandomAccess& o; - bool sourceMap; - bool debug; - - std::map<Index, size_t> mappedLocals; // local index => index in compact form of [all int32s][all int64s]etc - - std::vector<Name> breakStack; - - int32_t getBreakIndex(Name name); - void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset); - - void mapLocals(); -}; - // Writes out wasm to the binary format class WasmBinaryWriter { - Module* wasm; - BufferWithRandomAccess& o; - bool debug; - bool debugInfo = true; - std::ostream* sourceMap = nullptr; - std::string sourceMapUrl; - std::string symbolMap; - - MixedArena allocator; - - // storage of source map locations until the section is placed at its final location - // (shrinking LEBs may cause changes there) - std::vector<std::pair<size_t, const Function::DebugLocation*>> sourceMapLocations; - size_t sourceMapLocationsSizeAtSectionStart; - Function::DebugLocation lastDebugLocation; - - void prepare(); public: - WasmBinaryWriter(Module* input, BufferWithRandomAccess& o, bool debug = false) : wasm(input), o(o), debug(debug) { + WasmBinaryWriter(Module* input, + BufferWithRandomAccess& o, + bool debug = false) : + wasm(input), o(o), debug(debug) { prepare(); } @@ -817,6 +735,28 @@ public: void emitBuffer(const char* data, size_t size); void emitString(const char *str); void finishUp(); + + Module* getModule() { return wasm; } + +private: + Module* wasm; + BufferWithRandomAccess& o; + bool debug; + + bool debugInfo = true; + std::ostream* sourceMap = nullptr; + std::string sourceMapUrl; + std::string symbolMap; + + MixedArena allocator; + + // storage of source map locations until the section is placed at its final location + // (shrinking LEBs may cause changes there) + std::vector<std::pair<size_t, const Function::DebugLocation*>> sourceMapLocations; + size_t sourceMapLocationsSizeAtSectionStart; + Function::DebugLocation lastDebugLocation; + + void prepare(); }; class WasmBinaryBuilder { @@ -967,16 +907,16 @@ public: BinaryConsts::ASTNodes readExpression(Expression*& curr); void pushBlockElements(Block* curr, size_t start, size_t end); - void visitBlock(Block *curr); + void visitBlock(Block* curr); // Gets a block of expressions. If it's just one, return that singleton. Expression* getBlockOrSingleton(Type type); - void visitIf(If *curr); - void visitLoop(Loop *curr); + void visitIf(If* curr); + void visitLoop(Loop* curr); BreakTarget getBreakTarget(int32_t offset); void visitBreak(Break *curr, uint8_t code); - void visitSwitch(Switch *curr); + void visitSwitch(Switch* curr); template<typename T> void fillCall(T* call, FunctionType* type) { @@ -990,11 +930,11 @@ public: } Expression* visitCall(); - void visitCallIndirect(CallIndirect *curr); - void visitGetLocal(GetLocal *curr); + void visitCallIndirect(CallIndirect* curr); + void visitGetLocal(GetLocal* curr); void visitSetLocal(SetLocal *curr, uint8_t code); - void visitGetGlobal(GetGlobal *curr); - void visitSetGlobal(SetGlobal *curr); + void visitGetGlobal(GetGlobal* curr); + void visitSetGlobal(SetGlobal* curr); void readMemoryAccess(Address& alignment, Address& offset); bool maybeVisitLoad(Expression*& out, uint8_t code, bool isAtomic); bool maybeVisitStore(Expression*& out, uint8_t code, bool isAtomic); @@ -1005,12 +945,12 @@ public: bool maybeVisitConst(Expression*& out, uint8_t code); bool maybeVisitUnary(Expression*& out, uint8_t code); bool maybeVisitBinary(Expression*& out, uint8_t code); - void visitSelect(Select *curr); - void visitReturn(Return *curr); + void visitSelect(Select* curr); + void visitReturn(Return* curr); bool maybeVisitHost(Expression*& out, uint8_t code); - void visitNop(Nop *curr); - void visitUnreachable(Unreachable *curr); - void visitDrop(Drop *curr); + void visitNop(Nop* curr); + void visitUnreachable(Unreachable* curr); + void visitDrop(Drop* curr); void throwError(std::string text); }; diff --git a/src/wasm-stack.h b/src/wasm-stack.h new file mode 100644 index 000000000..8648148b6 --- /dev/null +++ b/src/wasm-stack.h @@ -0,0 +1,1244 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_stack_h +#define wasm_stack_h + +#include "wasm.h" +#include "wasm-binary.h" +#include "wasm-traversal.h" +#include "ir/branch-utils.h" +#include "pass.h" + +namespace wasm { + +// Stack IR: an IR that represents code at the wasm binary format level, +// that is, a stack machine. Binaryen IR is *almost* identical to this, +// but as documented in README.md, there are a few differences, intended +// to make Binaryen IR fast and flexible for maximal optimization. Stack +// IR, on the other hand, is designed to optimize a few final things that +// can only really be done when modeling the stack machine format precisely. + +// Currently the benefits of Stack IR are minor, less than 1% reduction in +// code size. For that reason it is just a secondary IR, run optionally +// after the main IR has been optimized. However, if we improve Stack IR +// optimizations to a point where they have a significant impact, it's +// possible that could motivate investigating replacing the main IR with Stack +// IR (so that we have just a single IR). + +// A StackIR instance (see wasm.h) contains a linear sequence of +// stack instructions. This representation is very simple: just a single vector of +// all instructions, in order. +// * nullptr is allowed in the vector, representing something to skip. +// This is useful as a common thing optimizations do is remove instructions, +// so this way we can do so without compacting the vector all the time. + +// A Stack IR instruction. Most just directly reflect a Binaryen IR node, +// but we need extra ones for certain things. +class StackInst { +public: + StackInst(MixedArena&) {} + + enum Op { + Basic, // an instruction directly corresponding to a non-control-flow + // Binaryen IR node + BlockBegin, // the beginning of a block + BlockEnd, // the ending of a block + IfBegin, // the beginning of a if + IfElse, // the else of a if + IfEnd, // the ending of a if + LoopBegin, // the beginning of a loop + LoopEnd, // the ending of a loop + } op; + + Expression* origin; // the expression this originates from + + Type type; // the type - usually identical to the origin type, but + // e.g. wasm has no unreachable blocks, they must be none +}; + +} // namespace wasm + +namespace std { + +inline std::ostream& operator<<(std::ostream& o, wasm::StackInst& inst) { + switch (inst.op) { + case wasm::StackInst::Basic: { + std::cout << wasm::getExpressionName(inst.origin) << " (" << wasm::printType(inst.type) << ')'; + break; + } + case wasm::StackInst::BlockBegin: + case wasm::StackInst::IfBegin: + case wasm::StackInst::LoopBegin: { + std::cout << wasm::getExpressionName(inst.origin); + break; + } + case wasm::StackInst::BlockEnd: + case wasm::StackInst::IfEnd: + case wasm::StackInst::LoopEnd: { + std::cout << "end (" << wasm::printType(inst.type) << ')'; + break; + } + case wasm::StackInst::IfElse: { + std::cout << "else"; + break; + } + default: WASM_UNREACHABLE(); + } + return o; +} + +inline std::ostream& operator<<(std::ostream& o, wasm::StackIR& insts) { + wasm::Index index = 0; + for (wasm::Index i = 0; i < insts.size(); i++) { + auto* inst = insts[i]; + if (!inst) continue; + std::cout << index++ << ' ' << *inst << '\n'; + } + return o; +} + +} // namespace std + +namespace wasm { + +// +// StackWriter: Writes out binary format stack machine code for a Binaryen IR expression +// +// A stack writer has one of three modes: +// * Binaryen2Binary: directly writes the expression to wasm binary +// * Binaryen2Stack: queues the expressions linearly, in Stack IR (SIR) +// * Stack2Binary: emits SIR to wasm binary +// +// Direct writing, in Binaryen2Binary, is fast. Otherwise, Binaryen2Stack +// lets you optimize the Stack IR before running Stack2Binary (but the cost +// is that the extra IR in the middle makes things 20% slower than direct +// Binaryen2Binary). +// +// To reduce the amount of boilerplate code here, we implement all 3 in +// a single class, templated on the mode. This allows compilers to trivially +// optimize out irrelevant code paths, and there should be no runtime +// downside. +// + +enum class StackWriterMode { + Binaryen2Binary, Binaryen2Stack, Stack2Binary +}; + +template<StackWriterMode Mode, typename Parent> +class StackWriter : public Visitor<StackWriter<Mode, Parent>> { +public: + StackWriter(Parent& parent, BufferWithRandomAccess& o, bool sourceMap=false, bool debug=false) + : parent(parent), o(o), sourceMap(sourceMap), debug(debug), allocator(parent.getModule()->allocator) {} + + StackIR stackIR; // filled in Binaryen2Stack, read in Stack2Binary + + std::map<Type, size_t> numLocalsByType; // type => number of locals of that type in the compact form + + // visits a node, emitting the proper code for it + void visit(Expression* curr); + // emits a node, but if it is a block with no name, emit a list of its contents + void visitPossibleBlockContents(Expression* curr); + // visits a child node. (in some modes we may not want to visit children, + // that logic is handled here) + void visitChild(Expression* curr); + + void visitBlock(Block* curr); + void visitBlockEnd(Block* curr); + + void visitIf(If* curr); + void visitIfElse(If* curr); + void visitIfEnd(If* curr); + + void visitLoop(Loop* curr); + void visitLoopEnd(Loop* curr); + + void visitBreak(Break* curr); + void visitSwitch(Switch* curr); + void visitCall(Call* curr); + void visitCallImport(CallImport* curr); + void visitCallIndirect(CallIndirect* curr); + void visitGetLocal(GetLocal* curr); + void visitSetLocal(SetLocal* curr); + void visitGetGlobal(GetGlobal* curr); + void visitSetGlobal(SetGlobal* curr); + void visitLoad(Load* curr); + void visitStore(Store* curr); + void visitAtomicRMW(AtomicRMW* curr); + void visitAtomicCmpxchg(AtomicCmpxchg* curr); + void visitAtomicWait(AtomicWait* curr); + void visitAtomicWake(AtomicWake* curr); + void visitConst(Const* curr); + void visitUnary(Unary* curr); + void visitBinary(Binary* curr); + void visitSelect(Select* curr); + void visitReturn(Return* curr); + void visitHost(Host* curr); + void visitNop(Nop* curr); + void visitUnreachable(Unreachable* curr); + void visitDrop(Drop* curr); + + // We need to emit extra unreachable opcodes in some cases + void emitExtraUnreachable(); + + // If we are in Binaryen2Stack, then this adds the item to the + // stack IR and returns true, which is all we need to do for + // non-control flow expressions. + bool justAddToStack(Expression* curr); + + void setFunction(Function* funcInit) { + func = funcInit; + } + + void mapLocalsAndEmitHeader(); + +protected: + Parent& parent; + BufferWithRandomAccess& o; + bool sourceMap; + bool debug; + + MixedArena& allocator; + + Function* func; + + std::map<Index, size_t> mappedLocals; // local index => index in compact form of [all int32s][all int64s]etc + + std::vector<Name> breakStack; + + int32_t getBreakIndex(Name name); + void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset); + + void finishFunctionBody(); + + StackInst* makeStackInst(StackInst::Op op, Expression* origin); + StackInst* makeStackInst(Expression* origin) { + return makeStackInst(StackInst::Basic, origin); + } +}; + +// Write out a single expression, such as an offset for a global segment. +template<typename Parent> +class ExpressionStackWriter : StackWriter<StackWriterMode::Binaryen2Binary, Parent> { +public: + ExpressionStackWriter(Expression* curr, Parent& parent, BufferWithRandomAccess& o, bool debug=false) : + StackWriter<StackWriterMode::Binaryen2Binary, Parent>(parent, o, /* sourceMap= */ false, debug) { + this->visit(curr); + } +}; + +// Write out a function body, including the local header info. +template<typename Parent> +class FunctionStackWriter : StackWriter<StackWriterMode::Binaryen2Binary, Parent> { +public: + FunctionStackWriter(Function* funcInit, Parent& parent, BufferWithRandomAccess& o, bool sourceMap=false, bool debug=false) : + StackWriter<StackWriterMode::Binaryen2Binary, Parent>(parent, o, sourceMap, debug) { + this->setFunction(funcInit); + this->mapLocalsAndEmitHeader(); + this->visitPossibleBlockContents(this->func->body); + this->finishFunctionBody(); + } +}; + +// Use Stack IR to write the function body +template<typename Parent> +class StackIRFunctionStackWriter : StackWriter<StackWriterMode::Stack2Binary, Parent> { +public: + StackIRFunctionStackWriter(Function* funcInit, Parent& parent, BufferWithRandomAccess& o, bool debug=false) : + StackWriter<StackWriterMode::Stack2Binary, Parent>(parent, o, false, debug) { + this->setFunction(funcInit); + this->mapLocalsAndEmitHeader(); + for (auto* inst : *funcInit->stackIR) { + if (!inst) continue; // a nullptr is just something we can skip + switch (inst->op) { + case StackInst::Basic: + case StackInst::BlockBegin: + case StackInst::IfBegin: + case StackInst::LoopBegin: { + this->visit(inst->origin); + break; + } + case StackInst::BlockEnd: { + this->visitBlockEnd(inst->origin->template cast<Block>()); + break; + } + case StackInst::IfElse: { + this->visitIfElse(inst->origin->template cast<If>()); + break; + } + case StackInst::IfEnd: { + this->visitIfEnd(inst->origin->template cast<If>()); + break; + } + case StackInst::LoopEnd: { + this->visitLoopEnd(inst->origin->template cast<Loop>()); + break; + } + default: WASM_UNREACHABLE(); + } + } + this->finishFunctionBody(); + } +}; + +// +// Implementations +// + +// StackWriter + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::mapLocalsAndEmitHeader() { + // Map them + for (Index i = 0; i < func->getNumParams(); i++) { + size_t curr = mappedLocals.size(); + mappedLocals[i] = curr; + } + for (auto type : func->vars) { + numLocalsByType[type]++; + } + std::map<Type, size_t> currLocalsByType; + for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) { + size_t index = func->getVarIndexBase(); + Type type = func->getLocalType(i); + currLocalsByType[type]++; // increment now for simplicity, must decrement it in returns + if (type == i32) { + mappedLocals[i] = index + currLocalsByType[i32] - 1; + continue; + } + index += numLocalsByType[i32]; + if (type == i64) { + mappedLocals[i] = index + currLocalsByType[i64] - 1; + continue; + } + index += numLocalsByType[i64]; + if (type == f32) { + mappedLocals[i] = index + currLocalsByType[f32] - 1; + continue; + } + index += numLocalsByType[f32]; + if (type == f64) { + mappedLocals[i] = index + currLocalsByType[f64] - 1; + continue; + } + WASM_UNREACHABLE(); + } + // Emit them. + o << U32LEB( + (numLocalsByType[i32] ? 1 : 0) + + (numLocalsByType[i64] ? 1 : 0) + + (numLocalsByType[f32] ? 1 : 0) + + (numLocalsByType[f64] ? 1 : 0) + ); + if (numLocalsByType[i32]) o << U32LEB(numLocalsByType[i32]) << binaryType(i32); + if (numLocalsByType[i64]) o << U32LEB(numLocalsByType[i64]) << binaryType(i64); + if (numLocalsByType[f32]) o << U32LEB(numLocalsByType[f32]) << binaryType(f32); + if (numLocalsByType[f64]) o << U32LEB(numLocalsByType[f64]) << binaryType(f64); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visit(Expression* curr) { + if (Mode == StackWriterMode::Binaryen2Binary && sourceMap) { + parent.writeDebugLocation(curr, func); + } + Visitor<StackWriter>::visit(curr); +} + +// emits a node, but if it is a block with no name, emit a list of its contents +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitPossibleBlockContents(Expression* curr) { + auto* block = curr->dynCast<Block>(); + if (!block || BranchUtils::BranchSeeker::hasNamed(block, block->name)) { + visitChild(curr); + return; + } + for (auto* child : block->list) { + visitChild(child); + } + if (block->type == unreachable && block->list.back()->type != unreachable) { + // similar to in visitBlock, here we could skip emitting the block itself, + // but must still end the 'block' (the contents, really) with an unreachable + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitChild(Expression* curr) { + // In stack => binary, we don't need to visit child nodes, everything + // is already in the linear stream. + if (Mode != StackWriterMode::Stack2Binary) { + visit(curr); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitBlock(Block* curr) { + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::BlockBegin, curr)); + } else { + if (debug) std::cerr << "zz node: Block" << std::endl; + o << int8_t(BinaryConsts::Block); + o << binaryType(curr->type != unreachable ? curr->type : none); + } + breakStack.push_back(curr->name); // TODO: we don't need to do this in Binaryen2Stack + Index i = 0; + for (auto* child : curr->list) { + if (debug) std::cerr << " " << size_t(curr) << "\n zz Block element " << i++ << std::endl; + visitChild(child); + } + // in Stack2Binary the block ending is in the stream later on + if (Mode == StackWriterMode::Stack2Binary) { + return; + } + visitBlockEnd(curr); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitBlockEnd(Block* curr) { + if (curr->type == unreachable) { + // an unreachable block is one that cannot be exited. We cannot encode this directly + // in wasm, where blocks must be none,i32,i64,f32,f64. Since the block cannot be + // exited, we can emit an unreachable at the end, and that will always be valid, + // and then the block is ok as a none + emitExtraUnreachable(); + } + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::BlockEnd, curr)); + } else { + o << int8_t(BinaryConsts::End); + } + assert(!breakStack.empty()); + breakStack.pop_back(); + if (curr->type == unreachable) { + // and emit an unreachable *outside* the block too, so later things can pop anything + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitIf(If* curr) { + if (debug) std::cerr << "zz node: If" << std::endl; + if (curr->condition->type == unreachable) { + // this if-else is unreachable because of the condition, i.e., the condition + // does not exit. So don't emit the if, but do consume the condition + visitChild(curr->condition); + emitExtraUnreachable(); + return; + } + visitChild(curr->condition); + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::IfBegin, curr)); + } else { + o << int8_t(BinaryConsts::If); + o << binaryType(curr->type != unreachable ? curr->type : none); + } + breakStack.push_back(IMPOSSIBLE_CONTINUE); // the binary format requires this; we have a block if we need one + // TODO: optimize this in Stack IR (if child is a block, we + // may break to this instead) + visitPossibleBlockContents(curr->ifTrue); // TODO: emit block contents directly, if possible + if (Mode == StackWriterMode::Stack2Binary) { + return; + } + if (curr->ifFalse) { + visitIfElse(curr); + } + visitIfEnd(curr); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitIfElse(If* curr) { + assert(!breakStack.empty()); + breakStack.pop_back(); + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::IfElse, curr)); + } else { + o << int8_t(BinaryConsts::Else); + } + breakStack.push_back(IMPOSSIBLE_CONTINUE); // TODO ditto + visitPossibleBlockContents(curr->ifFalse); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitIfEnd(If* curr) { + assert(!breakStack.empty()); + breakStack.pop_back(); + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::IfEnd, curr)); + } else { + o << int8_t(BinaryConsts::End); + } + if (curr->type == unreachable) { + // we already handled the case of the condition being unreachable. otherwise, + // we may still be unreachable, if we are an if-else with both sides unreachable. + // wasm does not allow this to be emitted directly, so we must do something more. we could do + // better, but for now we emit an extra unreachable instruction after the if, so it is not consumed itself, + assert(curr->ifFalse); + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitLoop(Loop* curr) { + if (debug) std::cerr << "zz node: Loop" << std::endl; + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::LoopBegin, curr)); + } else { + o << int8_t(BinaryConsts::Loop); + o << binaryType(curr->type != unreachable ? curr->type : none); + } + breakStack.push_back(curr->name); + visitPossibleBlockContents(curr->body); + if (Mode == StackWriterMode::Stack2Binary) { + return; + } + visitLoopEnd(curr); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitLoopEnd(Loop* curr) { + assert(!breakStack.empty()); + breakStack.pop_back(); + if (curr->type == unreachable) { + // we emitted a loop without a return type, and the body might be + // block contents, so ensure it is not consumed + emitExtraUnreachable(); + } + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(StackInst::LoopEnd, curr)); + } else { + o << int8_t(BinaryConsts::End); + } + if (curr->type == unreachable) { + // we emitted a loop without a return type, so it must not be consumed + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitBreak(Break* curr) { + if (debug) std::cerr << "zz node: Break" << std::endl; + if (curr->value) { + visitChild(curr->value); + } + if (curr->condition) visitChild(curr->condition); + if (!justAddToStack(curr)) { + o << int8_t(curr->condition ? BinaryConsts::BrIf : BinaryConsts::Br) + << U32LEB(getBreakIndex(curr->name)); + } + if (curr->condition && curr->type == unreachable) { + // a br_if is normally none or emits a value. if it is unreachable, + // then either the condition or the value is unreachable, which is + // extremely rare, and may require us to make the stack polymorphic + // (if the block we branch to has a value, we may lack one as we + // are not a reachable branch; the wasm spec on the other hand does + // presume the br_if emits a value of the right type, even if it + // popped unreachable) + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitSwitch(Switch* curr) { + if (debug) std::cerr << "zz node: Switch" << std::endl; + if (curr->value) { + visitChild(curr->value); + } + visitChild(curr->condition); + if (!BranchUtils::isBranchReachable(curr)) { + // if the branch is not reachable, then it's dangerous to emit it, as + // wasm type checking rules are different, especially in unreachable + // code. so just don't emit that unreachable code. + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size()); + for (auto target : curr->targets) { + o << U32LEB(getBreakIndex(target)); + } + o << U32LEB(getBreakIndex(curr->default_)); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitCall(Call* curr) { + if (debug) std::cerr << "zz node: Call" << std::endl; + for (auto* operand : curr->operands) { + visitChild(operand); + } + if (!justAddToStack(curr)) { + o << int8_t(BinaryConsts::CallFunction) << U32LEB(parent.getFunctionIndex(curr->target)); + } + if (curr->type == unreachable) { // TODO FIXME: this and similar can be removed + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitCallImport(CallImport* curr) { + if (debug) std::cerr << "zz node: CallImport" << std::endl; + for (auto* operand : curr->operands) { + visitChild(operand); + } + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::CallFunction) << U32LEB(parent.getFunctionIndex(curr->target)); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitCallIndirect(CallIndirect* curr) { + if (debug) std::cerr << "zz node: CallIndirect" << std::endl; + for (auto* operand : curr->operands) { + visitChild(operand); + } + visitChild(curr->target); + if (!justAddToStack(curr)) { + o << int8_t(BinaryConsts::CallIndirect) + << U32LEB(parent.getFunctionTypeIndex(curr->fullType)) + << U32LEB(0); // Reserved flags field + } + if (curr->type == unreachable) { + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitGetLocal(GetLocal* curr) { + if (debug) std::cerr << "zz node: GetLocal " << (o.size() + 1) << std::endl; + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::GetLocal) << U32LEB(mappedLocals[curr->index]); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitSetLocal(SetLocal* curr) { + if (debug) std::cerr << "zz node: Set|TeeLocal" << std::endl; + visitChild(curr->value); + if (!justAddToStack(curr)) { + o << int8_t(curr->isTee() ? BinaryConsts::TeeLocal : BinaryConsts::SetLocal) << U32LEB(mappedLocals[curr->index]); + } + if (curr->type == unreachable) { + emitExtraUnreachable(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitGetGlobal(GetGlobal* curr) { + if (debug) std::cerr << "zz node: GetGlobal " << (o.size() + 1) << std::endl; + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::GetGlobal) << U32LEB(parent.getGlobalIndex(curr->name)); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitSetGlobal(SetGlobal* curr) { + if (debug) std::cerr << "zz node: SetGlobal" << std::endl; + visitChild(curr->value); + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::SetGlobal) << U32LEB(parent.getGlobalIndex(curr->name)); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitLoad(Load* curr) { + if (debug) std::cerr << "zz node: Load" << std::endl; + visitChild(curr->ptr); + if (curr->type == unreachable) { + // don't even emit it; we don't know the right type + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + if (!curr->isAtomic) { + switch (curr->type) { + case i32: { + switch (curr->bytes) { + case 1: o << int8_t(curr->signed_ ? BinaryConsts::I32LoadMem8S : BinaryConsts::I32LoadMem8U); break; + case 2: o << int8_t(curr->signed_ ? BinaryConsts::I32LoadMem16S : BinaryConsts::I32LoadMem16U); break; + case 4: o << int8_t(BinaryConsts::I32LoadMem); break; + default: abort(); + } + break; + } + case i64: { + switch (curr->bytes) { + case 1: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem8S : BinaryConsts::I64LoadMem8U); break; + case 2: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem16S : BinaryConsts::I64LoadMem16U); break; + case 4: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem32S : BinaryConsts::I64LoadMem32U); break; + case 8: o << int8_t(BinaryConsts::I64LoadMem); break; + default: abort(); + } + break; + } + case f32: o << int8_t(BinaryConsts::F32LoadMem); break; + case f64: o << int8_t(BinaryConsts::F64LoadMem); break; + case unreachable: return; // the pointer is unreachable, so we are never reached; just don't emit a load + default: WASM_UNREACHABLE(); + } + } else { + o << int8_t(BinaryConsts::AtomicPrefix); + switch (curr->type) { + case i32: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I32AtomicLoad8U); break; + case 2: o << int8_t(BinaryConsts::I32AtomicLoad16U); break; + case 4: o << int8_t(BinaryConsts::I32AtomicLoad); break; + default: WASM_UNREACHABLE(); + } + break; + } + case i64: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I64AtomicLoad8U); break; + case 2: o << int8_t(BinaryConsts::I64AtomicLoad16U); break; + case 4: o << int8_t(BinaryConsts::I64AtomicLoad32U); break; + case 8: o << int8_t(BinaryConsts::I64AtomicLoad); break; + default: WASM_UNREACHABLE(); + } + break; + } + case unreachable: return; + default: WASM_UNREACHABLE(); + } + } + emitMemoryAccess(curr->align, curr->bytes, curr->offset); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitStore(Store* curr) { + if (debug) std::cerr << "zz node: Store" << std::endl; + visitChild(curr->ptr); + visitChild(curr->value); + if (curr->type == unreachable) { + // don't even emit it; we don't know the right type + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + if (!curr->isAtomic) { + switch (curr->valueType) { + case i32: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I32StoreMem8); break; + case 2: o << int8_t(BinaryConsts::I32StoreMem16); break; + case 4: o << int8_t(BinaryConsts::I32StoreMem); break; + default: abort(); + } + break; + } + case i64: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I64StoreMem8); break; + case 2: o << int8_t(BinaryConsts::I64StoreMem16); break; + case 4: o << int8_t(BinaryConsts::I64StoreMem32); break; + case 8: o << int8_t(BinaryConsts::I64StoreMem); break; + default: abort(); + } + break; + } + case f32: o << int8_t(BinaryConsts::F32StoreMem); break; + case f64: o << int8_t(BinaryConsts::F64StoreMem); break; + default: abort(); + } + } else { + o << int8_t(BinaryConsts::AtomicPrefix); + switch (curr->valueType) { + case i32: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I32AtomicStore8); break; + case 2: o << int8_t(BinaryConsts::I32AtomicStore16); break; + case 4: o << int8_t(BinaryConsts::I32AtomicStore); break; + default: WASM_UNREACHABLE(); + } + break; + } + case i64: { + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I64AtomicStore8); break; + case 2: o << int8_t(BinaryConsts::I64AtomicStore16); break; + case 4: o << int8_t(BinaryConsts::I64AtomicStore32); break; + case 8: o << int8_t(BinaryConsts::I64AtomicStore); break; + default: WASM_UNREACHABLE(); + } + break; + } + default: WASM_UNREACHABLE(); + } + } + emitMemoryAccess(curr->align, curr->bytes, curr->offset); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitAtomicRMW(AtomicRMW* curr) { + if (debug) std::cerr << "zz node: AtomicRMW" << std::endl; + visitChild(curr->ptr); + // stop if the rest isn't reachable anyhow + if (curr->ptr->type == unreachable) return; + visitChild(curr->value); + if (curr->value->type == unreachable) return; + if (curr->type == unreachable) { + // don't even emit it; we don't know the right type + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + + o << int8_t(BinaryConsts::AtomicPrefix); + +#define CASE_FOR_OP(Op) \ + case Op: \ + switch (curr->type) { \ + case i32: \ + switch (curr->bytes) { \ + case 1: o << int8_t(BinaryConsts::I32AtomicRMW##Op##8U); break; \ + case 2: o << int8_t(BinaryConsts::I32AtomicRMW##Op##16U); break; \ + case 4: o << int8_t(BinaryConsts::I32AtomicRMW##Op); break; \ + default: WASM_UNREACHABLE(); \ + } \ + break; \ + case i64: \ + switch (curr->bytes) { \ + case 1: o << int8_t(BinaryConsts::I64AtomicRMW##Op##8U); break; \ + case 2: o << int8_t(BinaryConsts::I64AtomicRMW##Op##16U); break; \ + case 4: o << int8_t(BinaryConsts::I64AtomicRMW##Op##32U); break; \ + case 8: o << int8_t(BinaryConsts::I64AtomicRMW##Op); break; \ + default: WASM_UNREACHABLE(); \ + } \ + break; \ + default: WASM_UNREACHABLE(); \ + } \ + break + + switch(curr->op) { + CASE_FOR_OP(Add); + CASE_FOR_OP(Sub); + CASE_FOR_OP(And); + CASE_FOR_OP(Or); + CASE_FOR_OP(Xor); + CASE_FOR_OP(Xchg); + default: WASM_UNREACHABLE(); + } +#undef CASE_FOR_OP + + emitMemoryAccess(curr->bytes, curr->bytes, curr->offset); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitAtomicCmpxchg(AtomicCmpxchg* curr) { + if (debug) std::cerr << "zz node: AtomicCmpxchg" << std::endl; + visitChild(curr->ptr); + // stop if the rest isn't reachable anyhow + if (curr->ptr->type == unreachable) return; + visitChild(curr->expected); + if (curr->expected->type == unreachable) return; + visitChild(curr->replacement); + if (curr->replacement->type == unreachable) return; + if (curr->type == unreachable) { + // don't even emit it; we don't know the right type + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + + o << int8_t(BinaryConsts::AtomicPrefix); + switch (curr->type) { + case i32: + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I32AtomicCmpxchg8U); break; + case 2: o << int8_t(BinaryConsts::I32AtomicCmpxchg16U); break; + case 4: o << int8_t(BinaryConsts::I32AtomicCmpxchg); break; + default: WASM_UNREACHABLE(); + } + break; + case i64: + switch (curr->bytes) { + case 1: o << int8_t(BinaryConsts::I64AtomicCmpxchg8U); break; + case 2: o << int8_t(BinaryConsts::I64AtomicCmpxchg16U); break; + case 4: o << int8_t(BinaryConsts::I64AtomicCmpxchg32U); break; + case 8: o << int8_t(BinaryConsts::I64AtomicCmpxchg); break; + default: WASM_UNREACHABLE(); + } + break; + default: WASM_UNREACHABLE(); + } + emitMemoryAccess(curr->bytes, curr->bytes, curr->offset); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitAtomicWait(AtomicWait* curr) { + if (debug) std::cerr << "zz node: AtomicWait" << std::endl; + visitChild(curr->ptr); + // stop if the rest isn't reachable anyhow + if (curr->ptr->type == unreachable) return; + visitChild(curr->expected); + if (curr->expected->type == unreachable) return; + visitChild(curr->timeout); + if (curr->timeout->type == unreachable) return; + if (justAddToStack(curr)) return; + + o << int8_t(BinaryConsts::AtomicPrefix); + switch (curr->expectedType) { + case i32: { + o << int8_t(BinaryConsts::I32AtomicWait); + emitMemoryAccess(4, 4, 0); + break; + } + case i64: { + o << int8_t(BinaryConsts::I64AtomicWait); + emitMemoryAccess(8, 8, 0); + break; + } + default: WASM_UNREACHABLE(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitAtomicWake(AtomicWake* curr) { + if (debug) std::cerr << "zz node: AtomicWake" << std::endl; + visitChild(curr->ptr); + // stop if the rest isn't reachable anyhow + if (curr->ptr->type == unreachable) return; + visitChild(curr->wakeCount); + if (curr->wakeCount->type == unreachable) return; + if (justAddToStack(curr)) return; + + o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicWake); + emitMemoryAccess(4, 4, 0); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitConst(Const* curr) { + if (debug) std::cerr << "zz node: Const" << curr << " : " << curr->type << std::endl; + if (justAddToStack(curr)) return; + switch (curr->type) { + case i32: { + o << int8_t(BinaryConsts::I32Const) << S32LEB(curr->value.geti32()); + break; + } + case i64: { + o << int8_t(BinaryConsts::I64Const) << S64LEB(curr->value.geti64()); + break; + } + case f32: { + o << int8_t(BinaryConsts::F32Const) << curr->value.reinterpreti32(); + break; + } + case f64: { + o << int8_t(BinaryConsts::F64Const) << curr->value.reinterpreti64(); + break; + } + default: abort(); + } + if (debug) std::cerr << "zz const node done.\n"; +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitUnary(Unary* curr) { + if (debug) std::cerr << "zz node: Unary" << std::endl; + visitChild(curr->value); + if (curr->type == unreachable) { + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + switch (curr->op) { + case ClzInt32: o << int8_t(BinaryConsts::I32Clz); break; + case CtzInt32: o << int8_t(BinaryConsts::I32Ctz); break; + case PopcntInt32: o << int8_t(BinaryConsts::I32Popcnt); break; + case EqZInt32: o << int8_t(BinaryConsts::I32EqZ); break; + case ClzInt64: o << int8_t(BinaryConsts::I64Clz); break; + case CtzInt64: o << int8_t(BinaryConsts::I64Ctz); break; + case PopcntInt64: o << int8_t(BinaryConsts::I64Popcnt); break; + case EqZInt64: o << int8_t(BinaryConsts::I64EqZ); break; + case NegFloat32: o << int8_t(BinaryConsts::F32Neg); break; + case AbsFloat32: o << int8_t(BinaryConsts::F32Abs); break; + case CeilFloat32: o << int8_t(BinaryConsts::F32Ceil); break; + case FloorFloat32: o << int8_t(BinaryConsts::F32Floor); break; + case TruncFloat32: o << int8_t(BinaryConsts::F32Trunc); break; + case NearestFloat32: o << int8_t(BinaryConsts::F32NearestInt); break; + case SqrtFloat32: o << int8_t(BinaryConsts::F32Sqrt); break; + case NegFloat64: o << int8_t(BinaryConsts::F64Neg); break; + case AbsFloat64: o << int8_t(BinaryConsts::F64Abs); break; + case CeilFloat64: o << int8_t(BinaryConsts::F64Ceil); break; + case FloorFloat64: o << int8_t(BinaryConsts::F64Floor); break; + case TruncFloat64: o << int8_t(BinaryConsts::F64Trunc); break; + case NearestFloat64: o << int8_t(BinaryConsts::F64NearestInt); break; + case SqrtFloat64: o << int8_t(BinaryConsts::F64Sqrt); break; + case ExtendSInt32: o << int8_t(BinaryConsts::I64STruncI32); break; + case ExtendUInt32: o << int8_t(BinaryConsts::I64UTruncI32); break; + case WrapInt64: o << int8_t(BinaryConsts::I32ConvertI64); break; + case TruncUFloat32ToInt32: o << int8_t(BinaryConsts::I32UTruncF32); break; + case TruncUFloat32ToInt64: o << int8_t(BinaryConsts::I64UTruncF32); break; + case TruncSFloat32ToInt32: o << int8_t(BinaryConsts::I32STruncF32); break; + case TruncSFloat32ToInt64: o << int8_t(BinaryConsts::I64STruncF32); break; + case TruncUFloat64ToInt32: o << int8_t(BinaryConsts::I32UTruncF64); break; + case TruncUFloat64ToInt64: o << int8_t(BinaryConsts::I64UTruncF64); break; + case TruncSFloat64ToInt32: o << int8_t(BinaryConsts::I32STruncF64); break; + case TruncSFloat64ToInt64: o << int8_t(BinaryConsts::I64STruncF64); break; + case ConvertUInt32ToFloat32: o << int8_t(BinaryConsts::F32UConvertI32); break; + case ConvertUInt32ToFloat64: o << int8_t(BinaryConsts::F64UConvertI32); break; + case ConvertSInt32ToFloat32: o << int8_t(BinaryConsts::F32SConvertI32); break; + case ConvertSInt32ToFloat64: o << int8_t(BinaryConsts::F64SConvertI32); break; + case ConvertUInt64ToFloat32: o << int8_t(BinaryConsts::F32UConvertI64); break; + case ConvertUInt64ToFloat64: o << int8_t(BinaryConsts::F64UConvertI64); break; + case ConvertSInt64ToFloat32: o << int8_t(BinaryConsts::F32SConvertI64); break; + case ConvertSInt64ToFloat64: o << int8_t(BinaryConsts::F64SConvertI64); break; + case DemoteFloat64: o << int8_t(BinaryConsts::F32ConvertF64); break; + case PromoteFloat32: o << int8_t(BinaryConsts::F64ConvertF32); break; + case ReinterpretFloat32: o << int8_t(BinaryConsts::I32ReinterpretF32); break; + case ReinterpretFloat64: o << int8_t(BinaryConsts::I64ReinterpretF64); break; + case ReinterpretInt32: o << int8_t(BinaryConsts::F32ReinterpretI32); break; + case ReinterpretInt64: o << int8_t(BinaryConsts::F64ReinterpretI64); break; + case ExtendS8Int32: o << int8_t(BinaryConsts::I32ExtendS8); break; + case ExtendS16Int32: o << int8_t(BinaryConsts::I32ExtendS16); break; + case ExtendS8Int64: o << int8_t(BinaryConsts::I64ExtendS8); break; + case ExtendS16Int64: o << int8_t(BinaryConsts::I64ExtendS16); break; + case ExtendS32Int64: o << int8_t(BinaryConsts::I64ExtendS32); break; + default: abort(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitBinary(Binary* curr) { + if (debug) std::cerr << "zz node: Binary" << std::endl; + visitChild(curr->left); + visitChild(curr->right); + if (curr->type == unreachable) { + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + switch (curr->op) { + case AddInt32: o << int8_t(BinaryConsts::I32Add); break; + case SubInt32: o << int8_t(BinaryConsts::I32Sub); break; + case MulInt32: o << int8_t(BinaryConsts::I32Mul); break; + case DivSInt32: o << int8_t(BinaryConsts::I32DivS); break; + case DivUInt32: o << int8_t(BinaryConsts::I32DivU); break; + case RemSInt32: o << int8_t(BinaryConsts::I32RemS); break; + case RemUInt32: o << int8_t(BinaryConsts::I32RemU); break; + case AndInt32: o << int8_t(BinaryConsts::I32And); break; + case OrInt32: o << int8_t(BinaryConsts::I32Or); break; + case XorInt32: o << int8_t(BinaryConsts::I32Xor); break; + case ShlInt32: o << int8_t(BinaryConsts::I32Shl); break; + case ShrUInt32: o << int8_t(BinaryConsts::I32ShrU); break; + case ShrSInt32: o << int8_t(BinaryConsts::I32ShrS); break; + case RotLInt32: o << int8_t(BinaryConsts::I32RotL); break; + case RotRInt32: o << int8_t(BinaryConsts::I32RotR); break; + case EqInt32: o << int8_t(BinaryConsts::I32Eq); break; + case NeInt32: o << int8_t(BinaryConsts::I32Ne); break; + case LtSInt32: o << int8_t(BinaryConsts::I32LtS); break; + case LtUInt32: o << int8_t(BinaryConsts::I32LtU); break; + case LeSInt32: o << int8_t(BinaryConsts::I32LeS); break; + case LeUInt32: o << int8_t(BinaryConsts::I32LeU); break; + case GtSInt32: o << int8_t(BinaryConsts::I32GtS); break; + case GtUInt32: o << int8_t(BinaryConsts::I32GtU); break; + case GeSInt32: o << int8_t(BinaryConsts::I32GeS); break; + case GeUInt32: o << int8_t(BinaryConsts::I32GeU); break; + + case AddInt64: o << int8_t(BinaryConsts::I64Add); break; + case SubInt64: o << int8_t(BinaryConsts::I64Sub); break; + case MulInt64: o << int8_t(BinaryConsts::I64Mul); break; + case DivSInt64: o << int8_t(BinaryConsts::I64DivS); break; + case DivUInt64: o << int8_t(BinaryConsts::I64DivU); break; + case RemSInt64: o << int8_t(BinaryConsts::I64RemS); break; + case RemUInt64: o << int8_t(BinaryConsts::I64RemU); break; + case AndInt64: o << int8_t(BinaryConsts::I64And); break; + case OrInt64: o << int8_t(BinaryConsts::I64Or); break; + case XorInt64: o << int8_t(BinaryConsts::I64Xor); break; + case ShlInt64: o << int8_t(BinaryConsts::I64Shl); break; + case ShrUInt64: o << int8_t(BinaryConsts::I64ShrU); break; + case ShrSInt64: o << int8_t(BinaryConsts::I64ShrS); break; + case RotLInt64: o << int8_t(BinaryConsts::I64RotL); break; + case RotRInt64: o << int8_t(BinaryConsts::I64RotR); break; + case EqInt64: o << int8_t(BinaryConsts::I64Eq); break; + case NeInt64: o << int8_t(BinaryConsts::I64Ne); break; + case LtSInt64: o << int8_t(BinaryConsts::I64LtS); break; + case LtUInt64: o << int8_t(BinaryConsts::I64LtU); break; + case LeSInt64: o << int8_t(BinaryConsts::I64LeS); break; + case LeUInt64: o << int8_t(BinaryConsts::I64LeU); break; + case GtSInt64: o << int8_t(BinaryConsts::I64GtS); break; + case GtUInt64: o << int8_t(BinaryConsts::I64GtU); break; + case GeSInt64: o << int8_t(BinaryConsts::I64GeS); break; + case GeUInt64: o << int8_t(BinaryConsts::I64GeU); break; + + case AddFloat32: o << int8_t(BinaryConsts::F32Add); break; + case SubFloat32: o << int8_t(BinaryConsts::F32Sub); break; + case MulFloat32: o << int8_t(BinaryConsts::F32Mul); break; + case DivFloat32: o << int8_t(BinaryConsts::F32Div); break; + case CopySignFloat32: o << int8_t(BinaryConsts::F32CopySign);break; + case MinFloat32: o << int8_t(BinaryConsts::F32Min); break; + case MaxFloat32: o << int8_t(BinaryConsts::F32Max); break; + case EqFloat32: o << int8_t(BinaryConsts::F32Eq); break; + case NeFloat32: o << int8_t(BinaryConsts::F32Ne); break; + case LtFloat32: o << int8_t(BinaryConsts::F32Lt); break; + case LeFloat32: o << int8_t(BinaryConsts::F32Le); break; + case GtFloat32: o << int8_t(BinaryConsts::F32Gt); break; + case GeFloat32: o << int8_t(BinaryConsts::F32Ge); break; + + case AddFloat64: o << int8_t(BinaryConsts::F64Add); break; + case SubFloat64: o << int8_t(BinaryConsts::F64Sub); break; + case MulFloat64: o << int8_t(BinaryConsts::F64Mul); break; + case DivFloat64: o << int8_t(BinaryConsts::F64Div); break; + case CopySignFloat64: o << int8_t(BinaryConsts::F64CopySign);break; + case MinFloat64: o << int8_t(BinaryConsts::F64Min); break; + case MaxFloat64: o << int8_t(BinaryConsts::F64Max); break; + case EqFloat64: o << int8_t(BinaryConsts::F64Eq); break; + case NeFloat64: o << int8_t(BinaryConsts::F64Ne); break; + case LtFloat64: o << int8_t(BinaryConsts::F64Lt); break; + case LeFloat64: o << int8_t(BinaryConsts::F64Le); break; + case GtFloat64: o << int8_t(BinaryConsts::F64Gt); break; + case GeFloat64: o << int8_t(BinaryConsts::F64Ge); break; + default: abort(); + } +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitSelect(Select* curr) { + if (debug) std::cerr << "zz node: Select" << std::endl; + visitChild(curr->ifTrue); + visitChild(curr->ifFalse); + visitChild(curr->condition); + if (curr->type == unreachable) { + emitExtraUnreachable(); + return; + } + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::Select); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitReturn(Return* curr) { + if (debug) std::cerr << "zz node: Return" << std::endl; + if (curr->value) { + visitChild(curr->value); + } + if (justAddToStack(curr)) return; + + o << int8_t(BinaryConsts::Return); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitHost(Host* curr) { + if (debug) std::cerr << "zz node: Host" << std::endl; + switch (curr->op) { + case CurrentMemory: { + break; + } + case GrowMemory: { + visitChild(curr->operands[0]); + break; + } + default: WASM_UNREACHABLE(); + } + if (justAddToStack(curr)) return; + switch (curr->op) { + case CurrentMemory: { + o << int8_t(BinaryConsts::CurrentMemory); + break; + } + case GrowMemory: { + o << int8_t(BinaryConsts::GrowMemory); + break; + } + default: WASM_UNREACHABLE(); + } + o << U32LEB(0); // Reserved flags field +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitNop(Nop* curr) { + if (debug) std::cerr << "zz node: Nop" << std::endl; + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::Nop); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitUnreachable(Unreachable* curr) { + if (debug) std::cerr << "zz node: Unreachable" << std::endl; + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::Unreachable); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::visitDrop(Drop* curr) { + if (debug) std::cerr << "zz node: Drop" << std::endl; + visitChild(curr->value); + if (justAddToStack(curr)) return; + o << int8_t(BinaryConsts::Drop); +} + +template<StackWriterMode Mode, typename Parent> +int32_t StackWriter<Mode, Parent>::getBreakIndex(Name name) { // -1 if not found + for (int i = breakStack.size() - 1; i >= 0; i--) { + if (breakStack[i] == name) { + return breakStack.size() - 1 - i; + } + } + WASM_UNREACHABLE(); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset) { + o << U32LEB(Log2(alignment ? alignment : bytes)); + o << U32LEB(offset); +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::emitExtraUnreachable() { + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(Builder(allocator).makeUnreachable())); + } else if (Mode == StackWriterMode::Binaryen2Binary) { + o << int8_t(BinaryConsts::Unreachable); + } +} + +template<StackWriterMode Mode, typename Parent> +bool StackWriter<Mode, Parent>::justAddToStack(Expression* curr) { + if (Mode == StackWriterMode::Binaryen2Stack) { + stackIR.push_back(makeStackInst(curr)); + return true; + } + return false; +} + +template<StackWriterMode Mode, typename Parent> +void StackWriter<Mode, Parent>::finishFunctionBody() { + o << int8_t(BinaryConsts::End); +} + +template<StackWriterMode Mode, typename Parent> +StackInst* StackWriter<Mode, Parent>::makeStackInst(StackInst::Op op, Expression* origin) { + auto* ret = allocator.alloc<StackInst>(); + ret->op = op; + ret->origin = origin; + auto stackType = origin->type; + if (origin->is<Block>() || origin->is<Loop>() || origin->is<If>()) { + if (stackType == unreachable) { + // There are no unreachable blocks, loops, or ifs. we emit extra unreachables + // to fix that up, so that they are valid as having none type. + stackType = none; + } else if (op != StackInst::BlockEnd && + op != StackInst::IfEnd && + op != StackInst::LoopEnd) { + // If a concrete type is returned, we mark the end of the construct has + // having that type (as it is pushed to the value stack at that point), + // other parts are marked as none). + stackType = none; + } + } + ret->type = stackType; + return ret; +} + +} // namespace wasm + +#endif // wasm_stack_h + diff --git a/src/wasm.h b/src/wasm.h index 45881e519..49b0881b9 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -15,29 +15,10 @@ */ // -// wasm.h: WebAssembly representation and processing library, in one -// header file. +// wasm.h: Define Binaryen IR, a representation for WebAssembly, with +// all core parts in one simple header file. // -// This represents WebAssembly in an AST format, with a focus on making -// it easy to not just inspect but also to process. For example, some -// things that this enables are: -// -// * Interpreting: See wasm-interpreter.h. -// * Optimizing: See asm2wasm.h, which performs some optimizations -// after code generation. -// * Validation: See wasm-validator.h. -// * Pretty-printing: See Print.cpp. -// - -// -// wasm.js internal WebAssembly representation design: -// -// * Unify where possible. Where size isn't a concern, combine -// classes, so binary ops and relational ops are joined. This -// simplifies that AST and makes traversals easier. -// * Optimize for size? This might justify separating if and if_else -// (so that if doesn't have an always-empty else; also it avoids -// a branch). +// For more overview, see README.md // #ifndef wasm_wasm_h @@ -601,6 +582,13 @@ public: // Globals +// Forward declarations of Stack IR, as functions can contain it, see +// the stackIR property. +// Stack IR is a secondary IR to the main IR defined in this file (Binaryen +// IR). See wasm-stack.h. +class StackInst; +typedef std::vector<StackInst*> StackIR; + class Function { public: Name name; @@ -608,8 +596,20 @@ public: std::vector<Type> params; // function locals are std::vector<Type> vars; // params plus vars Name type; // if null, it is implicit in params and result + + // The body of the function Expression* body; + // If present, this stack IR was generated from the main Binaryen IR body, + // and possibly optimized. If it is present when writing to wasm binary, + // it will be emitted instead of the main Binaryen IR. + // + // Note that no special care is taken to synchronize the two IRs - if you + // emit stack IR and then optimize the main IR, you need to recompute the + // stack IR. The Pass system will throw away Stack IR if a pass is run + // that declares it may modify Binaryen IR. + std::unique_ptr<StackIR> stackIR; + // local names. these are optional. std::map<Index, Name> localNames; std::map<Name, Index> localIndices; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 6a5775151..935660d95 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -19,7 +19,7 @@ #include "support/bits.h" #include "wasm-binary.h" -#include "ir/branch-utils.h" +#include "wasm-stack.h" #include "ir/module-utils.h" namespace wasm { @@ -217,7 +217,7 @@ void WasmBinaryWriter::writeFunctionSignatures() { } void WasmBinaryWriter::writeExpression(Expression* curr) { - StackWriter(*this, o, debug).visit(curr); + ExpressionStackWriter<WasmBinaryWriter>(curr, *this, o, debug); } void WasmBinaryWriter::writeFunctions() { @@ -231,22 +231,16 @@ void WasmBinaryWriter::writeFunctions() { if (debug) std::cerr << "write one at" << o.size() << std::endl; size_t sizePos = writeU32LEBPlaceholder(); size_t start = o.size(); - Function* function = wasm->functions[i].get(); - if (debug) std::cerr << "writing" << function->name << std::endl; - StackWriter stackWriter(function, *this, o, sourceMap, debug); - o << U32LEB( - (stackWriter.numLocalsByType[i32] ? 1 : 0) + - (stackWriter.numLocalsByType[i64] ? 1 : 0) + - (stackWriter.numLocalsByType[f32] ? 1 : 0) + - (stackWriter.numLocalsByType[f64] ? 1 : 0) - ); - if (stackWriter.numLocalsByType[i32]) o << U32LEB(stackWriter.numLocalsByType[i32]) << binaryType(i32); - if (stackWriter.numLocalsByType[i64]) o << U32LEB(stackWriter.numLocalsByType[i64]) << binaryType(i64); - if (stackWriter.numLocalsByType[f32]) o << U32LEB(stackWriter.numLocalsByType[f32]) << binaryType(f32); - if (stackWriter.numLocalsByType[f64]) o << U32LEB(stackWriter.numLocalsByType[f64]) << binaryType(f64); - - stackWriter.visitPossibleBlockContents(function->body); - o << int8_t(BinaryConsts::End); + Function* func = wasm->functions[i].get(); + if (debug) std::cerr << "writing" << func->name << std::endl; + // Emit Stack IR if present, and if we can + if (func->stackIR && !sourceMap) { + if (debug) std::cerr << "write Stack IR" << std::endl; + StackIRFunctionStackWriter<WasmBinaryWriter>(func, *this, o, debug); + } else { + if (debug) std::cerr << "write Binaryen IR" << std::endl; + FunctionStackWriter<WasmBinaryWriter>(func, *this, o, sourceMap, debug); + } size_t size = o.size() - start; assert(size <= std::numeric_limits<uint32_t>::max()); if (debug) std::cerr << "body size: " << size << ", writing at " << sizePos << ", next starts at " << o.size() << std::endl; @@ -263,7 +257,7 @@ void WasmBinaryWriter::writeFunctions() { } } } - tableOfContents.functionBodies.emplace_back(function->name, sizePos + sizeFieldSize, size); + tableOfContents.functionBodies.emplace_back(func->name, sizePos + sizeFieldSize, size); } finishSection(start); } @@ -601,745 +595,6 @@ void WasmBinaryWriter::finishUp() { } } -// StackWriter - -void StackWriter::mapLocals() { - for (Index i = 0; i < func->getNumParams(); i++) { - size_t curr = mappedLocals.size(); - mappedLocals[i] = curr; - } - for (auto type : func->vars) { - numLocalsByType[type]++; - } - std::map<Type, size_t> currLocalsByType; - for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) { - size_t index = func->getVarIndexBase(); - Type type = func->getLocalType(i); - currLocalsByType[type]++; // increment now for simplicity, must decrement it in returns - if (type == i32) { - mappedLocals[i] = index + currLocalsByType[i32] - 1; - continue; - } - index += numLocalsByType[i32]; - if (type == i64) { - mappedLocals[i] = index + currLocalsByType[i64] - 1; - continue; - } - index += numLocalsByType[i64]; - if (type == f32) { - mappedLocals[i] = index + currLocalsByType[f32] - 1; - continue; - } - index += numLocalsByType[f32]; - if (type == f64) { - mappedLocals[i] = index + currLocalsByType[f64] - 1; - continue; - } - abort(); - } -} - -void StackWriter::visit(Expression* curr) { - if (sourceMap) { - parent.writeDebugLocation(curr, func); - } - Visitor<StackWriter>::visit(curr); -} - -static bool brokenTo(Block* block) { - return block->name.is() && BranchUtils::BranchSeeker::hasNamed(block, block->name); -} - -// emits a node, but if it is a block with no name, emit a list of its contents -void StackWriter::visitPossibleBlockContents(Expression* curr) { - auto* block = curr->dynCast<Block>(); - if (!block || brokenTo(block)) { - visit(curr); - return; - } - for (auto* child : block->list) { - visit(child); - } - if (block->type == unreachable && block->list.back()->type != unreachable) { - // similar to in visitBlock, here we could skip emitting the block itself, - // but must still end the 'block' (the contents, really) with an unreachable - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitBlock(Block *curr) { - if (debug) std::cerr << "zz node: Block" << std::endl; - o << int8_t(BinaryConsts::Block); - o << binaryType(curr->type != unreachable ? curr->type : none); - breakStack.push_back(curr->name); - Index i = 0; - for (auto* child : curr->list) { - if (debug) std::cerr << " " << size_t(curr) << "\n zz Block element " << i++ << std::endl; - visit(child); - } - breakStack.pop_back(); - if (curr->type == unreachable) { - // an unreachable block is one that cannot be exited. We cannot encode this directly - // in wasm, where blocks must be none,i32,i64,f32,f64. Since the block cannot be - // exited, we can emit an unreachable at the end, and that will always be valid, - // and then the block is ok as a none - o << int8_t(BinaryConsts::Unreachable); - } - o << int8_t(BinaryConsts::End); - if (curr->type == unreachable) { - // and emit an unreachable *outside* the block too, so later things can pop anything - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitIf(If *curr) { - if (debug) std::cerr << "zz node: If" << std::endl; - if (curr->condition->type == unreachable) { - // this if-else is unreachable because of the condition, i.e., the condition - // does not exit. So don't emit the if, but do consume the condition - visit(curr->condition); - o << int8_t(BinaryConsts::Unreachable); - return; - } - visit(curr->condition); - o << int8_t(BinaryConsts::If); - o << binaryType(curr->type != unreachable ? curr->type : none); - breakStack.push_back(IMPOSSIBLE_CONTINUE); // the binary format requires this; we have a block if we need one; TODO: optimize - visitPossibleBlockContents(curr->ifTrue); // TODO: emit block contents directly, if possible - breakStack.pop_back(); - if (curr->ifFalse) { - o << int8_t(BinaryConsts::Else); - breakStack.push_back(IMPOSSIBLE_CONTINUE); // TODO ditto - visitPossibleBlockContents(curr->ifFalse); - breakStack.pop_back(); - } - o << int8_t(BinaryConsts::End); - if (curr->type == unreachable) { - // we already handled the case of the condition being unreachable. otherwise, - // we may still be unreachable, if we are an if-else with both sides unreachable. - // wasm does not allow this to be emitted directly, so we must do something more. we could do - // better, but for now we emit an extra unreachable instruction after the if, so it is not consumed itself, - assert(curr->ifFalse); - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitLoop(Loop *curr) { - if (debug) std::cerr << "zz node: Loop" << std::endl; - o << int8_t(BinaryConsts::Loop); - o << binaryType(curr->type != unreachable ? curr->type : none); - breakStack.push_back(curr->name); - visitPossibleBlockContents(curr->body); - breakStack.pop_back(); - o << int8_t(BinaryConsts::End); - if (curr->type == unreachable) { - // we emitted a loop without a return type, so it must not be consumed - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitBreak(Break *curr) { - if (debug) std::cerr << "zz node: Break" << std::endl; - if (curr->value) { - visit(curr->value); - } - if (curr->condition) visit(curr->condition); - o << int8_t(curr->condition ? BinaryConsts::BrIf : BinaryConsts::Br) - << U32LEB(getBreakIndex(curr->name)); - if (curr->condition && curr->type == unreachable) { - // a br_if is normally none or emits a value. if it is unreachable, - // then either the condition or the value is unreachable, which is - // extremely rare, and may require us to make the stack polymorphic - // (if the block we branch to has a value, we may lack one as we - // are not a reachable branch; the wasm spec on the other hand does - // presume the br_if emits a value of the right type, even if it - // popped unreachable) - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitSwitch(Switch *curr) { - if (debug) std::cerr << "zz node: Switch" << std::endl; - if (curr->value) { - visit(curr->value); - } - visit(curr->condition); - if (!BranchUtils::isBranchReachable(curr)) { - // if the branch is not reachable, then it's dangerous to emit it, as - // wasm type checking rules are different, especially in unreachable - // code. so just don't emit that unreachable code. - o << int8_t(BinaryConsts::Unreachable); - return; - } - o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size()); - for (auto target : curr->targets) { - o << U32LEB(getBreakIndex(target)); - } - o << U32LEB(getBreakIndex(curr->default_)); -} - -void StackWriter::visitCall(Call *curr) { - if (debug) std::cerr << "zz node: Call" << std::endl; - for (auto* operand : curr->operands) { - visit(operand); - } - o << int8_t(BinaryConsts::CallFunction) << U32LEB(parent.getFunctionIndex(curr->target)); - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitCallImport(CallImport *curr) { - if (debug) std::cerr << "zz node: CallImport" << std::endl; - for (auto* operand : curr->operands) { - visit(operand); - } - o << int8_t(BinaryConsts::CallFunction) << U32LEB(parent.getFunctionIndex(curr->target)); -} - -void StackWriter::visitCallIndirect(CallIndirect *curr) { - if (debug) std::cerr << "zz node: CallIndirect" << std::endl; - - for (auto* operand : curr->operands) { - visit(operand); - } - visit(curr->target); - o << int8_t(BinaryConsts::CallIndirect) - << U32LEB(parent.getFunctionTypeIndex(curr->fullType)) - << U32LEB(0); // Reserved flags field - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitGetLocal(GetLocal *curr) { - if (debug) std::cerr << "zz node: GetLocal " << (o.size() + 1) << std::endl; - o << int8_t(BinaryConsts::GetLocal) << U32LEB(mappedLocals[curr->index]); -} - -void StackWriter::visitSetLocal(SetLocal *curr) { - if (debug) std::cerr << "zz node: Set|TeeLocal" << std::endl; - visit(curr->value); - o << int8_t(curr->isTee() ? BinaryConsts::TeeLocal : BinaryConsts::SetLocal) << U32LEB(mappedLocals[curr->index]); - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitGetGlobal(GetGlobal *curr) { - if (debug) std::cerr << "zz node: GetGlobal " << (o.size() + 1) << std::endl; - o << int8_t(BinaryConsts::GetGlobal) << U32LEB(parent.getGlobalIndex(curr->name)); -} - -void StackWriter::visitSetGlobal(SetGlobal *curr) { - if (debug) std::cerr << "zz node: SetGlobal" << std::endl; - visit(curr->value); - o << int8_t(BinaryConsts::SetGlobal) << U32LEB(parent.getGlobalIndex(curr->name)); -} - -void StackWriter::visitLoad(Load *curr) { - if (debug) std::cerr << "zz node: Load" << std::endl; - visit(curr->ptr); - if (!curr->isAtomic) { - switch (curr->type) { - case i32: { - switch (curr->bytes) { - case 1: o << int8_t(curr->signed_ ? BinaryConsts::I32LoadMem8S : BinaryConsts::I32LoadMem8U); break; - case 2: o << int8_t(curr->signed_ ? BinaryConsts::I32LoadMem16S : BinaryConsts::I32LoadMem16U); break; - case 4: o << int8_t(BinaryConsts::I32LoadMem); break; - default: abort(); - } - break; - } - case i64: { - switch (curr->bytes) { - case 1: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem8S : BinaryConsts::I64LoadMem8U); break; - case 2: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem16S : BinaryConsts::I64LoadMem16U); break; - case 4: o << int8_t(curr->signed_ ? BinaryConsts::I64LoadMem32S : BinaryConsts::I64LoadMem32U); break; - case 8: o << int8_t(BinaryConsts::I64LoadMem); break; - default: abort(); - } - break; - } - case f32: o << int8_t(BinaryConsts::F32LoadMem); break; - case f64: o << int8_t(BinaryConsts::F64LoadMem); break; - case unreachable: return; // the pointer is unreachable, so we are never reached; just don't emit a load - default: WASM_UNREACHABLE(); - } - } else { - if (curr->type == unreachable) { - // don't even emit it; we don't know the right type - o << int8_t(BinaryConsts::Unreachable); - return; - } - o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->type) { - case i32: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I32AtomicLoad8U); break; - case 2: o << int8_t(BinaryConsts::I32AtomicLoad16U); break; - case 4: o << int8_t(BinaryConsts::I32AtomicLoad); break; - default: WASM_UNREACHABLE(); - } - break; - } - case i64: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I64AtomicLoad8U); break; - case 2: o << int8_t(BinaryConsts::I64AtomicLoad16U); break; - case 4: o << int8_t(BinaryConsts::I64AtomicLoad32U); break; - case 8: o << int8_t(BinaryConsts::I64AtomicLoad); break; - default: WASM_UNREACHABLE(); - } - break; - } - case unreachable: return; - default: WASM_UNREACHABLE(); - } - } - emitMemoryAccess(curr->align, curr->bytes, curr->offset); -} - -void StackWriter::visitStore(Store *curr) { - if (debug) std::cerr << "zz node: Store" << std::endl; - visit(curr->ptr); - visit(curr->value); - if (!curr->isAtomic) { - switch (curr->valueType) { - case i32: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I32StoreMem8); break; - case 2: o << int8_t(BinaryConsts::I32StoreMem16); break; - case 4: o << int8_t(BinaryConsts::I32StoreMem); break; - default: abort(); - } - break; - } - case i64: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I64StoreMem8); break; - case 2: o << int8_t(BinaryConsts::I64StoreMem16); break; - case 4: o << int8_t(BinaryConsts::I64StoreMem32); break; - case 8: o << int8_t(BinaryConsts::I64StoreMem); break; - default: abort(); - } - break; - } - case f32: o << int8_t(BinaryConsts::F32StoreMem); break; - case f64: o << int8_t(BinaryConsts::F64StoreMem); break; - default: abort(); - } - } else { - if (curr->type == unreachable) { - // don't even emit it; we don't know the right type - o << int8_t(BinaryConsts::Unreachable); - return; - } - o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->valueType) { - case i32: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I32AtomicStore8); break; - case 2: o << int8_t(BinaryConsts::I32AtomicStore16); break; - case 4: o << int8_t(BinaryConsts::I32AtomicStore); break; - default: WASM_UNREACHABLE(); - } - break; - } - case i64: { - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I64AtomicStore8); break; - case 2: o << int8_t(BinaryConsts::I64AtomicStore16); break; - case 4: o << int8_t(BinaryConsts::I64AtomicStore32); break; - case 8: o << int8_t(BinaryConsts::I64AtomicStore); break; - default: WASM_UNREACHABLE(); - } - break; - } - default: WASM_UNREACHABLE(); - } - } - emitMemoryAccess(curr->align, curr->bytes, curr->offset); -} - -void StackWriter::visitAtomicRMW(AtomicRMW *curr) { - if (debug) std::cerr << "zz node: AtomicRMW" << std::endl; - visit(curr->ptr); - // stop if the rest isn't reachable anyhow - if (curr->ptr->type == unreachable) return; - visit(curr->value); - if (curr->value->type == unreachable) return; - - if (curr->type == unreachable) { - // don't even emit it; we don't know the right type - o << int8_t(BinaryConsts::Unreachable); - return; - } - - o << int8_t(BinaryConsts::AtomicPrefix); - -#define CASE_FOR_OP(Op) \ - case Op: \ - switch (curr->type) { \ - case i32: \ - switch (curr->bytes) { \ - case 1: o << int8_t(BinaryConsts::I32AtomicRMW##Op##8U); break; \ - case 2: o << int8_t(BinaryConsts::I32AtomicRMW##Op##16U); break; \ - case 4: o << int8_t(BinaryConsts::I32AtomicRMW##Op); break; \ - default: WASM_UNREACHABLE(); \ - } \ - break; \ - case i64: \ - switch (curr->bytes) { \ - case 1: o << int8_t(BinaryConsts::I64AtomicRMW##Op##8U); break; \ - case 2: o << int8_t(BinaryConsts::I64AtomicRMW##Op##16U); break; \ - case 4: o << int8_t(BinaryConsts::I64AtomicRMW##Op##32U); break; \ - case 8: o << int8_t(BinaryConsts::I64AtomicRMW##Op); break; \ - default: WASM_UNREACHABLE(); \ - } \ - break; \ - default: WASM_UNREACHABLE(); \ - } \ - break - - switch(curr->op) { - CASE_FOR_OP(Add); - CASE_FOR_OP(Sub); - CASE_FOR_OP(And); - CASE_FOR_OP(Or); - CASE_FOR_OP(Xor); - CASE_FOR_OP(Xchg); - default: WASM_UNREACHABLE(); - } -#undef CASE_FOR_OP - - emitMemoryAccess(curr->bytes, curr->bytes, curr->offset); -} - -void StackWriter::visitAtomicCmpxchg(AtomicCmpxchg *curr) { - if (debug) std::cerr << "zz node: AtomicCmpxchg" << std::endl; - visit(curr->ptr); - // stop if the rest isn't reachable anyhow - if (curr->ptr->type == unreachable) return; - visit(curr->expected); - if (curr->expected->type == unreachable) return; - visit(curr->replacement); - if (curr->replacement->type == unreachable) return; - - if (curr->type == unreachable) { - // don't even emit it; we don't know the right type - o << int8_t(BinaryConsts::Unreachable); - return; - } - - o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->type) { - case i32: - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I32AtomicCmpxchg8U); break; - case 2: o << int8_t(BinaryConsts::I32AtomicCmpxchg16U); break; - case 4: o << int8_t(BinaryConsts::I32AtomicCmpxchg); break; - default: WASM_UNREACHABLE(); - } - break; - case i64: - switch (curr->bytes) { - case 1: o << int8_t(BinaryConsts::I64AtomicCmpxchg8U); break; - case 2: o << int8_t(BinaryConsts::I64AtomicCmpxchg16U); break; - case 4: o << int8_t(BinaryConsts::I64AtomicCmpxchg32U); break; - case 8: o << int8_t(BinaryConsts::I64AtomicCmpxchg); break; - default: WASM_UNREACHABLE(); - } - break; - default: WASM_UNREACHABLE(); - } - emitMemoryAccess(curr->bytes, curr->bytes, curr->offset); -} - -void StackWriter::visitAtomicWait(AtomicWait *curr) { - if (debug) std::cerr << "zz node: AtomicWait" << std::endl; - visit(curr->ptr); - // stop if the rest isn't reachable anyhow - if (curr->ptr->type == unreachable) return; - visit(curr->expected); - if (curr->expected->type == unreachable) return; - visit(curr->timeout); - if (curr->timeout->type == unreachable) return; - - o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->expectedType) { - case i32: { - o << int8_t(BinaryConsts::I32AtomicWait); - emitMemoryAccess(4, 4, 0); - break; - } - case i64: { - o << int8_t(BinaryConsts::I64AtomicWait); - emitMemoryAccess(8, 8, 0); - break; - } - default: WASM_UNREACHABLE(); - } -} - -void StackWriter::visitAtomicWake(AtomicWake *curr) { - if (debug) std::cerr << "zz node: AtomicWake" << std::endl; - visit(curr->ptr); - // stop if the rest isn't reachable anyhow - if (curr->ptr->type == unreachable) return; - visit(curr->wakeCount); - if (curr->wakeCount->type == unreachable) return; - - o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicWake); - emitMemoryAccess(4, 4, 0); -} - -void StackWriter::visitConst(Const *curr) { - if (debug) std::cerr << "zz node: Const" << curr << " : " << curr->type << std::endl; - switch (curr->type) { - case i32: { - o << int8_t(BinaryConsts::I32Const) << S32LEB(curr->value.geti32()); - break; - } - case i64: { - o << int8_t(BinaryConsts::I64Const) << S64LEB(curr->value.geti64()); - break; - } - case f32: { - o << int8_t(BinaryConsts::F32Const) << curr->value.reinterpreti32(); - break; - } - case f64: { - o << int8_t(BinaryConsts::F64Const) << curr->value.reinterpreti64(); - break; - } - default: abort(); - } - if (debug) std::cerr << "zz const node done.\n"; -} - -void StackWriter::visitUnary(Unary *curr) { - if (debug) std::cerr << "zz node: Unary" << std::endl; - visit(curr->value); - switch (curr->op) { - case ClzInt32: o << int8_t(BinaryConsts::I32Clz); break; - case CtzInt32: o << int8_t(BinaryConsts::I32Ctz); break; - case PopcntInt32: o << int8_t(BinaryConsts::I32Popcnt); break; - case EqZInt32: o << int8_t(BinaryConsts::I32EqZ); break; - case ClzInt64: o << int8_t(BinaryConsts::I64Clz); break; - case CtzInt64: o << int8_t(BinaryConsts::I64Ctz); break; - case PopcntInt64: o << int8_t(BinaryConsts::I64Popcnt); break; - case EqZInt64: o << int8_t(BinaryConsts::I64EqZ); break; - case NegFloat32: o << int8_t(BinaryConsts::F32Neg); break; - case AbsFloat32: o << int8_t(BinaryConsts::F32Abs); break; - case CeilFloat32: o << int8_t(BinaryConsts::F32Ceil); break; - case FloorFloat32: o << int8_t(BinaryConsts::F32Floor); break; - case TruncFloat32: o << int8_t(BinaryConsts::F32Trunc); break; - case NearestFloat32: o << int8_t(BinaryConsts::F32NearestInt); break; - case SqrtFloat32: o << int8_t(BinaryConsts::F32Sqrt); break; - case NegFloat64: o << int8_t(BinaryConsts::F64Neg); break; - case AbsFloat64: o << int8_t(BinaryConsts::F64Abs); break; - case CeilFloat64: o << int8_t(BinaryConsts::F64Ceil); break; - case FloorFloat64: o << int8_t(BinaryConsts::F64Floor); break; - case TruncFloat64: o << int8_t(BinaryConsts::F64Trunc); break; - case NearestFloat64: o << int8_t(BinaryConsts::F64NearestInt); break; - case SqrtFloat64: o << int8_t(BinaryConsts::F64Sqrt); break; - case ExtendSInt32: o << int8_t(BinaryConsts::I64STruncI32); break; - case ExtendUInt32: o << int8_t(BinaryConsts::I64UTruncI32); break; - case WrapInt64: o << int8_t(BinaryConsts::I32ConvertI64); break; - case TruncUFloat32ToInt32: o << int8_t(BinaryConsts::I32UTruncF32); break; - case TruncUFloat32ToInt64: o << int8_t(BinaryConsts::I64UTruncF32); break; - case TruncSFloat32ToInt32: o << int8_t(BinaryConsts::I32STruncF32); break; - case TruncSFloat32ToInt64: o << int8_t(BinaryConsts::I64STruncF32); break; - case TruncUFloat64ToInt32: o << int8_t(BinaryConsts::I32UTruncF64); break; - case TruncUFloat64ToInt64: o << int8_t(BinaryConsts::I64UTruncF64); break; - case TruncSFloat64ToInt32: o << int8_t(BinaryConsts::I32STruncF64); break; - case TruncSFloat64ToInt64: o << int8_t(BinaryConsts::I64STruncF64); break; - case ConvertUInt32ToFloat32: o << int8_t(BinaryConsts::F32UConvertI32); break; - case ConvertUInt32ToFloat64: o << int8_t(BinaryConsts::F64UConvertI32); break; - case ConvertSInt32ToFloat32: o << int8_t(BinaryConsts::F32SConvertI32); break; - case ConvertSInt32ToFloat64: o << int8_t(BinaryConsts::F64SConvertI32); break; - case ConvertUInt64ToFloat32: o << int8_t(BinaryConsts::F32UConvertI64); break; - case ConvertUInt64ToFloat64: o << int8_t(BinaryConsts::F64UConvertI64); break; - case ConvertSInt64ToFloat32: o << int8_t(BinaryConsts::F32SConvertI64); break; - case ConvertSInt64ToFloat64: o << int8_t(BinaryConsts::F64SConvertI64); break; - case DemoteFloat64: o << int8_t(BinaryConsts::F32ConvertF64); break; - case PromoteFloat32: o << int8_t(BinaryConsts::F64ConvertF32); break; - case ReinterpretFloat32: o << int8_t(BinaryConsts::I32ReinterpretF32); break; - case ReinterpretFloat64: o << int8_t(BinaryConsts::I64ReinterpretF64); break; - case ReinterpretInt32: o << int8_t(BinaryConsts::F32ReinterpretI32); break; - case ReinterpretInt64: o << int8_t(BinaryConsts::F64ReinterpretI64); break; - case ExtendS8Int32: o << int8_t(BinaryConsts::I32ExtendS8); break; - case ExtendS16Int32: o << int8_t(BinaryConsts::I32ExtendS16); break; - case ExtendS8Int64: o << int8_t(BinaryConsts::I64ExtendS8); break; - case ExtendS16Int64: o << int8_t(BinaryConsts::I64ExtendS16); break; - case ExtendS32Int64: o << int8_t(BinaryConsts::I64ExtendS32); break; - default: abort(); - } - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitBinary(Binary *curr) { - if (debug) std::cerr << "zz node: Binary" << std::endl; - visit(curr->left); - visit(curr->right); - - switch (curr->op) { - case AddInt32: o << int8_t(BinaryConsts::I32Add); break; - case SubInt32: o << int8_t(BinaryConsts::I32Sub); break; - case MulInt32: o << int8_t(BinaryConsts::I32Mul); break; - case DivSInt32: o << int8_t(BinaryConsts::I32DivS); break; - case DivUInt32: o << int8_t(BinaryConsts::I32DivU); break; - case RemSInt32: o << int8_t(BinaryConsts::I32RemS); break; - case RemUInt32: o << int8_t(BinaryConsts::I32RemU); break; - case AndInt32: o << int8_t(BinaryConsts::I32And); break; - case OrInt32: o << int8_t(BinaryConsts::I32Or); break; - case XorInt32: o << int8_t(BinaryConsts::I32Xor); break; - case ShlInt32: o << int8_t(BinaryConsts::I32Shl); break; - case ShrUInt32: o << int8_t(BinaryConsts::I32ShrU); break; - case ShrSInt32: o << int8_t(BinaryConsts::I32ShrS); break; - case RotLInt32: o << int8_t(BinaryConsts::I32RotL); break; - case RotRInt32: o << int8_t(BinaryConsts::I32RotR); break; - case EqInt32: o << int8_t(BinaryConsts::I32Eq); break; - case NeInt32: o << int8_t(BinaryConsts::I32Ne); break; - case LtSInt32: o << int8_t(BinaryConsts::I32LtS); break; - case LtUInt32: o << int8_t(BinaryConsts::I32LtU); break; - case LeSInt32: o << int8_t(BinaryConsts::I32LeS); break; - case LeUInt32: o << int8_t(BinaryConsts::I32LeU); break; - case GtSInt32: o << int8_t(BinaryConsts::I32GtS); break; - case GtUInt32: o << int8_t(BinaryConsts::I32GtU); break; - case GeSInt32: o << int8_t(BinaryConsts::I32GeS); break; - case GeUInt32: o << int8_t(BinaryConsts::I32GeU); break; - - case AddInt64: o << int8_t(BinaryConsts::I64Add); break; - case SubInt64: o << int8_t(BinaryConsts::I64Sub); break; - case MulInt64: o << int8_t(BinaryConsts::I64Mul); break; - case DivSInt64: o << int8_t(BinaryConsts::I64DivS); break; - case DivUInt64: o << int8_t(BinaryConsts::I64DivU); break; - case RemSInt64: o << int8_t(BinaryConsts::I64RemS); break; - case RemUInt64: o << int8_t(BinaryConsts::I64RemU); break; - case AndInt64: o << int8_t(BinaryConsts::I64And); break; - case OrInt64: o << int8_t(BinaryConsts::I64Or); break; - case XorInt64: o << int8_t(BinaryConsts::I64Xor); break; - case ShlInt64: o << int8_t(BinaryConsts::I64Shl); break; - case ShrUInt64: o << int8_t(BinaryConsts::I64ShrU); break; - case ShrSInt64: o << int8_t(BinaryConsts::I64ShrS); break; - case RotLInt64: o << int8_t(BinaryConsts::I64RotL); break; - case RotRInt64: o << int8_t(BinaryConsts::I64RotR); break; - case EqInt64: o << int8_t(BinaryConsts::I64Eq); break; - case NeInt64: o << int8_t(BinaryConsts::I64Ne); break; - case LtSInt64: o << int8_t(BinaryConsts::I64LtS); break; - case LtUInt64: o << int8_t(BinaryConsts::I64LtU); break; - case LeSInt64: o << int8_t(BinaryConsts::I64LeS); break; - case LeUInt64: o << int8_t(BinaryConsts::I64LeU); break; - case GtSInt64: o << int8_t(BinaryConsts::I64GtS); break; - case GtUInt64: o << int8_t(BinaryConsts::I64GtU); break; - case GeSInt64: o << int8_t(BinaryConsts::I64GeS); break; - case GeUInt64: o << int8_t(BinaryConsts::I64GeU); break; - - case AddFloat32: o << int8_t(BinaryConsts::F32Add); break; - case SubFloat32: o << int8_t(BinaryConsts::F32Sub); break; - case MulFloat32: o << int8_t(BinaryConsts::F32Mul); break; - case DivFloat32: o << int8_t(BinaryConsts::F32Div); break; - case CopySignFloat32: o << int8_t(BinaryConsts::F32CopySign);break; - case MinFloat32: o << int8_t(BinaryConsts::F32Min); break; - case MaxFloat32: o << int8_t(BinaryConsts::F32Max); break; - case EqFloat32: o << int8_t(BinaryConsts::F32Eq); break; - case NeFloat32: o << int8_t(BinaryConsts::F32Ne); break; - case LtFloat32: o << int8_t(BinaryConsts::F32Lt); break; - case LeFloat32: o << int8_t(BinaryConsts::F32Le); break; - case GtFloat32: o << int8_t(BinaryConsts::F32Gt); break; - case GeFloat32: o << int8_t(BinaryConsts::F32Ge); break; - - case AddFloat64: o << int8_t(BinaryConsts::F64Add); break; - case SubFloat64: o << int8_t(BinaryConsts::F64Sub); break; - case MulFloat64: o << int8_t(BinaryConsts::F64Mul); break; - case DivFloat64: o << int8_t(BinaryConsts::F64Div); break; - case CopySignFloat64: o << int8_t(BinaryConsts::F64CopySign);break; - case MinFloat64: o << int8_t(BinaryConsts::F64Min); break; - case MaxFloat64: o << int8_t(BinaryConsts::F64Max); break; - case EqFloat64: o << int8_t(BinaryConsts::F64Eq); break; - case NeFloat64: o << int8_t(BinaryConsts::F64Ne); break; - case LtFloat64: o << int8_t(BinaryConsts::F64Lt); break; - case LeFloat64: o << int8_t(BinaryConsts::F64Le); break; - case GtFloat64: o << int8_t(BinaryConsts::F64Gt); break; - case GeFloat64: o << int8_t(BinaryConsts::F64Ge); break; - default: abort(); - } - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitSelect(Select *curr) { - if (debug) std::cerr << "zz node: Select" << std::endl; - visit(curr->ifTrue); - visit(curr->ifFalse); - visit(curr->condition); - o << int8_t(BinaryConsts::Select); - if (curr->type == unreachable) { - o << int8_t(BinaryConsts::Unreachable); - } -} - -void StackWriter::visitReturn(Return *curr) { - if (debug) std::cerr << "zz node: Return" << std::endl; - if (curr->value) { - visit(curr->value); - } - o << int8_t(BinaryConsts::Return); -} - -void StackWriter::visitHost(Host *curr) { - if (debug) std::cerr << "zz node: Host" << std::endl; - switch (curr->op) { - case CurrentMemory: { - o << int8_t(BinaryConsts::CurrentMemory); - break; - } - case GrowMemory: { - visit(curr->operands[0]); - o << int8_t(BinaryConsts::GrowMemory); - break; - } - default: abort(); - } - o << U32LEB(0); // Reserved flags field -} - -void StackWriter::visitNop(Nop *curr) { - if (debug) std::cerr << "zz node: Nop" << std::endl; - o << int8_t(BinaryConsts::Nop); -} - -void StackWriter::visitUnreachable(Unreachable *curr) { - if (debug) std::cerr << "zz node: Unreachable" << std::endl; - o << int8_t(BinaryConsts::Unreachable); -} - -void StackWriter::visitDrop(Drop *curr) { - if (debug) std::cerr << "zz node: Drop" << std::endl; - visit(curr->value); - o << int8_t(BinaryConsts::Drop); -} - -int32_t StackWriter::getBreakIndex(Name name) { // -1 if not found - for (int i = breakStack.size() - 1; i >= 0; i--) { - if (breakStack[i] == name) { - return breakStack.size() - 1 - i; - } - } - std::cerr << "bad break: " << name << " in " << func->name << std::endl; - abort(); -} - -void StackWriter::emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset) { - o << U32LEB(Log2(alignment ? alignment : bytes)); - o << U32LEB(offset); -} - // reader void WasmBinaryBuilder::read() { @@ -2408,7 +1663,7 @@ void WasmBinaryBuilder::pushBlockElements(Block* curr, size_t start, size_t end) } } -void WasmBinaryBuilder::visitBlock(Block *curr) { +void WasmBinaryBuilder::visitBlock(Block* curr) { if (debug) std::cerr << "zz node: Block" << std::endl; // special-case Block and de-recurse nested blocks in their first position, as that is // a common pattern that can be very highly nested. @@ -2475,7 +1730,7 @@ Expression* WasmBinaryBuilder::getBlockOrSingleton(Type type) { return block; } -void WasmBinaryBuilder::visitIf(If *curr) { +void WasmBinaryBuilder::visitIf(If* curr) { if (debug) std::cerr << "zz node: If" << std::endl; curr->type = getType(); curr->condition = popNonVoidExpression(); @@ -2489,7 +1744,7 @@ void WasmBinaryBuilder::visitIf(If *curr) { } } -void WasmBinaryBuilder::visitLoop(Loop *curr) { +void WasmBinaryBuilder::visitLoop(Loop* curr) { if (debug) std::cerr << "zz node: Loop" << std::endl; curr->type = getType(); curr->name = getNextLabel(); @@ -2546,7 +1801,7 @@ void WasmBinaryBuilder::visitBreak(Break *curr, uint8_t code) { curr->finalize(); } -void WasmBinaryBuilder::visitSwitch(Switch *curr) { +void WasmBinaryBuilder::visitSwitch(Switch* curr) { if (debug) std::cerr << "zz node: Switch" << std::endl; curr->condition = popNonVoidExpression(); auto numTargets = getU32LEB(); @@ -2592,7 +1847,7 @@ Expression* WasmBinaryBuilder::visitCall() { return ret; } -void WasmBinaryBuilder::visitCallIndirect(CallIndirect *curr) { +void WasmBinaryBuilder::visitCallIndirect(CallIndirect* curr) { if (debug) std::cerr << "zz node: CallIndirect" << std::endl; auto index = getU32LEB(); if (index >= wasm.functionTypes.size()) { @@ -2612,7 +1867,7 @@ void WasmBinaryBuilder::visitCallIndirect(CallIndirect *curr) { curr->finalize(); } -void WasmBinaryBuilder::visitGetLocal(GetLocal *curr) { +void WasmBinaryBuilder::visitGetLocal(GetLocal* curr) { if (debug) std::cerr << "zz node: GetLocal " << pos << std::endl; requireFunctionContext("get_local"); curr->index = getU32LEB(); @@ -2636,7 +1891,7 @@ void WasmBinaryBuilder::visitSetLocal(SetLocal *curr, uint8_t code) { curr->finalize(); } -void WasmBinaryBuilder::visitGetGlobal(GetGlobal *curr) { +void WasmBinaryBuilder::visitGetGlobal(GetGlobal* curr) { if (debug) std::cerr << "zz node: GetGlobal " << pos << std::endl; auto index = getU32LEB(); curr->name = getGlobalName(index); @@ -2653,7 +1908,7 @@ void WasmBinaryBuilder::visitGetGlobal(GetGlobal *curr) { throwError("bad get_global"); } -void WasmBinaryBuilder::visitSetGlobal(SetGlobal *curr) { +void WasmBinaryBuilder::visitSetGlobal(SetGlobal* curr) { if (debug) std::cerr << "zz node: SetGlobal" << std::endl; auto index = getU32LEB(); curr->name = getGlobalName(index); @@ -3012,7 +2267,7 @@ bool WasmBinaryBuilder::maybeVisitBinary(Expression*& out, uint8_t code) { #undef FLOAT_TYPED_CODE } -void WasmBinaryBuilder::visitSelect(Select *curr) { +void WasmBinaryBuilder::visitSelect(Select* curr) { if (debug) std::cerr << "zz node: Select" << std::endl; curr->condition = popNonVoidExpression(); curr->ifFalse = popNonVoidExpression(); @@ -3020,7 +2275,7 @@ void WasmBinaryBuilder::visitSelect(Select *curr) { curr->finalize(); } -void WasmBinaryBuilder::visitReturn(Return *curr) { +void WasmBinaryBuilder::visitReturn(Return* curr) { if (debug) std::cerr << "zz node: Return" << std::endl; requireFunctionContext("return"); if (currFunction->result != none) { @@ -3055,15 +2310,15 @@ bool WasmBinaryBuilder::maybeVisitHost(Expression*& out, uint8_t code) { return true; } -void WasmBinaryBuilder::visitNop(Nop *curr) { +void WasmBinaryBuilder::visitNop(Nop* curr) { if (debug) std::cerr << "zz node: Nop" << std::endl; } -void WasmBinaryBuilder::visitUnreachable(Unreachable *curr) { +void WasmBinaryBuilder::visitUnreachable(Unreachable* curr) { if (debug) std::cerr << "zz node: Unreachable" << std::endl; } -void WasmBinaryBuilder::visitDrop(Drop *curr) { +void WasmBinaryBuilder::visitDrop(Drop* curr) { if (debug) std::cerr << "zz node: Drop" << std::endl; curr->value = popNonVoidExpression(); curr->finalize(); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 9b5384efe..4a6ed19be 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -171,6 +171,8 @@ struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> { Pass* create() override { return new FunctionValidator(&info); } + bool modifiesBinaryenIR() override { return false; } + ValidationInfo& info; FunctionValidator(ValidationInfo* info) : info(*info) {} diff --git a/test/bad_params.fromasm b/test/bad_params.fromasm index 52f804340..1862f5ffe 100644 --- a/test/bad_params.fromasm +++ b/test/bad_params.fromasm @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "bad_params.asm.js") (export "ex" (func $ex)) - (func $ex (; 0 ;) + (func $ex (; 0 ;) (; has Stack IR ;) (nop) ) ) diff --git a/test/bad_params.fromasm.clamp b/test/bad_params.fromasm.clamp index 52f804340..1862f5ffe 100644 --- a/test/bad_params.fromasm.clamp +++ b/test/bad_params.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "bad_params.asm.js") (export "ex" (func $ex)) - (func $ex (; 0 ;) + (func $ex (; 0 ;) (; has Stack IR ;) (nop) ) ) diff --git a/test/bad_params.fromasm.imprecise b/test/bad_params.fromasm.imprecise index ae5256c57..d174d5614 100644 --- a/test/bad_params.fromasm.imprecise +++ b/test/bad_params.fromasm.imprecise @@ -1,6 +1,6 @@ (module (export "ex" (func $ex)) - (func $ex (; 0 ;) + (func $ex (; 0 ;) (; has Stack IR ;) (nop) ) ) diff --git a/test/binaryen.js/hello-world.js.txt b/test/binaryen.js/hello-world.js.txt index c3cfae20b..dcdb21e80 100644 --- a/test/binaryen.js/hello-world.js.txt +++ b/test/binaryen.js/hello-world.js.txt @@ -16,7 +16,7 @@ optimized: (module (type $iii (func (param i32 i32) (result i32))) (export "adder" (func $adder)) - (func $adder (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $adder (; 0 ;) (; has Stack IR ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) (i32.add (get_local $0) (get_local $1) diff --git a/test/binaryen.js/optimize-levels.js.txt b/test/binaryen.js/optimize-levels.js.txt index 78190fc0d..8cb0dfea5 100644 --- a/test/binaryen.js/optimize-levels.js.txt +++ b/test/binaryen.js/optimize-levels.js.txt @@ -36,7 +36,7 @@ shrinkLevel=1 (module (type $i (func (param i32) (result i32))) (export "test" (func $test)) - (func $test (; 0 ;) (type $i) (param $0 i32) (result i32) + (func $test (; 0 ;) (; has Stack IR ;) (type $i) (param $0 i32) (result i32) (select (get_local $0) (i32.const 0) @@ -66,7 +66,7 @@ shrinkLevel=1 (module (type $i (func (param i32) (result i32))) (export "test" (func $test)) - (func $test (; 0 ;) (type $i) (param $0 i32) (result i32) + (func $test (; 0 ;) (; has Stack IR ;) (type $i) (param $0 i32) (result i32) (select (get_local $0) (i32.const 0) diff --git a/test/binaryen.js/sieve.js b/test/binaryen.js/sieve.js index a7f0c993b..4c1e5eefc 100644 --- a/test/binaryen.js/sieve.js +++ b/test/binaryen.js/sieve.js @@ -19,16 +19,18 @@ var body = module.block( ), module.get_local(0, Binaryen.i32) ), - module.grow_memory( - module.i32.sub( - module.i32.div_u( - module.i32.add( - module.get_local(0, Binaryen.i32), - module.i32.const(65535) + module.drop( + module.grow_memory( + module.i32.sub( + module.i32.div_u( + module.i32.add( + module.get_local(0, Binaryen.i32), + module.i32.const(65535) + ), + module.i32.const(65536) ), - module.i32.const(65536) - ), - module.current_memory() + module.current_memory() + ) ) ) ), @@ -44,8 +46,8 @@ var body = module.block( module.i32.const(1) )), module.br_if('clear', module.i32.eq( - module.get_local(1), - module.get_local(0) + module.get_local(1, Binaryen.i32), + module.get_local(0, Binaryen.i32) )) ])), // perform the sieve TODO @@ -63,6 +65,8 @@ module.addFunction('sieve', ii, [Binaryen.i32], body); // export it as the same name as it has internally) module.addFunctionExport('sieve', 'sieve'); +if (!module.validate()) throw 'did not validate :('; + // Print out the text console.log(module.emitText()); diff --git a/test/binaryen.js/sieve.js.txt b/test/binaryen.js/sieve.js.txt index 2c4b906dd..97816e6b3 100644 --- a/test/binaryen.js/sieve.js.txt +++ b/test/binaryen.js/sieve.js.txt @@ -12,16 +12,18 @@ ) (get_local $0) ) - (grow_memory - (i32.sub - (i32.div_u - (i32.add - (get_local $0) - (i32.const 65535) + (drop + (grow_memory + (i32.sub + (i32.div_u + (i32.add + (get_local $0) + (i32.const 65535) + ) + (i32.const 65536) ) - (i32.const 65536) + (current_memory) ) - (current_memory) ) ) ) @@ -58,7 +60,7 @@ optimized: (type $i (func (param i32) (result i32))) (memory $0 1 100) (export "sieve" (func $sieve)) - (func $sieve (; 0 ;) (type $i) (param $0 i32) (result i32) + (func $sieve (; 0 ;) (; has Stack IR ;) (type $i) (param $0 i32) (result i32) (local $1 i32) (if (i32.lt_u @@ -68,16 +70,18 @@ optimized: ) (get_local $0) ) - (grow_memory - (i32.sub - (i32.div_u - (i32.add - (get_local $0) - (i32.const 65535) + (drop + (grow_memory + (i32.sub + (i32.div_u + (i32.add + (get_local $0) + (i32.const 65535) + ) + (i32.const 65536) ) - (i32.const 65536) + (current_memory) ) - (current_memory) ) ) ) diff --git a/test/debugInfo.fromasm b/test/debugInfo.fromasm index 0f104af84..5bedd5bdf 100644 --- a/test/debugInfo.fromasm +++ b/test/debugInfo.fromasm @@ -8,14 +8,14 @@ (export "fib" (func $fib)) (export "switch_reach" (func $switch_reach)) (export "nofile" (func $nofile)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ tests/other_file.cpp:314159:0 (i32.add (get_local $1) (get_local $1) ) ) - (func $ret (; 1 ;) (param $0 i32) (result i32) + (func $ret (; 1 ;) (; has Stack IR ;) (param $0 i32) (result i32) ;;@ return.cpp:50:0 (set_local $0 (i32.shl @@ -29,7 +29,7 @@ (i32.const 1) ) ) - (func $i32s-rem (; 2 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32s-rem (; 2 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.rem_s @@ -39,7 +39,7 @@ (i32.const 0) ) ) - (func $opts (; 3 ;) (param $0 i32) (param $1 i32) (result i32) + (func $opts (; 3 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ even-opted.cpp:1:0 (set_local $0 (i32.add @@ -63,7 +63,7 @@ (get_local $1) ) ) - (func $fib (; 4 ;) (param $0 i32) (result i32) + (func $fib (; 4 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -126,7 +126,7 @@ ;;@ fib.c:8:0 (get_local $1) ) - (func $switch_reach (; 5 ;) (param $0 i32) (result i32) + (func $switch_reach (; 5 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (block $__rjto$0 (result i32) @@ -180,7 +180,7 @@ ;;@ /tmp/emscripten_test_binaryen2_28hnAe/src.c:59950:0 (get_local $1) ) - (func $nofile (; 6 ;) + (func $nofile (; 6 ;) (; has Stack IR ;) ;;@ (unknown):1337:0 (call $nofile) ) diff --git a/test/debugInfo.fromasm.clamp b/test/debugInfo.fromasm.clamp index 0f104af84..5bedd5bdf 100644 --- a/test/debugInfo.fromasm.clamp +++ b/test/debugInfo.fromasm.clamp @@ -8,14 +8,14 @@ (export "fib" (func $fib)) (export "switch_reach" (func $switch_reach)) (export "nofile" (func $nofile)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ tests/other_file.cpp:314159:0 (i32.add (get_local $1) (get_local $1) ) ) - (func $ret (; 1 ;) (param $0 i32) (result i32) + (func $ret (; 1 ;) (; has Stack IR ;) (param $0 i32) (result i32) ;;@ return.cpp:50:0 (set_local $0 (i32.shl @@ -29,7 +29,7 @@ (i32.const 1) ) ) - (func $i32s-rem (; 2 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32s-rem (; 2 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.rem_s @@ -39,7 +39,7 @@ (i32.const 0) ) ) - (func $opts (; 3 ;) (param $0 i32) (param $1 i32) (result i32) + (func $opts (; 3 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ even-opted.cpp:1:0 (set_local $0 (i32.add @@ -63,7 +63,7 @@ (get_local $1) ) ) - (func $fib (; 4 ;) (param $0 i32) (result i32) + (func $fib (; 4 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -126,7 +126,7 @@ ;;@ fib.c:8:0 (get_local $1) ) - (func $switch_reach (; 5 ;) (param $0 i32) (result i32) + (func $switch_reach (; 5 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (block $__rjto$0 (result i32) @@ -180,7 +180,7 @@ ;;@ /tmp/emscripten_test_binaryen2_28hnAe/src.c:59950:0 (get_local $1) ) - (func $nofile (; 6 ;) + (func $nofile (; 6 ;) (; has Stack IR ;) ;;@ (unknown):1337:0 (call $nofile) ) diff --git a/test/debugInfo.fromasm.imprecise b/test/debugInfo.fromasm.imprecise index 9cad26249..a52606e16 100644 --- a/test/debugInfo.fromasm.imprecise +++ b/test/debugInfo.fromasm.imprecise @@ -5,14 +5,14 @@ (export "fib" (func $fib)) (export "switch_reach" (func $switch_reach)) (export "nofile" (func $nofile)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ tests/other_file.cpp:314159:0 (i32.add (get_local $1) (get_local $1) ) ) - (func $ret (; 1 ;) (param $0 i32) (result i32) + (func $ret (; 1 ;) (; has Stack IR ;) (param $0 i32) (result i32) ;;@ return.cpp:50:0 (set_local $0 (i32.shl @@ -26,7 +26,7 @@ (i32.const 1) ) ) - (func $opts (; 2 ;) (param $0 i32) (param $1 i32) (result i32) + (func $opts (; 2 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;;@ even-opted.cpp:1:0 (set_local $0 (i32.add @@ -50,7 +50,7 @@ (get_local $1) ) ) - (func $fib (; 3 ;) (param $0 i32) (result i32) + (func $fib (; 3 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -113,7 +113,7 @@ ;;@ fib.c:8:0 (get_local $1) ) - (func $switch_reach (; 4 ;) (param $0 i32) (result i32) + (func $switch_reach (; 4 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (block $__rjto$0 (result i32) @@ -167,7 +167,7 @@ ;;@ /tmp/emscripten_test_binaryen2_28hnAe/src.c:59950:0 (get_local $1) ) - (func $nofile (; 5 ;) + (func $nofile (; 5 ;) (; has Stack IR ;) ;;@ (unknown):1337:0 (call $nofile) ) diff --git a/test/dynamicLibrary.fromasm b/test/dynamicLibrary.fromasm index 295451b4c..edd7a60d0 100644 --- a/test/dynamicLibrary.fromasm +++ b/test/dynamicLibrary.fromasm @@ -13,7 +13,7 @@ (export "__post_instantiate" (func $__post_instantiate)) (export "runPostSets" (func $runPostSets)) (export "_global" (global $_global)) - (func $__ZN3FooC2Ev (; 2 ;) (param $0 i32) + (func $__ZN3FooC2Ev (; 2 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -42,10 +42,10 @@ (get_local $1) ) ) - (func $runPostSets (; 3 ;) + (func $runPostSets (; 3 ;) (; has Stack IR ;) (nop) ) - (func $__post_instantiate (; 4 ;) + (func $__post_instantiate (; 4 ;) (; has Stack IR ;) (set_global $STACKTOP (i32.add (get_global $memoryBase) diff --git a/test/dynamicLibrary.fromasm.clamp b/test/dynamicLibrary.fromasm.clamp index 295451b4c..edd7a60d0 100644 --- a/test/dynamicLibrary.fromasm.clamp +++ b/test/dynamicLibrary.fromasm.clamp @@ -13,7 +13,7 @@ (export "__post_instantiate" (func $__post_instantiate)) (export "runPostSets" (func $runPostSets)) (export "_global" (global $_global)) - (func $__ZN3FooC2Ev (; 2 ;) (param $0 i32) + (func $__ZN3FooC2Ev (; 2 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -42,10 +42,10 @@ (get_local $1) ) ) - (func $runPostSets (; 3 ;) + (func $runPostSets (; 3 ;) (; has Stack IR ;) (nop) ) - (func $__post_instantiate (; 4 ;) + (func $__post_instantiate (; 4 ;) (; has Stack IR ;) (set_global $STACKTOP (i32.add (get_global $memoryBase) diff --git a/test/dynamicLibrary.fromasm.imprecise b/test/dynamicLibrary.fromasm.imprecise index 58d9559ad..ce18a050f 100644 --- a/test/dynamicLibrary.fromasm.imprecise +++ b/test/dynamicLibrary.fromasm.imprecise @@ -11,7 +11,7 @@ (export "__post_instantiate" (func $__post_instantiate)) (export "runPostSets" (func $runPostSets)) (export "_global" (global $_global)) - (func $__ZN3FooC2Ev (; 2 ;) (param $0 i32) + (func $__ZN3FooC2Ev (; 2 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -40,10 +40,10 @@ (get_local $1) ) ) - (func $runPostSets (; 3 ;) + (func $runPostSets (; 3 ;) (; has Stack IR ;) (nop) ) - (func $__post_instantiate (; 4 ;) + (func $__post_instantiate (; 4 ;) (; has Stack IR ;) (set_global $STACKTOP (i32.add (get_global $memoryBase) diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm index cd097028a..0566193d0 100644 --- a/test/emcc_O2_hello_world.fromasm +++ b/test/emcc_O2_hello_world.fromasm @@ -51,7 +51,7 @@ (export "dynCall_ii" (func $dynCall_ii)) (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) - (func $_malloc (; 15 ;) (param $0 i32) (result i32) + (func $_malloc (; 15 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5830,7 +5830,7 @@ ) (i32.const 0) ) - (func $_free (; 16 ;) (param $0 i32) + (func $_free (; 16 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7651,7 +7651,7 @@ (i32.const -1) ) ) - (func $___stdio_write (; 17 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 17 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8025,7 +8025,7 @@ ) (get_local $15) ) - (func $___fwritex (; 18 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8237,7 +8237,7 @@ ) (get_local $4) ) - (func $_fflush (; 19 ;) (param $0 i32) (result i32) + (func $_fflush (; 19 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -8344,7 +8344,7 @@ ) (get_local $1) ) - (func $_strlen (; 20 ;) (param $0 i32) (result i32) + (func $_strlen (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8488,7 +8488,7 @@ (get_local $3) ) ) - (func $___overflow (; 21 ;) (param $0 i32) (param $1 i32) (result i32) + (func $___overflow (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8642,7 +8642,7 @@ ) (get_local $4) ) - (func $___fflush_unlocked (; 22 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 22 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8765,7 +8765,7 @@ ) ) ) - (func $_memcpy (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8912,10 +8912,10 @@ ) (get_local $3) ) - (func $runPostSets (; 24 ;) + (func $runPostSets (; 24 ;) (; has Stack IR ;) (nop) ) - (func $_memset (; 25 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 25 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9053,7 +9053,7 @@ (get_local $2) ) ) - (func $_puts (; 26 ;) (param $0 i32) (result i32) + (func $_puts (; 26 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -9145,7 +9145,7 @@ (i32.const 31) ) ) - (func $___stdio_seek (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9214,7 +9214,7 @@ ) (get_local $0) ) - (func $___towrite (; 28 ;) (param $0 i32) (result i32) + (func $___towrite (; 28 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9292,7 +9292,7 @@ ) ) ) - (func $_fwrite (; 29 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_fwrite (; 29 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9331,7 +9331,7 @@ ) (get_local $2) ) - (func $___stdout_write (; 30 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 30 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9400,7 +9400,7 @@ ) (get_local $3) ) - (func $___stdio_close (; 31 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 31 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9430,7 +9430,7 @@ ) (get_local $0) ) - (func $___syscall_ret (; 32 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9449,7 +9449,7 @@ (get_local $0) ) ) - (func $dynCall_iiii (; 33 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 33 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9463,7 +9463,7 @@ ) ) ) - (func $stackAlloc (; 34 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 34 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9485,7 +9485,7 @@ ) (get_local $1) ) - (func $___errno_location (; 35 ;) (result i32) + (func $___errno_location (; 35 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 8) @@ -9496,7 +9496,7 @@ (i32.const 60) ) ) - (func $setThrew (; 36 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -9511,7 +9511,7 @@ ) ) ) - (func $dynCall_ii (; 37 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 37 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9520,14 +9520,14 @@ ) ) ) - (func $_cleanup_418 (; 38 ;) (param $0 i32) + (func $_cleanup_418 (; 38 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $establishStackSpace (; 39 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -9535,7 +9535,7 @@ (get_local $1) ) ) - (func $dynCall_vi (; 40 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9547,32 +9547,32 @@ ) ) ) - (func $b1 (; 41 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 41 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $abort (i32.const 1) ) (i32.const 0) ) - (func $stackRestore (; 42 ;) (param $0 i32) + (func $stackRestore (; 42 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $setTempRet0 (; 43 ;) (param $0 i32) + (func $setTempRet0 (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $b0 (; 44 ;) (param $0 i32) (result i32) + (func $b0 (; 44 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $abort (i32.const 0) ) (i32.const 0) ) - (func $getTempRet0 (; 45 ;) (result i32) + (func $getTempRet0 (; 45 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 46 ;) (result i32) + (func $_main (; 46 ;) (; has Stack IR ;) (result i32) (drop (call $_puts (i32.const 672) @@ -9580,10 +9580,10 @@ ) (i32.const 0) ) - (func $stackSave (; 47 ;) (result i32) + (func $stackSave (; 47 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $b2 (; 48 ;) (param $0 i32) + (func $b2 (; 48 ;) (; has Stack IR ;) (param $0 i32) (call $abort (i32.const 2) ) diff --git a/test/emcc_O2_hello_world.fromasm.clamp b/test/emcc_O2_hello_world.fromasm.clamp index cd097028a..0566193d0 100644 --- a/test/emcc_O2_hello_world.fromasm.clamp +++ b/test/emcc_O2_hello_world.fromasm.clamp @@ -51,7 +51,7 @@ (export "dynCall_ii" (func $dynCall_ii)) (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) - (func $_malloc (; 15 ;) (param $0 i32) (result i32) + (func $_malloc (; 15 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5830,7 +5830,7 @@ ) (i32.const 0) ) - (func $_free (; 16 ;) (param $0 i32) + (func $_free (; 16 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7651,7 +7651,7 @@ (i32.const -1) ) ) - (func $___stdio_write (; 17 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 17 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8025,7 +8025,7 @@ ) (get_local $15) ) - (func $___fwritex (; 18 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8237,7 +8237,7 @@ ) (get_local $4) ) - (func $_fflush (; 19 ;) (param $0 i32) (result i32) + (func $_fflush (; 19 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -8344,7 +8344,7 @@ ) (get_local $1) ) - (func $_strlen (; 20 ;) (param $0 i32) (result i32) + (func $_strlen (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8488,7 +8488,7 @@ (get_local $3) ) ) - (func $___overflow (; 21 ;) (param $0 i32) (param $1 i32) (result i32) + (func $___overflow (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8642,7 +8642,7 @@ ) (get_local $4) ) - (func $___fflush_unlocked (; 22 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 22 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8765,7 +8765,7 @@ ) ) ) - (func $_memcpy (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8912,10 +8912,10 @@ ) (get_local $3) ) - (func $runPostSets (; 24 ;) + (func $runPostSets (; 24 ;) (; has Stack IR ;) (nop) ) - (func $_memset (; 25 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 25 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9053,7 +9053,7 @@ (get_local $2) ) ) - (func $_puts (; 26 ;) (param $0 i32) (result i32) + (func $_puts (; 26 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -9145,7 +9145,7 @@ (i32.const 31) ) ) - (func $___stdio_seek (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9214,7 +9214,7 @@ ) (get_local $0) ) - (func $___towrite (; 28 ;) (param $0 i32) (result i32) + (func $___towrite (; 28 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9292,7 +9292,7 @@ ) ) ) - (func $_fwrite (; 29 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_fwrite (; 29 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9331,7 +9331,7 @@ ) (get_local $2) ) - (func $___stdout_write (; 30 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 30 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9400,7 +9400,7 @@ ) (get_local $3) ) - (func $___stdio_close (; 31 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 31 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9430,7 +9430,7 @@ ) (get_local $0) ) - (func $___syscall_ret (; 32 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9449,7 +9449,7 @@ (get_local $0) ) ) - (func $dynCall_iiii (; 33 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 33 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9463,7 +9463,7 @@ ) ) ) - (func $stackAlloc (; 34 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 34 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9485,7 +9485,7 @@ ) (get_local $1) ) - (func $___errno_location (; 35 ;) (result i32) + (func $___errno_location (; 35 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 8) @@ -9496,7 +9496,7 @@ (i32.const 60) ) ) - (func $setThrew (; 36 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -9511,7 +9511,7 @@ ) ) ) - (func $dynCall_ii (; 37 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 37 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9520,14 +9520,14 @@ ) ) ) - (func $_cleanup_418 (; 38 ;) (param $0 i32) + (func $_cleanup_418 (; 38 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $establishStackSpace (; 39 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -9535,7 +9535,7 @@ (get_local $1) ) ) - (func $dynCall_vi (; 40 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9547,32 +9547,32 @@ ) ) ) - (func $b1 (; 41 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 41 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $abort (i32.const 1) ) (i32.const 0) ) - (func $stackRestore (; 42 ;) (param $0 i32) + (func $stackRestore (; 42 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $setTempRet0 (; 43 ;) (param $0 i32) + (func $setTempRet0 (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $b0 (; 44 ;) (param $0 i32) (result i32) + (func $b0 (; 44 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $abort (i32.const 0) ) (i32.const 0) ) - (func $getTempRet0 (; 45 ;) (result i32) + (func $getTempRet0 (; 45 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 46 ;) (result i32) + (func $_main (; 46 ;) (; has Stack IR ;) (result i32) (drop (call $_puts (i32.const 672) @@ -9580,10 +9580,10 @@ ) (i32.const 0) ) - (func $stackSave (; 47 ;) (result i32) + (func $stackSave (; 47 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $b2 (; 48 ;) (param $0 i32) + (func $b2 (; 48 ;) (; has Stack IR ;) (param $0 i32) (call $abort (i32.const 2) ) diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise index 1e7e99197..d34cf8655 100644 --- a/test/emcc_O2_hello_world.fromasm.imprecise +++ b/test/emcc_O2_hello_world.fromasm.imprecise @@ -50,7 +50,7 @@ (export "dynCall_ii" (func $dynCall_ii)) (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) - (func $_malloc (; 15 ;) (param $0 i32) (result i32) + (func $_malloc (; 15 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5829,7 +5829,7 @@ ) (i32.const 0) ) - (func $_free (; 16 ;) (param $0 i32) + (func $_free (; 16 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7650,7 +7650,7 @@ (i32.const -1) ) ) - (func $___stdio_write (; 17 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 17 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8024,7 +8024,7 @@ ) (get_local $15) ) - (func $___fwritex (; 18 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8236,7 +8236,7 @@ ) (get_local $4) ) - (func $_fflush (; 19 ;) (param $0 i32) (result i32) + (func $_fflush (; 19 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -8338,7 +8338,7 @@ ) (get_local $1) ) - (func $_strlen (; 20 ;) (param $0 i32) (result i32) + (func $_strlen (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8482,7 +8482,7 @@ (get_local $3) ) ) - (func $___overflow (; 21 ;) (param $0 i32) (param $1 i32) (result i32) + (func $___overflow (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8636,7 +8636,7 @@ ) (get_local $4) ) - (func $___fflush_unlocked (; 22 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 22 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8759,7 +8759,7 @@ ) ) ) - (func $_memcpy (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8906,10 +8906,10 @@ ) (get_local $3) ) - (func $runPostSets (; 24 ;) + (func $runPostSets (; 24 ;) (; has Stack IR ;) (nop) ) - (func $_memset (; 25 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 25 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9047,7 +9047,7 @@ (get_local $2) ) ) - (func $_puts (; 26 ;) (param $0 i32) (result i32) + (func $_puts (; 26 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -9139,7 +9139,7 @@ (i32.const 31) ) ) - (func $___stdio_seek (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9208,7 +9208,7 @@ ) (get_local $0) ) - (func $___towrite (; 28 ;) (param $0 i32) (result i32) + (func $___towrite (; 28 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9286,7 +9286,7 @@ ) ) ) - (func $_fwrite (; 29 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_fwrite (; 29 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9314,7 +9314,7 @@ ) (get_local $2) ) - (func $___stdout_write (; 30 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 30 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9383,7 +9383,7 @@ ) (get_local $3) ) - (func $___stdio_close (; 31 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 31 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9413,7 +9413,7 @@ ) (get_local $0) ) - (func $___syscall_ret (; 32 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9432,7 +9432,7 @@ (get_local $0) ) ) - (func $dynCall_iiii (; 33 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 33 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9446,7 +9446,7 @@ ) ) ) - (func $stackAlloc (; 34 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 34 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -9468,7 +9468,7 @@ ) (get_local $1) ) - (func $___errno_location (; 35 ;) (result i32) + (func $___errno_location (; 35 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 8) @@ -9479,7 +9479,7 @@ (i32.const 60) ) ) - (func $setThrew (; 36 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -9494,7 +9494,7 @@ ) ) ) - (func $dynCall_ii (; 37 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 37 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9503,10 +9503,10 @@ ) ) ) - (func $_cleanup_418 (; 38 ;) (param $0 i32) + (func $_cleanup_418 (; 38 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $establishStackSpace (; 39 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -9514,7 +9514,7 @@ (get_local $1) ) ) - (func $dynCall_vi (; 40 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9526,32 +9526,32 @@ ) ) ) - (func $b1 (; 41 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 41 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $abort (i32.const 1) ) (i32.const 0) ) - (func $stackRestore (; 42 ;) (param $0 i32) + (func $stackRestore (; 42 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $setTempRet0 (; 43 ;) (param $0 i32) + (func $setTempRet0 (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $b0 (; 44 ;) (param $0 i32) (result i32) + (func $b0 (; 44 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $abort (i32.const 0) ) (i32.const 0) ) - (func $getTempRet0 (; 45 ;) (result i32) + (func $getTempRet0 (; 45 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 46 ;) (result i32) + (func $_main (; 46 ;) (; has Stack IR ;) (result i32) (drop (call $_puts (i32.const 672) @@ -9559,10 +9559,10 @@ ) (i32.const 0) ) - (func $stackSave (; 47 ;) (result i32) + (func $stackSave (; 47 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $b2 (; 48 ;) (param $0 i32) + (func $b2 (; 48 ;) (; has Stack IR ;) (param $0 i32) (call $abort (i32.const 2) ) diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index 5f9343488..6811213dc 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -63,7 +63,7 @@ (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) (export "___udivmoddi4" (func $___udivmoddi4)) - (func $stackAlloc (; 19 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 19 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -92,15 +92,15 @@ ) (get_local $1) ) - (func $stackSave (; 20 ;) (result i32) + (func $stackSave (; 20 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $stackRestore (; 21 ;) (param $0 i32) + (func $stackRestore (; 21 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $establishStackSpace (; 22 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 22 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -108,7 +108,7 @@ (get_local $1) ) ) - (func $setThrew (; 23 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -123,15 +123,15 @@ ) ) ) - (func $setTempRet0 (; 24 ;) (param $0 i32) + (func $setTempRet0 (; 24 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $getTempRet0 (; 25 ;) (result i32) + (func $getTempRet0 (; 25 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 26 ;) (result i32) + (func $_main (; 26 ;) (; has Stack IR ;) (result i32) (local $0 i32) (set_local $0 (get_global $STACKTOP) @@ -160,7 +160,7 @@ ) (i32.const 0) ) - (func $_frexp (; 27 ;) (param $0 f64) (param $1 i32) (result f64) + (func $_frexp (; 27 ;) (; has Stack IR ;) (param $0 f64) (param $1 i32) (result f64) (local $2 i32) (local $3 i32) (local $4 i32) @@ -265,7 +265,7 @@ ) (get_local $0) ) - (func $_strerror (; 28 ;) (param $0 i32) (result i32) + (func $_strerror (; 28 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $__rjto$1 @@ -343,7 +343,7 @@ ) (get_local $0) ) - (func $___errno_location (; 29 ;) (result i32) + (func $___errno_location (; 29 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 16) @@ -354,7 +354,7 @@ (i32.const 60) ) ) - (func $___stdio_close (; 30 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 30 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -391,7 +391,7 @@ ) (get_local $0) ) - (func $___stdout_write (; 31 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 31 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -471,7 +471,7 @@ ) (get_local $0) ) - (func $___stdio_seek (; 32 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 32 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -547,7 +547,7 @@ ) (get_local $0) ) - (func $_fflush (; 33 ;) (param $0 i32) (result i32) + (func $_fflush (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -642,7 +642,7 @@ ) (get_local $0) ) - (func $_printf (; 34 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_printf (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (set_local $2 (get_global $STACKTOP) @@ -678,7 +678,7 @@ ) (get_local $0) ) - (func $___stdio_write (; 35 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1023,7 +1023,7 @@ ) (get_local $2) ) - (func $_vfprintf (; 36 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_vfprintf (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1300,7 +1300,7 @@ ) (get_local $0) ) - (func $___fwritex (; 37 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 37 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1486,7 +1486,7 @@ ) (get_local $3) ) - (func $___towrite (; 38 ;) (param $0 i32) (result i32) + (func $___towrite (; 38 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $1 @@ -1564,7 +1564,7 @@ ) ) ) - (func $_wcrtomb (; 39 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_wcrtomb (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (block $do-once (result i32) (if (result i32) (get_local $0) @@ -1738,7 +1738,7 @@ ) ) ) - (func $_wctomb (; 40 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_wctomb (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $0) (call $_wcrtomb @@ -1749,7 +1749,7 @@ (i32.const 0) ) ) - (func $_memchr (; 41 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 41 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1980,7 +1980,7 @@ (get_local $0) ) ) - (func $___syscall_ret (; 42 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 42 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -1999,7 +1999,7 @@ (get_local $0) ) ) - (func $___fflush_unlocked (; 43 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 43 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -2121,14 +2121,14 @@ ) ) ) - (func $_cleanup (; 44 ;) (param $0 i32) + (func $_cleanup (; 44 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $i32s-div (; 45 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32s-div (; 45 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (if (result i32) @@ -2151,7 +2151,7 @@ (i32.const 0) ) ) - (func $i32u-rem (; 46 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32u-rem (; 46 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.rem_u @@ -2161,7 +2161,7 @@ (i32.const 0) ) ) - (func $i32u-div (; 47 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32u-div (; 47 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.div_u @@ -2171,7 +2171,7 @@ (i32.const 0) ) ) - (func $_printf_core (; 48 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_printf_core (; 48 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -6991,7 +6991,7 @@ ) (get_local $17) ) - (func $_pop_arg_336 (; 49 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $_pop_arg_336 (; 49 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 f64) (local $5 i32) @@ -7391,7 +7391,7 @@ ) ) ) - (func $_fmt_u (; 50 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_fmt_u (; 50 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (if @@ -7513,7 +7513,7 @@ ) (get_local $2) ) - (func $_pad (; 51 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (func $_pad (; 51 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -7661,7 +7661,7 @@ (get_local $7) ) ) - (func $_malloc (; 52 ;) (param $0 i32) (result i32) + (func $_malloc (; 52 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -13094,7 +13094,7 @@ (i32.const 8) ) ) - (func $_free (; 53 ;) (param $0 i32) + (func $_free (; 53 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -14877,10 +14877,10 @@ (i32.const -1) ) ) - (func $runPostSets (; 54 ;) + (func $runPostSets (; 54 ;) (; has Stack IR ;) (nop) ) - (func $_i64Subtract (; 55 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Subtract (; 55 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (set_global $tempRet0 (i32.sub (i32.sub @@ -14898,7 +14898,7 @@ (get_local $2) ) ) - (func $_i64Add (; 56 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Add (; 56 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_global $tempRet0 (i32.add @@ -14919,7 +14919,7 @@ ) (get_local $4) ) - (func $_memset (; 57 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 57 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -15057,7 +15057,7 @@ (get_local $2) ) ) - (func $_bitshift64Lshr (; 58 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Lshr (; 58 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15107,7 +15107,7 @@ ) ) ) - (func $_bitshift64Shl (; 59 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Shl (; 59 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15163,7 +15163,7 @@ ) (i32.const 0) ) - (func $_memcpy (; 60 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 60 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -15310,7 +15310,7 @@ ) (get_local $3) ) - (func $___udivdi3 (; 61 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___udivdi3 (; 61 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call $___udivmoddi4 (get_local $0) (get_local $1) @@ -15319,7 +15319,7 @@ (i32.const 0) ) ) - (func $___uremdi3 (; 62 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___uremdi3 (; 62 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (get_global $STACKTOP) @@ -15351,7 +15351,7 @@ (get_local $4) ) ) - (func $___udivmoddi4 (; 63 ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) + (func $___udivmoddi4 (; 63 ;) (; has Stack IR ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) (local $x64 i64) (local $y64 i64) (set_local $x64 @@ -15408,7 +15408,7 @@ (get_local $x64) ) ) - (func $dynCall_ii (; 64 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 64 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -15417,7 +15417,7 @@ ) ) ) - (func $dynCall_iiii (; 65 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 65 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -15431,7 +15431,7 @@ ) ) ) - (func $dynCall_vi (; 66 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 66 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -15443,19 +15443,19 @@ ) ) ) - (func $b0 (; 67 ;) (param $0 i32) (result i32) + (func $b0 (; 67 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $nullFunc_ii (i32.const 0) ) (i32.const 0) ) - (func $b1 (; 68 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 68 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $nullFunc_iiii (i32.const 1) ) (i32.const 0) ) - (func $b2 (; 69 ;) (param $0 i32) + (func $b2 (; 69 ;) (; has Stack IR ;) (param $0 i32) (call $nullFunc_vi (i32.const 2) ) diff --git a/test/emcc_hello_world.fromasm.clamp b/test/emcc_hello_world.fromasm.clamp index 9ce70c0b5..ea687d264 100644 --- a/test/emcc_hello_world.fromasm.clamp +++ b/test/emcc_hello_world.fromasm.clamp @@ -61,7 +61,7 @@ (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) (export "___udivmoddi4" (func $___udivmoddi4)) - (func $stackAlloc (; 18 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 18 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -90,15 +90,15 @@ ) (get_local $1) ) - (func $stackSave (; 19 ;) (result i32) + (func $stackSave (; 19 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $stackRestore (; 20 ;) (param $0 i32) + (func $stackRestore (; 20 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $establishStackSpace (; 21 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -106,7 +106,7 @@ (get_local $1) ) ) - (func $setThrew (; 22 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 22 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -121,15 +121,15 @@ ) ) ) - (func $setTempRet0 (; 23 ;) (param $0 i32) + (func $setTempRet0 (; 23 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $getTempRet0 (; 24 ;) (result i32) + (func $getTempRet0 (; 24 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 25 ;) (result i32) + (func $_main (; 25 ;) (; has Stack IR ;) (result i32) (local $0 i32) (set_local $0 (get_global $STACKTOP) @@ -158,7 +158,7 @@ ) (i32.const 0) ) - (func $_frexp (; 26 ;) (param $0 f64) (param $1 i32) (result f64) + (func $_frexp (; 26 ;) (; has Stack IR ;) (param $0 f64) (param $1 i32) (result f64) (local $2 i32) (local $3 i32) (local $4 i32) @@ -263,7 +263,7 @@ ) (get_local $0) ) - (func $_strerror (; 27 ;) (param $0 i32) (result i32) + (func $_strerror (; 27 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $__rjto$1 @@ -341,7 +341,7 @@ ) (get_local $0) ) - (func $___errno_location (; 28 ;) (result i32) + (func $___errno_location (; 28 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 16) @@ -352,7 +352,7 @@ (i32.const 60) ) ) - (func $___stdio_close (; 29 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 29 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -389,7 +389,7 @@ ) (get_local $0) ) - (func $___stdout_write (; 30 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 30 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -469,7 +469,7 @@ ) (get_local $0) ) - (func $___stdio_seek (; 31 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 31 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -545,7 +545,7 @@ ) (get_local $0) ) - (func $_fflush (; 32 ;) (param $0 i32) (result i32) + (func $_fflush (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -640,7 +640,7 @@ ) (get_local $0) ) - (func $_printf (; 33 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_printf (; 33 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (set_local $2 (get_global $STACKTOP) @@ -676,7 +676,7 @@ ) (get_local $0) ) - (func $___stdio_write (; 34 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1021,7 +1021,7 @@ ) (get_local $2) ) - (func $_vfprintf (; 35 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_vfprintf (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1298,7 +1298,7 @@ ) (get_local $0) ) - (func $___fwritex (; 36 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1484,7 +1484,7 @@ ) (get_local $3) ) - (func $___towrite (; 37 ;) (param $0 i32) (result i32) + (func $___towrite (; 37 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $1 @@ -1562,7 +1562,7 @@ ) ) ) - (func $_wcrtomb (; 38 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_wcrtomb (; 38 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (block $do-once (result i32) (if (result i32) (get_local $0) @@ -1736,7 +1736,7 @@ ) ) ) - (func $_wctomb (; 39 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_wctomb (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $0) (call $_wcrtomb @@ -1747,7 +1747,7 @@ (i32.const 0) ) ) - (func $_memchr (; 40 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1978,7 +1978,7 @@ (get_local $0) ) ) - (func $___syscall_ret (; 41 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 41 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -1997,7 +1997,7 @@ (get_local $0) ) ) - (func $___fflush_unlocked (; 42 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 42 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -2119,14 +2119,14 @@ ) ) ) - (func $_cleanup (; 43 ;) (param $0 i32) + (func $_cleanup (; 43 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $f64-to-int (; 44 ;) (param $0 f64) (result i32) + (func $f64-to-int (; 44 ;) (; has Stack IR ;) (param $0 f64) (result i32) (if (result i32) (f64.ne (get_local $0) @@ -2152,7 +2152,7 @@ ) ) ) - (func $f64-to-uint (; 45 ;) (param $0 f64) (result i32) + (func $f64-to-uint (; 45 ;) (; has Stack IR ;) (param $0 f64) (result i32) (if (result i32) (f64.ne (get_local $0) @@ -2178,7 +2178,7 @@ ) ) ) - (func $i32s-div (; 46 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32s-div (; 46 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (if (result i32) @@ -2201,7 +2201,7 @@ (i32.const 0) ) ) - (func $i32u-rem (; 47 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32u-rem (; 47 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.rem_u @@ -2211,7 +2211,7 @@ (i32.const 0) ) ) - (func $i32u-div (; 48 ;) (param $0 i32) (param $1 i32) (result i32) + (func $i32u-div (; 48 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $1) (i32.div_u @@ -2221,7 +2221,7 @@ (i32.const 0) ) ) - (func $_printf_core (; 49 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_printf_core (; 49 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -7041,7 +7041,7 @@ ) (get_local $17) ) - (func $_pop_arg_336 (; 50 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $_pop_arg_336 (; 50 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 f64) (local $5 i32) @@ -7441,7 +7441,7 @@ ) ) ) - (func $_fmt_u (; 51 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_fmt_u (; 51 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (if @@ -7563,7 +7563,7 @@ ) (get_local $2) ) - (func $_pad (; 52 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (func $_pad (; 52 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -7711,7 +7711,7 @@ (get_local $7) ) ) - (func $_malloc (; 53 ;) (param $0 i32) (result i32) + (func $_malloc (; 53 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -13144,7 +13144,7 @@ (i32.const 8) ) ) - (func $_free (; 54 ;) (param $0 i32) + (func $_free (; 54 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -14927,10 +14927,10 @@ (i32.const -1) ) ) - (func $runPostSets (; 55 ;) + (func $runPostSets (; 55 ;) (; has Stack IR ;) (nop) ) - (func $_i64Subtract (; 56 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Subtract (; 56 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (set_global $tempRet0 (i32.sub (i32.sub @@ -14948,7 +14948,7 @@ (get_local $2) ) ) - (func $_i64Add (; 57 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Add (; 57 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_global $tempRet0 (i32.add @@ -14969,7 +14969,7 @@ ) (get_local $4) ) - (func $_memset (; 58 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 58 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -15107,7 +15107,7 @@ (get_local $2) ) ) - (func $_bitshift64Lshr (; 59 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Lshr (; 59 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15157,7 +15157,7 @@ ) ) ) - (func $_bitshift64Shl (; 60 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Shl (; 60 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15213,7 +15213,7 @@ ) (i32.const 0) ) - (func $_memcpy (; 61 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 61 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -15360,7 +15360,7 @@ ) (get_local $3) ) - (func $___udivdi3 (; 62 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___udivdi3 (; 62 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call $___udivmoddi4 (get_local $0) (get_local $1) @@ -15369,7 +15369,7 @@ (i32.const 0) ) ) - (func $___uremdi3 (; 63 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___uremdi3 (; 63 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (get_global $STACKTOP) @@ -15401,7 +15401,7 @@ (get_local $4) ) ) - (func $___udivmoddi4 (; 64 ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) + (func $___udivmoddi4 (; 64 ;) (; has Stack IR ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) (local $x64 i64) (local $y64 i64) (set_local $x64 @@ -15458,7 +15458,7 @@ (get_local $x64) ) ) - (func $dynCall_ii (; 65 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 65 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -15467,7 +15467,7 @@ ) ) ) - (func $dynCall_iiii (; 66 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 66 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -15481,7 +15481,7 @@ ) ) ) - (func $dynCall_vi (; 67 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 67 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -15493,19 +15493,19 @@ ) ) ) - (func $b0 (; 68 ;) (param $0 i32) (result i32) + (func $b0 (; 68 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $nullFunc_ii (i32.const 0) ) (i32.const 0) ) - (func $b1 (; 69 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 69 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $nullFunc_iiii (i32.const 1) ) (i32.const 0) ) - (func $b2 (; 70 ;) (param $0 i32) + (func $b2 (; 70 ;) (; has Stack IR ;) (param $0 i32) (call $nullFunc_vi (i32.const 2) ) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index f76c07317..25ca0c3da 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -60,7 +60,7 @@ (export "dynCall_iiii" (func $dynCall_iiii)) (export "dynCall_vi" (func $dynCall_vi)) (export "___udivmoddi4" (func $___udivmoddi4)) - (func $stackAlloc (; 18 ;) (param $0 i32) (result i32) + (func $stackAlloc (; 18 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -89,15 +89,15 @@ ) (get_local $1) ) - (func $stackSave (; 19 ;) (result i32) + (func $stackSave (; 19 ;) (; has Stack IR ;) (result i32) (get_global $STACKTOP) ) - (func $stackRestore (; 20 ;) (param $0 i32) + (func $stackRestore (; 20 ;) (; has Stack IR ;) (param $0 i32) (set_global $STACKTOP (get_local $0) ) ) - (func $establishStackSpace (; 21 ;) (param $0 i32) (param $1 i32) + (func $establishStackSpace (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $STACKTOP (get_local $0) ) @@ -105,7 +105,7 @@ (get_local $1) ) ) - (func $setThrew (; 22 ;) (param $0 i32) (param $1 i32) + (func $setThrew (; 22 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $__THREW__) @@ -120,15 +120,15 @@ ) ) ) - (func $setTempRet0 (; 23 ;) (param $0 i32) + (func $setTempRet0 (; 23 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) ) - (func $getTempRet0 (; 24 ;) (result i32) + (func $getTempRet0 (; 24 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $_main (; 25 ;) (result i32) + (func $_main (; 25 ;) (; has Stack IR ;) (result i32) (local $0 i32) (set_local $0 (get_global $STACKTOP) @@ -157,7 +157,7 @@ ) (i32.const 0) ) - (func $_frexp (; 26 ;) (param $0 f64) (param $1 i32) (result f64) + (func $_frexp (; 26 ;) (; has Stack IR ;) (param $0 f64) (param $1 i32) (result f64) (local $2 i32) (local $3 i32) (local $4 i32) @@ -262,7 +262,7 @@ ) (get_local $0) ) - (func $_strerror (; 27 ;) (param $0 i32) (result i32) + (func $_strerror (; 27 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $__rjto$1 @@ -340,7 +340,7 @@ ) (get_local $0) ) - (func $___errno_location (; 28 ;) (result i32) + (func $___errno_location (; 28 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 16) @@ -351,7 +351,7 @@ (i32.const 60) ) ) - (func $___stdio_close (; 29 ;) (param $0 i32) (result i32) + (func $___stdio_close (; 29 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $STACKTOP) @@ -388,7 +388,7 @@ ) (get_local $0) ) - (func $___stdout_write (; 30 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 30 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -468,7 +468,7 @@ ) (get_local $0) ) - (func $___stdio_seek (; 31 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_seek (; 31 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -544,7 +544,7 @@ ) (get_local $0) ) - (func $_fflush (; 32 ;) (param $0 i32) (result i32) + (func $_fflush (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (block $do-once @@ -634,7 +634,7 @@ ) (get_local $0) ) - (func $_printf (; 33 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_printf (; 33 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (set_local $2 (get_global $STACKTOP) @@ -670,7 +670,7 @@ ) (get_local $0) ) - (func $___stdio_write (; 34 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1015,7 +1015,7 @@ ) (get_local $2) ) - (func $_vfprintf (; 35 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_vfprintf (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1287,7 +1287,7 @@ ) (get_local $0) ) - (func $___fwritex (; 36 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___fwritex (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1473,7 +1473,7 @@ ) (get_local $3) ) - (func $___towrite (; 37 ;) (param $0 i32) (result i32) + (func $___towrite (; 37 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $1 @@ -1551,7 +1551,7 @@ ) ) ) - (func $_wcrtomb (; 38 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_wcrtomb (; 38 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (block $do-once (result i32) (if (result i32) (get_local $0) @@ -1725,7 +1725,7 @@ ) ) ) - (func $_wctomb (; 39 ;) (param $0 i32) (param $1 i32) (result i32) + (func $_wctomb (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (result i32) (get_local $0) (call $_wcrtomb @@ -1736,7 +1736,7 @@ (i32.const 0) ) ) - (func $_memchr (; 40 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1967,7 +1967,7 @@ (get_local $0) ) ) - (func $___syscall_ret (; 41 ;) (param $0 i32) (result i32) + (func $___syscall_ret (; 41 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -1986,7 +1986,7 @@ (get_local $0) ) ) - (func $___fflush_unlocked (; 42 ;) (param $0 i32) (result i32) + (func $___fflush_unlocked (; 42 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -2108,10 +2108,10 @@ ) ) ) - (func $_cleanup (; 43 ;) (param $0 i32) + (func $_cleanup (; 43 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $_printf_core (; 44 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_printf_core (; 44 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -6906,7 +6906,7 @@ ) (get_local $17) ) - (func $_pop_arg_336 (; 45 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $_pop_arg_336 (; 45 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 f64) (local $5 i32) @@ -7306,7 +7306,7 @@ ) ) ) - (func $_fmt_u (; 46 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_fmt_u (; 46 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (if @@ -7428,7 +7428,7 @@ ) (get_local $2) ) - (func $_pad (; 47 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (func $_pad (; 47 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -7576,7 +7576,7 @@ (get_local $7) ) ) - (func $_malloc (; 48 ;) (param $0 i32) (result i32) + (func $_malloc (; 48 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -13009,7 +13009,7 @@ (i32.const 8) ) ) - (func $_free (; 49 ;) (param $0 i32) + (func $_free (; 49 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -14791,10 +14791,10 @@ (i32.const -1) ) ) - (func $runPostSets (; 50 ;) + (func $runPostSets (; 50 ;) (; has Stack IR ;) (nop) ) - (func $_i64Subtract (; 51 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Subtract (; 51 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (set_global $tempRet0 (i32.sub (i32.sub @@ -14812,7 +14812,7 @@ (get_local $2) ) ) - (func $_i64Add (; 52 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $_i64Add (; 52 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_global $tempRet0 (i32.add @@ -14833,7 +14833,7 @@ ) (get_local $4) ) - (func $_memset (; 53 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memset (; 53 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -14971,7 +14971,7 @@ (get_local $2) ) ) - (func $_bitshift64Lshr (; 54 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Lshr (; 54 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15021,7 +15021,7 @@ ) ) ) - (func $_bitshift64Shl (; 55 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_bitshift64Shl (; 55 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (if (i32.lt_s (get_local $2) @@ -15077,7 +15077,7 @@ ) (i32.const 0) ) - (func $_memcpy (; 56 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memcpy (; 56 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -15224,7 +15224,7 @@ ) (get_local $3) ) - (func $___udivdi3 (; 57 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___udivdi3 (; 57 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call $___udivmoddi4 (get_local $0) (get_local $1) @@ -15233,7 +15233,7 @@ (i32.const 0) ) ) - (func $___uremdi3 (; 58 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $___uremdi3 (; 58 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (get_global $STACKTOP) @@ -15265,7 +15265,7 @@ (get_local $4) ) ) - (func $___udivmoddi4 (; 59 ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) + (func $___udivmoddi4 (; 59 ;) (; has Stack IR ;) (param $xl i32) (param $xh i32) (param $yl i32) (param $yh i32) (param $r i32) (result i32) (local $x64 i64) (local $y64 i64) (set_local $x64 @@ -15322,7 +15322,7 @@ (get_local $x64) ) ) - (func $dynCall_ii (; 60 ;) (param $0 i32) (param $1 i32) (result i32) + (func $dynCall_ii (; 60 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -15331,7 +15331,7 @@ ) ) ) - (func $dynCall_iiii (; 61 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $dynCall_iiii (; 61 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -15345,7 +15345,7 @@ ) ) ) - (func $dynCall_vi (; 62 ;) (param $0 i32) (param $1 i32) + (func $dynCall_vi (; 62 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -15357,19 +15357,19 @@ ) ) ) - (func $b0 (; 63 ;) (param $0 i32) (result i32) + (func $b0 (; 63 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $nullFunc_ii (i32.const 0) ) (i32.const 0) ) - (func $b1 (; 64 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $b1 (; 64 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $nullFunc_iiii (i32.const 1) ) (i32.const 0) ) - (func $b2 (; 65 ;) (param $0 i32) + (func $b2 (; 65 ;) (; has Stack IR ;) (param $0 i32) (call $nullFunc_vi (i32.const 2) ) diff --git a/test/example/relooper-fuzz.txt b/test/example/relooper-fuzz.txt index aeee64325..bde48af8c 100644 --- a/test/example/relooper-fuzz.txt +++ b/test/example/relooper-fuzz.txt @@ -299,7 +299,7 @@ (memory $0 1 1) (export "mem" (memory $0)) (start $main) - (func $check (; 1 ;) (type $i) (result i32) + (func $check (; 1 ;) (; has Stack IR ;) (type $i) (result i32) (if (i32.eq (i32.load @@ -334,7 +334,7 @@ ) ) ) - (func $main (; 2 ;) (type $v) + (func $main (; 2 ;) (; has Stack IR ;) (type $v) (local $0 i32) (local $1 i32) (i32.store diff --git a/test/example/relooper-fuzz1.txt b/test/example/relooper-fuzz1.txt index 5da2f5ff3..af3140f9c 100644 --- a/test/example/relooper-fuzz1.txt +++ b/test/example/relooper-fuzz1.txt @@ -275,7 +275,7 @@ (memory $0 1 1) (export "mem" (memory $0)) (start $main) - (func $check (; 1 ;) (type $i) (result i32) + (func $check (; 1 ;) (; has Stack IR ;) (type $i) (result i32) (if (i32.eq (i32.load @@ -310,7 +310,7 @@ ) ) ) - (func $main (; 2 ;) (type $v) + (func $main (; 2 ;) (; has Stack IR ;) (type $v) (local $0 i32) (i32.store (i32.const 8) diff --git a/test/hello_world.fromasm b/test/hello_world.fromasm index a98f6895d..16f132114 100644 --- a/test/hello_world.fromasm +++ b/test/hello_world.fromasm @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "hello_world.asm.js") (export "add" (func $add)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (i32.add (get_local $0) (get_local $1) diff --git a/test/hello_world.fromasm.clamp b/test/hello_world.fromasm.clamp index a98f6895d..16f132114 100644 --- a/test/hello_world.fromasm.clamp +++ b/test/hello_world.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "hello_world.asm.js") (export "add" (func $add)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (i32.add (get_local $0) (get_local $1) diff --git a/test/hello_world.fromasm.imprecise b/test/hello_world.fromasm.imprecise index 3655a5039..1732728a5 100644 --- a/test/hello_world.fromasm.imprecise +++ b/test/hello_world.fromasm.imprecise @@ -1,6 +1,6 @@ (module (export "add" (func $add)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) + (func $add (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (i32.add (get_local $0) (get_local $1) diff --git a/test/i64-setTempRet0.fromasm b/test/i64-setTempRet0.fromasm index ecb43a49c..bb834c144 100644 --- a/test/i64-setTempRet0.fromasm +++ b/test/i64-setTempRet0.fromasm @@ -7,7 +7,7 @@ (data (get_global $memoryBase) "i64-setTempRet0.asm.js") (export "illegalResult" (func $legalstub$illegalResult)) (export "imports" (func $imports)) - (func $imports (; 1 ;) (result i32) + (func $imports (; 1 ;) (; has Stack IR ;) (result i32) (i32.wrap/i64 (i64.or (i64.extend_u/i32 @@ -22,7 +22,7 @@ ) ) ) - (func $legalstub$illegalResult (; 2 ;) (result i32) + (func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) diff --git a/test/i64-setTempRet0.fromasm.clamp b/test/i64-setTempRet0.fromasm.clamp index ecb43a49c..bb834c144 100644 --- a/test/i64-setTempRet0.fromasm.clamp +++ b/test/i64-setTempRet0.fromasm.clamp @@ -7,7 +7,7 @@ (data (get_global $memoryBase) "i64-setTempRet0.asm.js") (export "illegalResult" (func $legalstub$illegalResult)) (export "imports" (func $imports)) - (func $imports (; 1 ;) (result i32) + (func $imports (; 1 ;) (; has Stack IR ;) (result i32) (i32.wrap/i64 (i64.or (i64.extend_u/i32 @@ -22,7 +22,7 @@ ) ) ) - (func $legalstub$illegalResult (; 2 ;) (result i32) + (func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) diff --git a/test/i64-setTempRet0.fromasm.imprecise b/test/i64-setTempRet0.fromasm.imprecise index c1ead5c79..4b22d94c8 100644 --- a/test/i64-setTempRet0.fromasm.imprecise +++ b/test/i64-setTempRet0.fromasm.imprecise @@ -4,7 +4,7 @@ (global $tempRet0 (mut i32) (i32.const 0)) (export "illegalResult" (func $legalstub$illegalResult)) (export "imports" (func $imports)) - (func $imports (; 1 ;) (result i32) + (func $imports (; 1 ;) (; has Stack IR ;) (result i32) (i32.wrap/i64 (i64.or (i64.extend_u/i32 @@ -19,7 +19,7 @@ ) ) ) - (func $legalstub$illegalResult (; 2 ;) (result i32) + (func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) diff --git a/test/importedSignCast.fromasm b/test/importedSignCast.fromasm index bc08b3596..81652875a 100644 --- a/test/importedSignCast.fromasm +++ b/test/importedSignCast.fromasm @@ -8,7 +8,7 @@ (elem (get_global $tableBase) $gm) (data (get_global $memoryBase) "importedSignCast.asm.js") (export "func" (func $func)) - (func $func (; 1 ;) + (func $func (; 1 ;) (; has Stack IR ;) (drop (call $gm (i32.const 0) diff --git a/test/importedSignCast.fromasm.clamp b/test/importedSignCast.fromasm.clamp index bc08b3596..81652875a 100644 --- a/test/importedSignCast.fromasm.clamp +++ b/test/importedSignCast.fromasm.clamp @@ -8,7 +8,7 @@ (elem (get_global $tableBase) $gm) (data (get_global $memoryBase) "importedSignCast.asm.js") (export "func" (func $func)) - (func $func (; 1 ;) + (func $func (; 1 ;) (; has Stack IR ;) (drop (call $gm (i32.const 0) diff --git a/test/importedSignCast.fromasm.imprecise b/test/importedSignCast.fromasm.imprecise index ecf04c851..d31be8dc4 100644 --- a/test/importedSignCast.fromasm.imprecise +++ b/test/importedSignCast.fromasm.imprecise @@ -5,7 +5,7 @@ (import "env" "_emscripten_glIsTexture" (func $gm (param i32) (result i32))) (elem (get_global $tableBase) $gm) (export "func" (func $func)) - (func $func (; 1 ;) + (func $func (; 1 ;) (; has Stack IR ;) (drop (call $gm (i32.const 0) diff --git a/test/memorygrowth-minimal.fromasm b/test/memorygrowth-minimal.fromasm index 5c5b303b3..021d7fca2 100644 --- a/test/memorygrowth-minimal.fromasm +++ b/test/memorygrowth-minimal.fromasm @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "memorygrowth-minimal.asm.js") (export "__growWasmMemory" (func $__growWasmMemory)) - (func $__growWasmMemory (; 0 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 0 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) diff --git a/test/memorygrowth-minimal.fromasm.clamp b/test/memorygrowth-minimal.fromasm.clamp index 5c5b303b3..021d7fca2 100644 --- a/test/memorygrowth-minimal.fromasm.clamp +++ b/test/memorygrowth-minimal.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "memorygrowth-minimal.asm.js") (export "__growWasmMemory" (func $__growWasmMemory)) - (func $__growWasmMemory (; 0 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 0 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) diff --git a/test/memorygrowth-minimal.fromasm.imprecise b/test/memorygrowth-minimal.fromasm.imprecise index 4f308717e..7a8ef1065 100644 --- a/test/memorygrowth-minimal.fromasm.imprecise +++ b/test/memorygrowth-minimal.fromasm.imprecise @@ -1,7 +1,7 @@ (module (import "env" "memory" (memory $0 256)) (export "__growWasmMemory" (func $__growWasmMemory)) - (func $__growWasmMemory (; 0 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 0 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm index cf5cf85c2..5afec926b 100644 --- a/test/memorygrowth.fromasm +++ b/test/memorygrowth.fromasm @@ -50,12 +50,12 @@ (export "dynCall_ii" (func $kb)) (export "dynCall_iiii" (func $lb)) (export "dynCall_vi" (func $mb)) - (func $__growWasmMemory (; 12 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 12 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) ) - (func $eb (; 13 ;) (param $0 i32) (result i32) + (func $eb (; 13 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5877,7 +5877,7 @@ (i32.const 8) ) ) - (func $fb (; 14 ;) (param $0 i32) + (func $fb (; 14 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7698,7 +7698,7 @@ (i32.const -1) ) ) - (func $Ra (; 15 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ra (; 15 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8072,7 +8072,7 @@ ) (get_local $15) ) - (func $Wa (; 16 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Wa (; 16 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8284,7 +8284,7 @@ ) (get_local $4) ) - (func $Za (; 17 ;) (param $0 i32) (result i32) + (func $Za (; 17 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8428,7 +8428,7 @@ (get_local $3) ) ) - (func $_a (; 18 ;) (param $0 i32) (result i32) + (func $_a (; 18 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (tee_local $1 @@ -8532,7 +8532,7 @@ ) ) ) - (func $ab (; 19 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ab (; 19 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8681,7 +8681,7 @@ ) (get_local $4) ) - (func $$a (; 20 ;) (param $0 i32) (result i32) + (func $$a (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8816,7 +8816,7 @@ ) (get_local $2) ) - (func $jb (; 21 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $jb (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8963,10 +8963,10 @@ ) (get_local $3) ) - (func $gb (; 22 ;) + (func $gb (; 22 ;) (; has Stack IR ;) (nop) ) - (func $hb (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $hb (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9104,7 +9104,7 @@ (get_local $2) ) ) - (func $db (; 24 ;) (param $0 i32) (result i32) + (func $db (; 24 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (drop @@ -9194,7 +9194,7 @@ (i32.const 31) ) ) - (func $Xa (; 25 ;) (param $0 i32) (result i32) + (func $Xa (; 25 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9272,7 +9272,7 @@ ) ) ) - (func $bb (; 26 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $bb (; 26 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9311,7 +9311,7 @@ ) (get_local $2) ) - (func $Ua (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ua (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9380,7 +9380,7 @@ ) (get_local $0) ) - (func $Va (; 28 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Va (; 28 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9450,7 +9450,7 @@ ) (get_local $3) ) - (func $Oa (; 29 ;) (param $0 i32) (result i32) + (func $Oa (; 29 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9480,7 +9480,7 @@ ) (get_local $0) ) - (func $Pa (; 30 ;) (param $0 i32) (result i32) + (func $Pa (; 30 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9499,7 +9499,7 @@ (get_local $0) ) ) - (func $Qa (; 31 ;) (result i32) + (func $Qa (; 31 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 1160) @@ -9510,7 +9510,7 @@ (i32.const 1204) ) ) - (func $lb (; 32 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $lb (; 32 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9524,7 +9524,7 @@ ) ) ) - (func $Ea (; 33 ;) (param $0 i32) (result i32) + (func $Ea (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9546,13 +9546,13 @@ ) (get_local $1) ) - (func $ob (; 34 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $ob (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $ja (i32.const 1) ) (i32.const 0) ) - (func $Ia (; 35 ;) (param $0 i32) (param $1 i32) + (func $Ia (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $v) @@ -9567,7 +9567,7 @@ ) ) ) - (func $kb (; 36 ;) (param $0 i32) (param $1 i32) (result i32) + (func $kb (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9576,14 +9576,14 @@ ) ) ) - (func $Sa (; 37 ;) (param $0 i32) + (func $Sa (; 37 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $mb (; 38 ;) (param $0 i32) (param $1 i32) + (func $mb (; 38 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9595,7 +9595,7 @@ ) ) ) - (func $Ha (; 39 ;) (param $0 i32) (param $1 i32) + (func $Ha (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $r (get_local $0) ) @@ -9603,13 +9603,13 @@ (get_local $1) ) ) - (func $nb (; 40 ;) (param $0 i32) (result i32) + (func $nb (; 40 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $ja (i32.const 0) ) (i32.const 0) ) - (func $Na (; 41 ;) (result i32) + (func $Na (; 41 ;) (; has Stack IR ;) (result i32) (drop (call $db (i32.const 1144) @@ -9617,28 +9617,28 @@ ) (i32.const 0) ) - (func $pb (; 42 ;) (param $0 i32) + (func $pb (; 42 ;) (; has Stack IR ;) (param $0 i32) (call $ja (i32.const 2) ) ) - (func $La (; 43 ;) (param $0 i32) + (func $La (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $K (get_local $0) ) ) - (func $Ga (; 44 ;) (param $0 i32) + (func $Ga (; 44 ;) (; has Stack IR ;) (param $0 i32) (set_global $r (get_local $0) ) ) - (func $Ma (; 45 ;) (result i32) + (func $Ma (; 45 ;) (; has Stack IR ;) (result i32) (get_global $K) ) - (func $Fa (; 46 ;) (result i32) + (func $Fa (; 46 ;) (; has Stack IR ;) (result i32) (get_global $r) ) - (func $ib (; 47 ;) (result i32) + (func $ib (; 47 ;) (; has Stack IR ;) (result i32) (i32.const 0) ) ) diff --git a/test/memorygrowth.fromasm.clamp b/test/memorygrowth.fromasm.clamp index cf5cf85c2..5afec926b 100644 --- a/test/memorygrowth.fromasm.clamp +++ b/test/memorygrowth.fromasm.clamp @@ -50,12 +50,12 @@ (export "dynCall_ii" (func $kb)) (export "dynCall_iiii" (func $lb)) (export "dynCall_vi" (func $mb)) - (func $__growWasmMemory (; 12 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 12 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) ) - (func $eb (; 13 ;) (param $0 i32) (result i32) + (func $eb (; 13 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5877,7 +5877,7 @@ (i32.const 8) ) ) - (func $fb (; 14 ;) (param $0 i32) + (func $fb (; 14 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7698,7 +7698,7 @@ (i32.const -1) ) ) - (func $Ra (; 15 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ra (; 15 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8072,7 +8072,7 @@ ) (get_local $15) ) - (func $Wa (; 16 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Wa (; 16 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8284,7 +8284,7 @@ ) (get_local $4) ) - (func $Za (; 17 ;) (param $0 i32) (result i32) + (func $Za (; 17 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8428,7 +8428,7 @@ (get_local $3) ) ) - (func $_a (; 18 ;) (param $0 i32) (result i32) + (func $_a (; 18 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (tee_local $1 @@ -8532,7 +8532,7 @@ ) ) ) - (func $ab (; 19 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ab (; 19 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8681,7 +8681,7 @@ ) (get_local $4) ) - (func $$a (; 20 ;) (param $0 i32) (result i32) + (func $$a (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8816,7 +8816,7 @@ ) (get_local $2) ) - (func $jb (; 21 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $jb (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8963,10 +8963,10 @@ ) (get_local $3) ) - (func $gb (; 22 ;) + (func $gb (; 22 ;) (; has Stack IR ;) (nop) ) - (func $hb (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $hb (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9104,7 +9104,7 @@ (get_local $2) ) ) - (func $db (; 24 ;) (param $0 i32) (result i32) + (func $db (; 24 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (drop @@ -9194,7 +9194,7 @@ (i32.const 31) ) ) - (func $Xa (; 25 ;) (param $0 i32) (result i32) + (func $Xa (; 25 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9272,7 +9272,7 @@ ) ) ) - (func $bb (; 26 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $bb (; 26 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9311,7 +9311,7 @@ ) (get_local $2) ) - (func $Ua (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ua (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9380,7 +9380,7 @@ ) (get_local $0) ) - (func $Va (; 28 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Va (; 28 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9450,7 +9450,7 @@ ) (get_local $3) ) - (func $Oa (; 29 ;) (param $0 i32) (result i32) + (func $Oa (; 29 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9480,7 +9480,7 @@ ) (get_local $0) ) - (func $Pa (; 30 ;) (param $0 i32) (result i32) + (func $Pa (; 30 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9499,7 +9499,7 @@ (get_local $0) ) ) - (func $Qa (; 31 ;) (result i32) + (func $Qa (; 31 ;) (; has Stack IR ;) (result i32) (if (result i32) (i32.load (i32.const 1160) @@ -9510,7 +9510,7 @@ (i32.const 1204) ) ) - (func $lb (; 32 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $lb (; 32 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9524,7 +9524,7 @@ ) ) ) - (func $Ea (; 33 ;) (param $0 i32) (result i32) + (func $Ea (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9546,13 +9546,13 @@ ) (get_local $1) ) - (func $ob (; 34 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $ob (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $ja (i32.const 1) ) (i32.const 0) ) - (func $Ia (; 35 ;) (param $0 i32) (param $1 i32) + (func $Ia (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $v) @@ -9567,7 +9567,7 @@ ) ) ) - (func $kb (; 36 ;) (param $0 i32) (param $1 i32) (result i32) + (func $kb (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9576,14 +9576,14 @@ ) ) ) - (func $Sa (; 37 ;) (param $0 i32) + (func $Sa (; 37 ;) (; has Stack IR ;) (param $0 i32) (drop (i32.load offset=68 (get_local $0) ) ) ) - (func $mb (; 38 ;) (param $0 i32) (param $1 i32) + (func $mb (; 38 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9595,7 +9595,7 @@ ) ) ) - (func $Ha (; 39 ;) (param $0 i32) (param $1 i32) + (func $Ha (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $r (get_local $0) ) @@ -9603,13 +9603,13 @@ (get_local $1) ) ) - (func $nb (; 40 ;) (param $0 i32) (result i32) + (func $nb (; 40 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $ja (i32.const 0) ) (i32.const 0) ) - (func $Na (; 41 ;) (result i32) + (func $Na (; 41 ;) (; has Stack IR ;) (result i32) (drop (call $db (i32.const 1144) @@ -9617,28 +9617,28 @@ ) (i32.const 0) ) - (func $pb (; 42 ;) (param $0 i32) + (func $pb (; 42 ;) (; has Stack IR ;) (param $0 i32) (call $ja (i32.const 2) ) ) - (func $La (; 43 ;) (param $0 i32) + (func $La (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $K (get_local $0) ) ) - (func $Ga (; 44 ;) (param $0 i32) + (func $Ga (; 44 ;) (; has Stack IR ;) (param $0 i32) (set_global $r (get_local $0) ) ) - (func $Ma (; 45 ;) (result i32) + (func $Ma (; 45 ;) (; has Stack IR ;) (result i32) (get_global $K) ) - (func $Fa (; 46 ;) (result i32) + (func $Fa (; 46 ;) (; has Stack IR ;) (result i32) (get_global $r) ) - (func $ib (; 47 ;) (result i32) + (func $ib (; 47 ;) (; has Stack IR ;) (result i32) (i32.const 0) ) ) diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise index 5512eab04..c71b3b697 100644 --- a/test/memorygrowth.fromasm.imprecise +++ b/test/memorygrowth.fromasm.imprecise @@ -48,12 +48,12 @@ (export "dynCall_ii" (func $kb)) (export "dynCall_iiii" (func $lb)) (export "dynCall_vi" (func $mb)) - (func $__growWasmMemory (; 12 ;) (param $0 i32) (result i32) + (func $__growWasmMemory (; 12 ;) (; has Stack IR ;) (param $0 i32) (result i32) (grow_memory (get_local $0) ) ) - (func $eb (; 13 ;) (param $0 i32) (result i32) + (func $eb (; 13 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -5875,7 +5875,7 @@ (i32.const 8) ) ) - (func $fb (; 14 ;) (param $0 i32) + (func $fb (; 14 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -7696,7 +7696,7 @@ (i32.const -1) ) ) - (func $Ra (; 15 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ra (; 15 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8070,7 +8070,7 @@ ) (get_local $15) ) - (func $Wa (; 16 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Wa (; 16 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -8282,7 +8282,7 @@ ) (get_local $4) ) - (func $Za (; 17 ;) (param $0 i32) (result i32) + (func $Za (; 17 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8426,7 +8426,7 @@ (get_local $3) ) ) - (func $_a (; 18 ;) (param $0 i32) (result i32) + (func $_a (; 18 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (tee_local $1 @@ -8525,7 +8525,7 @@ ) ) ) - (func $ab (; 19 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ab (; 19 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -8674,7 +8674,7 @@ ) (get_local $4) ) - (func $$a (; 20 ;) (param $0 i32) (result i32) + (func $$a (; 20 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -8809,7 +8809,7 @@ ) (get_local $2) ) - (func $jb (; 21 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $jb (; 21 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if (i32.ge_s @@ -8956,10 +8956,10 @@ ) (get_local $3) ) - (func $gb (; 22 ;) + (func $gb (; 22 ;) (; has Stack IR ;) (nop) ) - (func $hb (; 23 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $hb (; 23 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -9097,7 +9097,7 @@ (get_local $2) ) ) - (func $db (; 24 ;) (param $0 i32) (result i32) + (func $db (; 24 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (drop @@ -9187,7 +9187,7 @@ (i32.const 31) ) ) - (func $Xa (; 25 ;) (param $0 i32) (result i32) + (func $Xa (; 25 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (set_local $2 @@ -9265,7 +9265,7 @@ ) ) ) - (func $bb (; 26 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $bb (; 26 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) (set_local $4 (i32.mul @@ -9293,7 +9293,7 @@ ) (get_local $2) ) - (func $Ua (; 27 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Ua (; 27 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9362,7 +9362,7 @@ ) (get_local $0) ) - (func $Va (; 28 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $Va (; 28 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (set_local $4 @@ -9432,7 +9432,7 @@ ) (get_local $3) ) - (func $Oa (; 29 ;) (param $0 i32) (result i32) + (func $Oa (; 29 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9462,7 +9462,7 @@ ) (get_local $0) ) - (func $Pa (; 30 ;) (param $0 i32) (result i32) + (func $Pa (; 30 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (result i32) (i32.gt_u (get_local $0) @@ -9481,7 +9481,7 @@ (get_local $0) ) ) - (func $Qa (; 31 ;) (result i32) + (func $Qa (; 31 ;) (; has Stack IR ;) (result i32) (select (i32.load (i32.const 64) @@ -9492,7 +9492,7 @@ ) ) ) - (func $lb (; 32 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $lb (; 32 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (call_indirect (type $FUNCSIG$iiii) (get_local $1) (get_local $2) @@ -9506,7 +9506,7 @@ ) ) ) - (func $Ea (; 33 ;) (param $0 i32) (result i32) + (func $Ea (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (set_local $1 (get_global $r) @@ -9528,13 +9528,13 @@ ) (get_local $1) ) - (func $ob (; 34 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $ob (; 34 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (call $ja (i32.const 1) ) (i32.const 0) ) - (func $Ia (; 35 ;) (param $0 i32) (param $1 i32) + (func $Ia (; 35 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (if (i32.eqz (get_global $v) @@ -9549,7 +9549,7 @@ ) ) ) - (func $kb (; 36 ;) (param $0 i32) (param $1 i32) (result i32) + (func $kb (; 36 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call_indirect (type $FUNCSIG$ii) (get_local $1) (i32.and @@ -9558,10 +9558,10 @@ ) ) ) - (func $Sa (; 37 ;) (param $0 i32) + (func $Sa (; 37 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $mb (; 38 ;) (param $0 i32) (param $1 i32) + (func $mb (; 38 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (call_indirect (type $FUNCSIG$vi) (get_local $1) (i32.add @@ -9573,7 +9573,7 @@ ) ) ) - (func $Ha (; 39 ;) (param $0 i32) (param $1 i32) + (func $Ha (; 39 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (set_global $r (get_local $0) ) @@ -9581,13 +9581,13 @@ (get_local $1) ) ) - (func $nb (; 40 ;) (param $0 i32) (result i32) + (func $nb (; 40 ;) (; has Stack IR ;) (param $0 i32) (result i32) (call $ja (i32.const 0) ) (i32.const 0) ) - (func $Na (; 41 ;) (result i32) + (func $Na (; 41 ;) (; has Stack IR ;) (result i32) (drop (call $db (i32.const 1144) @@ -9595,28 +9595,28 @@ ) (i32.const 0) ) - (func $pb (; 42 ;) (param $0 i32) + (func $pb (; 42 ;) (; has Stack IR ;) (param $0 i32) (call $ja (i32.const 2) ) ) - (func $La (; 43 ;) (param $0 i32) + (func $La (; 43 ;) (; has Stack IR ;) (param $0 i32) (set_global $K (get_local $0) ) ) - (func $Ga (; 44 ;) (param $0 i32) + (func $Ga (; 44 ;) (; has Stack IR ;) (param $0 i32) (set_global $r (get_local $0) ) ) - (func $Ma (; 45 ;) (result i32) + (func $Ma (; 45 ;) (; has Stack IR ;) (result i32) (get_global $K) ) - (func $Fa (; 46 ;) (result i32) + (func $Fa (; 46 ;) (; has Stack IR ;) (result i32) (get_global $r) ) - (func $ib (; 47 ;) (result i32) + (func $ib (; 47 ;) (; has Stack IR ;) (result i32) (i32.const 0) ) ) diff --git a/test/min.fromasm b/test/min.fromasm index 1f68b2acf..d46362b92 100644 --- a/test/min.fromasm +++ b/test/min.fromasm @@ -8,16 +8,16 @@ (export "neg" (func $legalstub$neg)) (export "bitcasts" (func $legalstub$bitcasts)) (export "ctzzzz" (func $ctzzzz)) - (func $ctzzzz (; 0 ;) (result i32) + (func $ctzzzz (; 0 ;) (; has Stack IR ;) (result i32) (i32.const 2) ) - (func $ub (; 1 ;) (result i32) + (func $ub (; 1 ;) (; has Stack IR ;) (result i32) (drop (call $ub) ) (get_global $M) ) - (func $legalstub$floats (; 2 ;) (param $0 f64) (result f64) + (func $legalstub$floats (; 2 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.promote/f32 (f32.add (f32.const 0) @@ -27,7 +27,7 @@ ) ) ) - (func $legalstub$neg (; 3 ;) (param $0 i32) (param $1 i32) (result f64) + (func $legalstub$neg (; 3 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result f64) (i32.store (get_local $0) (get_local $1) @@ -40,7 +40,7 @@ ) ) ) - (func $legalstub$bitcasts (; 4 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 4 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) ) diff --git a/test/min.fromasm.clamp b/test/min.fromasm.clamp index 1f68b2acf..d46362b92 100644 --- a/test/min.fromasm.clamp +++ b/test/min.fromasm.clamp @@ -8,16 +8,16 @@ (export "neg" (func $legalstub$neg)) (export "bitcasts" (func $legalstub$bitcasts)) (export "ctzzzz" (func $ctzzzz)) - (func $ctzzzz (; 0 ;) (result i32) + (func $ctzzzz (; 0 ;) (; has Stack IR ;) (result i32) (i32.const 2) ) - (func $ub (; 1 ;) (result i32) + (func $ub (; 1 ;) (; has Stack IR ;) (result i32) (drop (call $ub) ) (get_global $M) ) - (func $legalstub$floats (; 2 ;) (param $0 f64) (result f64) + (func $legalstub$floats (; 2 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.promote/f32 (f32.add (f32.const 0) @@ -27,7 +27,7 @@ ) ) ) - (func $legalstub$neg (; 3 ;) (param $0 i32) (param $1 i32) (result f64) + (func $legalstub$neg (; 3 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result f64) (i32.store (get_local $0) (get_local $1) @@ -40,7 +40,7 @@ ) ) ) - (func $legalstub$bitcasts (; 4 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 4 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) ) diff --git a/test/min.fromasm.imprecise b/test/min.fromasm.imprecise index 444551428..997d2fbf0 100644 --- a/test/min.fromasm.imprecise +++ b/test/min.fromasm.imprecise @@ -6,16 +6,16 @@ (export "neg" (func $legalstub$neg)) (export "bitcasts" (func $legalstub$bitcasts)) (export "ctzzzz" (func $ctzzzz)) - (func $ctzzzz (; 0 ;) (result i32) + (func $ctzzzz (; 0 ;) (; has Stack IR ;) (result i32) (i32.const 2) ) - (func $ub (; 1 ;) (result i32) + (func $ub (; 1 ;) (; has Stack IR ;) (result i32) (drop (call $ub) ) (get_global $M) ) - (func $legalstub$floats (; 2 ;) (param $0 f64) (result f64) + (func $legalstub$floats (; 2 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.promote/f32 (f32.add (f32.const 0) @@ -25,7 +25,7 @@ ) ) ) - (func $legalstub$neg (; 3 ;) (param $0 i32) (param $1 i32) (result f64) + (func $legalstub$neg (; 3 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result f64) (i32.store (get_local $0) (get_local $1) @@ -38,7 +38,7 @@ ) ) ) - (func $legalstub$bitcasts (; 4 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 4 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) ) diff --git a/test/noffi_f32.fromasm b/test/noffi_f32.fromasm index 00ca4dc3d..ae0b26a6d 100644 --- a/test/noffi_f32.fromasm +++ b/test/noffi_f32.fromasm @@ -6,13 +6,13 @@ (data (get_global $memoryBase) "noffi_f32.asm.js") (export "main" (func $main)) (export "exportf" (func $exportf)) - (func $exportf (; 1 ;) (param $0 f32) (result f32) + (func $exportf (; 1 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.add (get_local $0) (f32.const 1) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importf (f32.const 3.4000000953674316) diff --git a/test/noffi_f32.fromasm.clamp b/test/noffi_f32.fromasm.clamp index 00ca4dc3d..ae0b26a6d 100644 --- a/test/noffi_f32.fromasm.clamp +++ b/test/noffi_f32.fromasm.clamp @@ -6,13 +6,13 @@ (data (get_global $memoryBase) "noffi_f32.asm.js") (export "main" (func $main)) (export "exportf" (func $exportf)) - (func $exportf (; 1 ;) (param $0 f32) (result f32) + (func $exportf (; 1 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.add (get_local $0) (f32.const 1) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importf (f32.const 3.4000000953674316) diff --git a/test/noffi_f32.fromasm.imprecise b/test/noffi_f32.fromasm.imprecise index 85fc2b07c..60d6df1d1 100644 --- a/test/noffi_f32.fromasm.imprecise +++ b/test/noffi_f32.fromasm.imprecise @@ -3,13 +3,13 @@ (import "env" "_importf" (func $importf (param f32) (result f32))) (export "main" (func $main)) (export "exportf" (func $exportf)) - (func $exportf (; 1 ;) (param $0 f32) (result f32) + (func $exportf (; 1 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.add (get_local $0) (f32.const 1) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importf (f32.const 3.4000000953674316) diff --git a/test/noffi_i64.fromasm b/test/noffi_i64.fromasm index 1254149fa..69fbe532b 100644 --- a/test/noffi_i64.fromasm +++ b/test/noffi_i64.fromasm @@ -6,13 +6,13 @@ (data (get_global $memoryBase) "noffi_i64.asm.js") (export "_add" (func $add)) (export "_main" (func $main)) - (func $add (; 1 ;) (param $0 i64) (param $1 i64) (result i64) + (func $add (; 1 ;) (; has Stack IR ;) (param $0 i64) (param $1 i64) (result i64) (i64.add (get_local $1) (get_local $0) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importll (i64.const 2) diff --git a/test/noffi_i64.fromasm.clamp b/test/noffi_i64.fromasm.clamp index 1254149fa..69fbe532b 100644 --- a/test/noffi_i64.fromasm.clamp +++ b/test/noffi_i64.fromasm.clamp @@ -6,13 +6,13 @@ (data (get_global $memoryBase) "noffi_i64.asm.js") (export "_add" (func $add)) (export "_main" (func $main)) - (func $add (; 1 ;) (param $0 i64) (param $1 i64) (result i64) + (func $add (; 1 ;) (; has Stack IR ;) (param $0 i64) (param $1 i64) (result i64) (i64.add (get_local $1) (get_local $0) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importll (i64.const 2) diff --git a/test/noffi_i64.fromasm.imprecise b/test/noffi_i64.fromasm.imprecise index 8eb41d2b8..7cdc838fb 100644 --- a/test/noffi_i64.fromasm.imprecise +++ b/test/noffi_i64.fromasm.imprecise @@ -3,13 +3,13 @@ (import "env" "_importll" (func $importll (param i64) (result i64))) (export "_add" (func $add)) (export "_main" (func $main)) - (func $add (; 1 ;) (param $0 i64) (param $1 i64) (result i64) + (func $add (; 1 ;) (; has Stack IR ;) (param $0 i64) (param $1 i64) (result i64) (i64.add (get_local $1) (get_local $0) ) ) - (func $main (; 2 ;) (result i32) + (func $main (; 2 ;) (; has Stack IR ;) (result i32) (drop (call $importll (i64.const 2) diff --git a/test/passes/O.bin.txt b/test/passes/O.bin.txt index d1f85899f..ae3bda836 100644 --- a/test/passes/O.bin.txt +++ b/test/passes/O.bin.txt @@ -5,7 +5,7 @@ (export "fac-iter" (func $2)) (export "fac-iter-named" (func $3)) (export "fac-opt" (func $4)) - (func $0 (; 0 ;) (type $0) (param $0 i64) (result i64) + (func $0 (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i64) (result i64) (if (result i64) (i64.eq (get_local $0) @@ -23,7 +23,7 @@ ) ) ) - (func $1 (; 1 ;) (type $0) (param $0 i64) (result i64) + (func $1 (; 1 ;) (; has Stack IR ;) (type $0) (param $0 i64) (result i64) (if (result i64) (i64.eq (get_local $0) @@ -41,10 +41,10 @@ ) ) ) - (func $2 (; 2 ;) (type $0) (param $0 i64) (result i64) + (func $2 (; 2 ;) (; has Stack IR ;) (type $0) (param $0 i64) (result i64) (unreachable) ) - (func $3 (; 3 ;) (type $0) (param $0 i64) (result i64) + (func $3 (; 3 ;) (; has Stack IR ;) (type $0) (param $0 i64) (result i64) (local $1 i64) (set_local $1 (i64.const 1) @@ -74,7 +74,7 @@ ) (get_local $1) ) - (func $4 (; 4 ;) (type $0) (param $0 i64) (result i64) + (func $4 (; 4 ;) (; has Stack IR ;) (type $0) (param $0 i64) (result i64) (local $1 i64) (set_local $1 (i64.const 1) diff --git a/test/passes/O.txt b/test/passes/O.txt index 390f0783b..dcf9257c3 100644 --- a/test/passes/O.txt +++ b/test/passes/O.txt @@ -3,7 +3,7 @@ (type $1 (func (param i64))) (export "ret" (func $ret)) (export "waka" (func $if-0-unreachable-to-none)) - (func $ret (; 0 ;) (type $0) (result i32) + (func $ret (; 0 ;) (; has Stack IR ;) (type $0) (result i32) (block $out (result i32) (drop (call $ret) @@ -17,7 +17,7 @@ (i32.const 999) ) ) - (func $if-0-unreachable-to-none (; 1 ;) (type $1) (param $0 i64) + (func $if-0-unreachable-to-none (; 1 ;) (; has Stack IR ;) (type $1) (param $0 i64) (unreachable) ) ) diff --git a/test/passes/O1_print-stack-ir.txt b/test/passes/O1_print-stack-ir.txt new file mode 100644 index 000000000..ab3bf9255 --- /dev/null +++ b/test/passes/O1_print-stack-ir.txt @@ -0,0 +1,29 @@ +$stacky-help: + (no stack ir) +(module + (type $0 (func (param i32) (result i32))) + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (; 0 ;) (type $0) (param $0 i32) (result i32) + (local $1 i32) + (i32.add + (call $stacky-help + (i32.const 0) + ) + (block (result i32) + (set_local $1 + (call $stacky-help + (i32.const 1) + ) + ) + (drop + (call $stacky-help + (i32.const 2) + ) + ) + (i32.eqz + (get_local $1) + ) + ) + ) + ) +) diff --git a/test/passes/O1_print-stack-ir.wast b/test/passes/O1_print-stack-ir.wast new file mode 100644 index 000000000..a53d9d51e --- /dev/null +++ b/test/passes/O1_print-stack-ir.wast @@ -0,0 +1,16 @@ +(module + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $stacky-help (i32.const 0)) + (i32.eqz + (block (result i32) ;; after we use the stack instead of the local, we can remove this block + (set_local $temp (call $stacky-help (i32.const 1))) + (drop (call $stacky-help (i32.const 2))) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/O2_precompute-propagate_print-stack-ir.txt b/test/passes/O2_precompute-propagate_print-stack-ir.txt new file mode 100644 index 000000000..6c3ee8ee1 --- /dev/null +++ b/test/passes/O2_precompute-propagate_print-stack-ir.txt @@ -0,0 +1,16 @@ +$0: + (no stack ir) +(module + (type $0 (func (param i32 i32 i32 i64) (result i64))) + (export "func" (func $0)) + (func $0 (; 0 ;) (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i64) (result i64) + (local $4 i32) + (block $label$1 + (set_local $3 + (i64.const 2147483647) + ) + (nop) + ) + (i64.const 2147483647) + ) +) diff --git a/test/passes/O2_precompute-propagate_print-stack-ir.wast b/test/passes/O2_precompute-propagate_print-stack-ir.wast new file mode 100644 index 000000000..f6f0dae9f --- /dev/null +++ b/test/passes/O2_precompute-propagate_print-stack-ir.wast @@ -0,0 +1,18 @@ +(module + (func "func" (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) (param $var$3 i64) (result i64) + (local $var$4 i32) + (block $label$1 + (set_local $var$3 + (i64.const 2147483647) + ) + (br_if $label$1 + (get_local $var$4) ;; precompute-propagate will optimize this into 0, then the br_if is nopped + ;; in place. if stack ir is not regenerated, that means we have the get + ;; on the stack from before, and the br_if is now a nop, which means no one + ;; pops the get + ) + ) + (get_local $var$3) + ) +) + diff --git a/test/passes/O2_print-stack-ir.txt b/test/passes/O2_print-stack-ir.txt new file mode 100644 index 000000000..aa2a91528 --- /dev/null +++ b/test/passes/O2_print-stack-ir.txt @@ -0,0 +1,40 @@ +$stacky-help: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 set_local (none) +5 const (i32) +6 call (i32) +7 drop (none) +8 get_local (i32) +9 unary (i32) +10 binary (i32) + +(module + (type $0 (func (param i32) (result i32))) + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i32) (result i32) + (local $1 i32) + (i32.add + (call $stacky-help + (i32.const 0) + ) + (block (result i32) + (set_local $1 + (call $stacky-help + (i32.const 1) + ) + ) + (drop + (call $stacky-help + (i32.const 2) + ) + ) + (i32.eqz + (get_local $1) + ) + ) + ) + ) +) diff --git a/test/passes/O2_print-stack-ir.wast b/test/passes/O2_print-stack-ir.wast new file mode 100644 index 000000000..a53d9d51e --- /dev/null +++ b/test/passes/O2_print-stack-ir.wast @@ -0,0 +1,16 @@ +(module + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $stacky-help (i32.const 0)) + (i32.eqz + (block (result i32) ;; after we use the stack instead of the local, we can remove this block + (set_local $temp (call $stacky-help (i32.const 1))) + (drop (call $stacky-help (i32.const 2))) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/O3_print-stack-ir.txt b/test/passes/O3_print-stack-ir.txt new file mode 100644 index 000000000..ca1cc46ba --- /dev/null +++ b/test/passes/O3_print-stack-ir.txt @@ -0,0 +1,38 @@ +$stacky-help: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 const (i32) +5 call (i32) +6 drop (none) +7 unary (i32) +8 binary (i32) + +(module + (type $0 (func (param i32) (result i32))) + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i32) (result i32) + (local $1 i32) + (i32.add + (call $stacky-help + (i32.const 0) + ) + (block (result i32) + (set_local $1 + (call $stacky-help + (i32.const 1) + ) + ) + (drop + (call $stacky-help + (i32.const 2) + ) + ) + (i32.eqz + (get_local $1) + ) + ) + ) + ) +) diff --git a/test/passes/O3_print-stack-ir.wast b/test/passes/O3_print-stack-ir.wast new file mode 100644 index 000000000..a53d9d51e --- /dev/null +++ b/test/passes/O3_print-stack-ir.wast @@ -0,0 +1,16 @@ +(module + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $stacky-help (i32.const 0)) + (i32.eqz + (block (result i32) ;; after we use the stack instead of the local, we can remove this block + (set_local $temp (call $stacky-help (i32.const 1))) + (drop (call $stacky-help (i32.const 2))) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/O4.txt b/test/passes/O4.txt index 1939a740e..9a64b18ff 100644 --- a/test/passes/O4.txt +++ b/test/passes/O4.txt @@ -2,7 +2,7 @@ (type $0 (func)) (global $global$0 (mut i32) (i32.const 10)) (export "func_59_invoker" (func $0)) - (func $0 (; 0 ;) (type $0) + (func $0 (; 0 ;) (; has Stack IR ;) (type $0) (set_global $global$0 (i32.const 0) ) diff --git a/test/passes/Os_print-stack-ir.txt b/test/passes/Os_print-stack-ir.txt new file mode 100644 index 000000000..ca1cc46ba --- /dev/null +++ b/test/passes/Os_print-stack-ir.txt @@ -0,0 +1,38 @@ +$stacky-help: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 const (i32) +5 call (i32) +6 drop (none) +7 unary (i32) +8 binary (i32) + +(module + (type $0 (func (param i32) (result i32))) + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i32) (result i32) + (local $1 i32) + (i32.add + (call $stacky-help + (i32.const 0) + ) + (block (result i32) + (set_local $1 + (call $stacky-help + (i32.const 1) + ) + ) + (drop + (call $stacky-help + (i32.const 2) + ) + ) + (i32.eqz + (get_local $1) + ) + ) + ) + ) +) diff --git a/test/passes/Os_print-stack-ir.wast b/test/passes/Os_print-stack-ir.wast new file mode 100644 index 000000000..a53d9d51e --- /dev/null +++ b/test/passes/Os_print-stack-ir.wast @@ -0,0 +1,16 @@ +(module + (export "stacky-help" (func $stacky-help)) + (func $stacky-help (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $stacky-help (i32.const 0)) + (i32.eqz + (block (result i32) ;; after we use the stack instead of the local, we can remove this block + (set_local $temp (call $stacky-help (i32.const 1))) + (drop (call $stacky-help (i32.const 2))) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/Oz.txt b/test/passes/Oz.txt index 883ccc476..a59ac924b 100644 --- a/test/passes/Oz.txt +++ b/test/passes/Oz.txt @@ -4,7 +4,7 @@ (memory $0 100 100) (export "localcse" (func $basics)) (export "localcse-2" (func $8)) - (func $basics (; 0 ;) (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $basics (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i32) (param $1 i32) (result i32) (i32.add (i32.add (get_local $0) @@ -16,7 +16,7 @@ ) ) ) - (func $8 (; 1 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (func $8 (; 1 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (i32.store (tee_local $2 (i32.add diff --git a/test/passes/converge_O3_metrics.bin.txt b/test/passes/converge_O3_metrics.bin.txt index 47e01cdbe..a272a6288 100644 --- a/test/passes/converge_O3_metrics.bin.txt +++ b/test/passes/converge_O3_metrics.bin.txt @@ -42,13 +42,13 @@ total (data (i32.const 18764) "`\0b") (export "_main" (func $_main)) (export "_malloc" (func $_malloc)) - (func $b0 (; 1 ;) (type $6) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (result i32) + (func $b0 (; 1 ;) (; has Stack IR ;) (type $6) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (result i32) (i32.const 0) ) - (func $_malloc (; 2 ;) (type $2) (param $0 i32) (result i32) + (func $_malloc (; 2 ;) (; has Stack IR ;) (type $2) (param $0 i32) (result i32) (i32.const 0) ) - (func $___stdio_write (; 3 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 3 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (i32.store (i32.const 8) (get_local $1) @@ -79,7 +79,7 @@ total ) (i32.const 1) ) - (func $_main (; 4 ;) (type $7) (result i32) + (func $_main (; 4 ;) (; has Stack IR ;) (type $7) (result i32) (local $0 i32) (call $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (block (result i32) @@ -109,7 +109,7 @@ total ) (i32.const 0) ) - (func $___stdout_write (; 5 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 5 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (set_global $global$0 (i32.const 32) ) @@ -119,7 +119,7 @@ total (get_local $2) ) ) - (func $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (; 6 ;) (type $3) (param $0 i32) + (func $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (; 6 ;) (; has Stack IR ;) (type $3) (param $0 i32) (local $1 i32) (set_local $1 (i32.load offset=24 @@ -157,7 +157,7 @@ total ) ) ) - (func $__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE3putEc (; 7 ;) (type $3) (param $0 i32) + (func $__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE3putEc (; 7 ;) (; has Stack IR ;) (type $3) (param $0 i32) (local $1 i32) (local $2 i32) (block $label$1 @@ -202,7 +202,7 @@ total ) ) ) - (func $__ZNSt3__211__stdoutbufIcE8overflowEi (; 8 ;) (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $__ZNSt3__211__stdoutbufIcE8overflowEi (; 8 ;) (; has Stack IR ;) (type $0) (param $0 i32) (param $1 i32) (result i32) (i32.store8 (i32.const 0) (get_local $1) @@ -227,7 +227,7 @@ total ) (i32.const 0) ) - (func $__ZNSt3__211__stdoutbufIcE6xsputnEPKci (; 9 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $__ZNSt3__211__stdoutbufIcE6xsputnEPKci (; 9 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (drop (call_indirect (type $1) (i32.const 0) @@ -290,13 +290,13 @@ total (data (i32.const 18764) "`\0b") (export "_main" (func $_main)) (export "_malloc" (func $_malloc)) - (func $b0 (; 1 ;) (type $6) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (result i32) + (func $b0 (; 1 ;) (; has Stack IR ;) (type $6) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (result i32) (i32.const 0) ) - (func $_malloc (; 2 ;) (type $2) (param $0 i32) (result i32) + (func $_malloc (; 2 ;) (; has Stack IR ;) (type $2) (param $0 i32) (result i32) (i32.const 0) ) - (func $___stdio_write (; 3 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdio_write (; 3 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (i32.store (i32.const 8) (get_local $1) @@ -327,7 +327,7 @@ total ) (i32.const 1) ) - (func $_main (; 4 ;) (type $7) (result i32) + (func $_main (; 4 ;) (; has Stack IR ;) (type $7) (result i32) (local $0 i32) (call $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (block (result i32) @@ -357,7 +357,7 @@ total ) (i32.const 0) ) - (func $___stdout_write (; 5 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $___stdout_write (; 5 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (set_global $global$0 (i32.const 32) ) @@ -367,7 +367,7 @@ total (get_local $2) ) ) - (func $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (; 6 ;) (type $3) (param $0 i32) + (func $__ZNSt3__224__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_j (; 6 ;) (; has Stack IR ;) (type $3) (param $0 i32) (local $1 i32) (set_local $1 (i32.load offset=24 @@ -405,7 +405,7 @@ total ) ) ) - (func $__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE3putEc (; 7 ;) (type $3) (param $0 i32) + (func $__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE3putEc (; 7 ;) (; has Stack IR ;) (type $3) (param $0 i32) (local $1 i32) (local $2 i32) (block $label$1 @@ -450,7 +450,7 @@ total ) ) ) - (func $__ZNSt3__211__stdoutbufIcE8overflowEi (; 8 ;) (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $__ZNSt3__211__stdoutbufIcE8overflowEi (; 8 ;) (; has Stack IR ;) (type $0) (param $0 i32) (param $1 i32) (result i32) (i32.store8 (i32.const 0) (get_local $1) @@ -475,7 +475,7 @@ total ) (i32.const 0) ) - (func $__ZNSt3__211__stdoutbufIcE6xsputnEPKci (; 9 ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $__ZNSt3__211__stdoutbufIcE6xsputnEPKci (; 9 ;) (; has Stack IR ;) (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (drop (call_indirect (type $1) (i32.const 0) diff --git a/test/passes/flatten_local-cse_Os.txt b/test/passes/flatten_local-cse_Os.txt index 85bc4d6f5..4c95a1df5 100644 --- a/test/passes/flatten_local-cse_Os.txt +++ b/test/passes/flatten_local-cse_Os.txt @@ -1,7 +1,7 @@ (module (type $0 (func (param i32 i32) (result i32))) (export "div16_internal" (func $0)) - (func $0 (; 0 ;) (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $0 (; 0 ;) (; has Stack IR ;) (type $0) (param $0 i32) (param $1 i32) (result i32) (i32.add (tee_local $0 (i32.xor diff --git a/test/passes/fuzz-exec_O.txt b/test/passes/fuzz-exec_O.txt index 8ebd35fa1..dd90a838c 100644 --- a/test/passes/fuzz-exec_O.txt +++ b/test/passes/fuzz-exec_O.txt @@ -7,7 +7,7 @@ (memory $0 1 1) (export "func_0" (func $func_0)) (export "func_1" (func $func_1)) - (func $func_0 (; 0 ;) (type $0) (result i64) + (func $func_0 (; 0 ;) (; has Stack IR ;) (type $0) (result i64) (block $label$0 (result i64) (br_if $label$0 (i64.const 1234) @@ -17,7 +17,7 @@ ) ) ) - (func $func_1 (; 1 ;) (type $1) (result i32) + (func $func_1 (; 1 ;) (; has Stack IR ;) (type $1) (result i32) (i32.load16_s offset=22 align=1 (i32.const -1) ) diff --git a/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.txt b/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.txt new file mode 100644 index 000000000..11c33366c --- /dev/null +++ b/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.txt @@ -0,0 +1,1540 @@ +$big_negative: +0 const (f64) +1 set_local (none) +2 const (f64) +3 set_local (none) +4 const (f64) +5 set_local (none) +6 const (f64) +7 set_local (none) +8 const (f64) +9 set_local (none) + +$importedDoubles: +0 block +1 const (i32) +2 load (f64) +3 const (i32) +4 load (f64) +5 binary (f64) +6 const (i32) +7 load (f64) +8 unary (f64) +9 binary (f64) +10 const (i32) +11 load (f64) +12 unary (f64) +13 binary (f64) +14 set_local (none) +15 const (i32) +16 load (i32) +17 const (i32) +18 binary (i32) +19 if +20 const (f64) +21 break (unreachable) +22 end (none) +23 const (i32) +24 load (f64) +25 const (f64) +26 binary (i32) +27 if +28 const (f64) +29 break (unreachable) +30 end (none) +31 const (f64) +32 end (f64) + +$doubleCompares: +0 block +1 get_local (f64) +2 const (f64) +3 binary (i32) +4 if +5 const (f64) +6 break (unreachable) +7 end (none) +8 get_local (f64) +9 const (f64) +10 binary (i32) +11 if +12 const (f64) +13 break (unreachable) +14 end (none) +15 get_local (i32) +16 const (i32) +17 binary (i32) +18 if +19 const (f64) +20 break (unreachable) +21 end (none) +22 get_local (f64) +23 get_local (f64) +24 binary (i32) +25 if +26 get_local (f64) +27 break (unreachable) +28 end (none) +29 get_local (f64) +30 end (f64) + +$intOps: +0 get_local (i32) +1 const (i32) +2 binary (i32) + +$hexLiterals: +0 const (i32) +1 const (i32) +2 binary (i32) +3 const (i32) +4 binary (i32) +5 drop (none) + +$conversions: +0 get_local (f64) +1 call_import (i32) +2 set_local (none) +3 get_local (i32) +4 unary (f64) +5 set_local (none) +6 get_local (i32) +7 const (i32) +8 binary (i32) +9 unary (f64) +10 set_local (none) + +$seq: +0 const (f64) +1 drop (none) +2 const (f64) +3 const (f64) +4 drop (none) +5 const (f64) +6 binary (f64) +7 set_local (none) + +$switcher: +0 block +1 block +2 block +3 block +4 get_local (i32) +5 const (i32) +6 binary (i32) +7 switch (unreachable) +8 end (none) +9 const (i32) +10 break (unreachable) +11 end (none) +12 const (i32) +13 break (unreachable) +14 end (none) +15 nop (none) +16 block +17 block +18 block +19 get_local (i32) +20 const (i32) +21 binary (i32) +22 switch (unreachable) +23 end (none) +24 const (i32) +25 break (unreachable) +26 end (none) +27 const (i32) +28 break (unreachable) +29 end (none) +30 nop (none) +31 block +32 block +33 block +34 block +35 block +36 block +37 get_local (i32) +38 const (i32) +39 binary (i32) +40 switch (unreachable) +41 end (none) +42 break (unreachable) +43 end (none) +44 break (unreachable) +45 end (none) +46 block +47 loop +48 break (unreachable) +49 end (none) +50 unreachable (unreachable) +51 end (none) +52 end (none) +53 loop +54 break (unreachable) +55 end (none) +56 unreachable (unreachable) +57 end (none) +58 nop (none) +59 end (none) +60 const (i32) +61 end (i32) + +$blocker: +0 block +1 break (unreachable) +2 end (none) + +$frem: +0 const (f64) +1 const (f64) +2 call_import (f64) + +$big_uint_div_u: +0 const (i32) +1 const (i32) +2 binary (i32) +3 const (i32) +4 binary (i32) + +$fr: +0 get_local (f64) +1 unary (f32) +2 drop (none) +3 get_local (f32) +4 drop (none) +5 const (f32) +6 drop (none) +7 const (f32) +8 drop (none) +9 const (f32) +10 drop (none) +11 const (f32) +12 drop (none) + +$negZero: +0 const (f64) + +$abs: +0 const (i32) +1 set_local (none) +2 const (i32) +3 get_local (i32) +4 binary (i32) +5 get_local (i32) +6 get_local (i32) +7 const (i32) +8 binary (i32) +9 select (i32) +10 set_local (none) +11 const (f64) +12 unary (f64) +13 set_local (none) +14 const (f32) +15 unary (f32) +16 set_local (none) + +$neg: +0 get_local (f32) +1 unary (f32) +2 const (i32) +3 const (i32) +4 binary (i32) +5 const (i32) +6 binary (i32) +7 call_indirect (none) + +$cneg: +0 get_local (f32) +1 const (i32) +2 const (i32) +3 binary (i32) +4 const (i32) +5 binary (i32) +6 call_indirect (none) + +$___syscall_ret: +0 get_local (i32) +1 const (i32) +2 binary (i32) +3 const (i32) +4 binary (i32) +5 drop (none) + +$z: +0 nop (none) + +$w: +0 nop (none) + +$block_and_after: +0 block +1 const (i32) +2 drop (none) +3 break (unreachable) +4 end (none) +5 const (i32) + +$loop-roundtrip: +0 loop +1 get_local (f64) +2 drop (none) +3 get_local (f64) +4 end (f64) + +$big-i64: +0 const (i64) + +$i64-store32: +0 get_local (i32) +1 get_local (i64) +2 store (none) + +$return-unreachable: +0 const (i32) +1 return (unreachable) + +$unreachable-block: +0 const (i32) +1 drop (none) +2 const (i32) +3 return (unreachable) + +$unreachable-block-toplevel: +0 const (i32) +1 drop (none) +2 const (i32) +3 return (unreachable) + +$unreachable-block0: +0 const (i32) +1 return (unreachable) + +$unreachable-block0-toplevel: +0 const (i32) +1 return (unreachable) + +$unreachable-block-with-br: +0 block +1 const (i32) +2 drop (none) +3 break (unreachable) +4 end (none) +5 const (i32) + +$unreachable-if: +0 const (i32) +1 if +2 const (i32) +3 return (unreachable) +4 else +5 const (i32) +6 return (unreachable) +7 end (none) +8 unreachable (unreachable) + +$unreachable-if-toplevel: +0 const (i32) +1 if +2 const (i32) +3 return (unreachable) +4 else +5 const (i32) +6 return (unreachable) +7 end (none) +8 unreachable (unreachable) + +$unreachable-loop: +0 loop +1 nop (none) +2 const (i32) +3 return (unreachable) +4 end (none) +5 unreachable (unreachable) + +$unreachable-loop0: +0 loop +1 const (i32) +2 return (unreachable) +3 end (none) +4 unreachable (unreachable) + +$unreachable-loop-toplevel: +0 loop +1 nop (none) +2 const (i32) +3 return (unreachable) +4 end (none) +5 unreachable (unreachable) + +$unreachable-loop0-toplevel: +0 loop +1 const (i32) +2 return (unreachable) +3 end (none) +4 unreachable (unreachable) + +$unreachable-ifs: +0 unreachable (unreachable) + +$unreachable-if-arm: +0 const (i32) +1 if +2 nop (none) +3 else +4 unreachable (unreachable) +5 end (none) + +$local-to-stack: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) + +$local-to-stack-1: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) +5 unary (i32) + +$local-to-stack-1b: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) +5 const (i32) +6 binary (i32) + +$local-to-stack-1c-no: +0 const (i32) +1 call (i32) +2 set_local (none) +3 const (i32) +4 call (i32) +5 drop (none) +6 const (i32) +7 get_local (i32) +8 binary (i32) + +$local-to-stack-2-no: +0 const (i32) +1 call (i32) +2 set_local (none) +3 const (i32) +4 call (i32) +5 drop (none) +6 get_local (i32) +7 get_local (i32) +8 binary (i32) + +$local-to-stack-3-no: +0 const (i32) +1 if +2 const (i32) +3 call (i32) +4 set_local (none) +5 else +6 const (i32) +7 call (i32) +8 set_local (none) +9 end (none) +10 const (i32) +11 call (i32) +12 drop (none) +13 get_local (i32) + +$local-to-stack-multi-4: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) +5 drop (none) +6 const (i32) +7 call (i32) +8 const (i32) +9 call (i32) +10 drop (none) + +$local-to-stack-multi-5: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) +5 drop (none) +6 const (i32) +7 call (i32) +8 const (i32) +9 call (i32) +10 drop (none) + +$local-to-stack-multi-6-justone: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 drop (none) +5 drop (none) +6 const (i32) +7 call (i32) +8 set_local (none) +9 const (i32) +10 call (i32) +11 drop (none) +12 get_local (i32) +13 get_local (i32) +14 binary (i32) + +$local-to-stack-multi-7-justone: +0 const (i32) +1 call (i32) +2 set_local (none) +3 const (i32) +4 call (i32) +5 drop (none) +6 get_local (i32) +7 get_local (i32) +8 binary (i32) +9 drop (none) +10 const (i32) +11 call (i32) +12 const (i32) +13 call (i32) +14 drop (none) + +$local-to-stack-overlapping-multi-8-no: +0 const (i32) +1 call (i32) +2 set_local (none) +3 const (i32) +4 call (i32) +5 const (i32) +6 call (i32) +7 drop (none) +8 get_local (i32) +9 binary (i32) + +$local-to-stack-overlapping-multi-9-yes: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 const (i32) +5 call (i32) +6 drop (none) +7 binary (i32) + +$local-to-stack-through-control-flow: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 const (i32) +5 if +6 nop (none) +7 end (none) +8 drop (none) +9 const (i32) +10 call (i32) +11 block +12 break (unreachable) +13 end (none) +14 drop (none) +15 drop (none) + +$local-to-stack-in-control-flow: +0 const (i32) +1 if +2 const (i32) +3 call (i32) +4 drop (none) +5 else +6 const (i32) +7 call (i32) +8 drop (none) +9 end (none) + +$remove-block: +0 const (i32) +1 call (i32) +2 const (i32) +3 call (i32) +4 const (i32) +5 call (i32) +6 drop (none) +7 unary (i32) +8 binary (i32) + +(module + (type $FUNCSIG$vf (func (param f32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$id (func (param f64) (result i32))) + (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + (type $4 (func (result f64))) + (type $5 (func (result i32))) + (type $6 (func (param i32) (result i32))) + (type $7 (func (param f64) (result f64))) + (type $8 (func (result i64))) + (type $9 (func (param i32 i64))) + (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) + (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) + (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) + (table 10 anyfunc) + (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (memory $0 4096 4096) + (data (i32.const 1026) "\14\00") + (export "big_negative" (func $big_negative)) + (func $big_negative (; 3 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $temp f64) + (block $block0 + (set_local $temp + (f64.const -2147483648) + ) + (set_local $temp + (f64.const -2147483648) + ) + (set_local $temp + (f64.const -21474836480) + ) + (set_local $temp + (f64.const 0.039625) + ) + (set_local $temp + (f64.const -0.039625) + ) + ) + ) + (func $importedDoubles (; 4 ;) (; has Stack IR ;) (type $4) (result f64) + (local $temp f64) + (block $topmost (result f64) + (set_local $temp + (f64.add + (f64.add + (f64.add + (f64.load + (i32.const 8) + ) + (f64.load + (i32.const 16) + ) + ) + (f64.neg + (f64.load + (i32.const 16) + ) + ) + ) + (f64.neg + (f64.load + (i32.const 8) + ) + ) + ) + ) + (if + (i32.gt_s + (i32.load + (i32.const 24) + ) + (i32.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (f64.gt + (f64.load + (i32.const 32) + ) + (f64.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (f64.const 1.2) + ) + ) + (func $doubleCompares (; 5 ;) (; has Stack IR ;) (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) + (local $t f64) + (local $Int f64) + (local $Double i32) + (block $topmost (result f64) + (if + (f64.gt + (get_local $x) + (f64.const 0) + ) + (br $topmost + (f64.const 1.2) + ) + ) + (if + (f64.gt + (get_local $Int) + (f64.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (i32.gt_s + (get_local $Double) + (i32.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (if + (f64.lt + (get_local $x) + (get_local $y) + ) + (br $topmost + (get_local $x) + ) + ) + (get_local $y) + ) + ) + (func $intOps (; 6 ;) (; has Stack IR ;) (type $5) (result i32) + (local $x i32) + (i32.eq + (get_local $x) + (i32.const 0) + ) + ) + (func $hexLiterals (; 7 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (drop + (i32.add + (i32.add + (i32.const 0) + (i32.const 313249263) + ) + (i32.const -19088752) + ) + ) + ) + (func $conversions (; 8 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $i i32) + (local $d f64) + (block $block0 + (set_local $i + (call $f64-to-int + (get_local $d) + ) + ) + (set_local $d + (f64.convert_s/i32 + (get_local $i) + ) + ) + (set_local $d + (f64.convert_u/i32 + (i32.shr_u + (get_local $i) + (i32.const 0) + ) + ) + ) + ) + ) + (func $seq (; 9 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $J f64) + (set_local $J + (f64.sub + (block $block0 (result f64) + (drop + (f64.const 0.1) + ) + (f64.const 5.1) + ) + (block $block1 (result f64) + (drop + (f64.const 3.2) + ) + (f64.const 4.2) + ) + ) + ) + ) + (func $switcher (; 10 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (block $topmost (result i32) + (block $switch$0 + (block $switch-default$3 + (block $switch-case$2 + (block $switch-case$1 + (br_table $switch-case$1 $switch-case$2 $switch-default$3 + (i32.sub + (get_local $x) + (i32.const 1) + ) + ) + ) + (br $topmost + (i32.const 1) + ) + ) + (br $topmost + (i32.const 2) + ) + ) + (nop) + ) + (block $switch$4 + (block $switch-default$7 + (block $switch-case$6 + (block $switch-case$5 + (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 + (i32.sub + (get_local $x) + (i32.const 5) + ) + ) + ) + (br $topmost + (i32.const 121) + ) + ) + (br $topmost + (i32.const 51) + ) + ) + (nop) + ) + (block $label$break$Lout + (block $switch-default$16 + (block $switch-case$15 + (block $switch-case$12 + (block $switch-case$9 + (block $switch-case$8 + (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 + (i32.sub + (get_local $x) + (i32.const 2) + ) + ) + ) + (br $label$break$Lout) + ) + (br $label$break$Lout) + ) + (block $while-out$10 + (loop $while-in$11 + (block $block1 + (br $while-out$10) + (br $while-in$11) + ) + ) + (br $label$break$Lout) + ) + ) + (block $while-out$13 + (loop $while-in$14 + (block $block3 + (br $label$break$Lout) + (br $while-in$14) + ) + ) + (br $label$break$Lout) + ) + ) + (nop) + ) + (i32.const 0) + ) + ) + (func $blocker (; 11 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (block $label$break$L + (br $label$break$L) + ) + ) + (func $frem (; 12 ;) (; has Stack IR ;) (type $4) (result f64) + (call $f64-rem + (f64.const 5.5) + (f64.const 1.2) + ) + ) + (func $big_uint_div_u (; 13 ;) (; has Stack IR ;) (type $5) (result i32) + (local $x i32) + (block $topmost (result i32) + (set_local $x + (i32.and + (i32.div_u + (i32.const -1) + (i32.const 2) + ) + (i32.const -1) + ) + ) + (get_local $x) + ) + ) + (func $fr (; 14 ;) (; has Stack IR ;) (type $FUNCSIG$vf) (param $x f32) + (local $y f32) + (local $z f64) + (block $block0 + (drop + (f32.demote/f64 + (get_local $z) + ) + ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + ) + ) + (func $negZero (; 15 ;) (; has Stack IR ;) (type $4) (result f64) + (f64.const -0) + ) + (func $abs (; 16 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $x i32) + (local $y f64) + (local $z f32) + (local $asm2wasm_i32_temp i32) + (block $block0 + (set_local $x + (block $block1 (result i32) + (set_local $asm2wasm_i32_temp + (i32.const 0) + ) + (select + (i32.sub + (i32.const 0) + (get_local $asm2wasm_i32_temp) + ) + (get_local $asm2wasm_i32_temp) + (i32.lt_s + (get_local $asm2wasm_i32_temp) + (i32.const 0) + ) + ) + ) + ) + (set_local $y + (f64.abs + (f64.const 0) + ) + ) + (set_local $z + (f32.abs + (f32.const 0) + ) + ) + ) + ) + (func $neg (; 17 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $x f32) + (block $block0 + (set_local $x + (f32.neg + (get_local $x) + ) + ) + (call_indirect (type $FUNCSIG$vf) + (get_local $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + ) + (func $cneg (; 18 ;) (; has Stack IR ;) (type $FUNCSIG$vf) (param $x f32) + (call_indirect (type $FUNCSIG$vf) + (get_local $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + (func $___syscall_ret (; 19 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $$0 i32) + (drop + (i32.gt_u + (i32.shr_u + (get_local $$0) + (i32.const 0) + ) + (i32.const -4096) + ) + ) + ) + (func $z (; 20 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (nop) + ) + (func $w (; 21 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (nop) + ) + (func $block_and_after (; 22 ;) (; has Stack IR ;) (type $5) (result i32) + (block $waka + (drop + (i32.const 1) + ) + (br $waka) + ) + (i32.const 0) + ) + (func $loop-roundtrip (; 23 ;) (; has Stack IR ;) (type $7) (param $0 f64) (result f64) + (loop $loop-in1 (result f64) + (drop + (get_local $0) + ) + (get_local $0) + ) + ) + (func $big-i64 (; 24 ;) (; has Stack IR ;) (type $8) (result i64) + (i64.const -9218868437227405313) + ) + (func $i64-store32 (; 25 ;) (; has Stack IR ;) (type $9) (param $0 i32) (param $1 i64) + (i64.store32 + (get_local $0) + (get_local $1) + ) + ) + (func $return-unreachable (; 26 ;) (; has Stack IR ;) (type $5) (result i32) + (return + (i32.const 1) + ) + ) + (func $unreachable-block (; 27 ;) (; has Stack IR ;) (type $5) (result i32) + (f64.abs + (block $block + (drop + (i32.const 1) + ) + (return + (i32.const 2) + ) + ) + ) + ) + (func $unreachable-block-toplevel (; 28 ;) (; has Stack IR ;) (type $5) (result i32) + (block $block + (drop + (i32.const 1) + ) + (return + (i32.const 2) + ) + ) + ) + (func $unreachable-block0 (; 29 ;) (; has Stack IR ;) (type $5) (result i32) + (f64.abs + (block $block + (return + (i32.const 2) + ) + ) + ) + ) + (func $unreachable-block0-toplevel (; 30 ;) (; has Stack IR ;) (type $5) (result i32) + (block $block + (return + (i32.const 2) + ) + ) + ) + (func $unreachable-block-with-br (; 31 ;) (; has Stack IR ;) (type $5) (result i32) + (block $block + (drop + (i32.const 1) + ) + (br $block) + ) + (i32.const 1) + ) + (func $unreachable-if (; 32 ;) (; has Stack IR ;) (type $5) (result i32) + (f64.abs + (if + (i32.const 3) + (return + (i32.const 2) + ) + (return + (i32.const 1) + ) + ) + ) + ) + (func $unreachable-if-toplevel (; 33 ;) (; has Stack IR ;) (type $5) (result i32) + (if + (i32.const 3) + (return + (i32.const 2) + ) + (return + (i32.const 1) + ) + ) + ) + (func $unreachable-loop (; 34 ;) (; has Stack IR ;) (type $5) (result i32) + (f64.abs + (loop $loop-in + (nop) + (return + (i32.const 1) + ) + ) + ) + ) + (func $unreachable-loop0 (; 35 ;) (; has Stack IR ;) (type $5) (result i32) + (f64.abs + (loop $loop-in + (return + (i32.const 1) + ) + ) + ) + ) + (func $unreachable-loop-toplevel (; 36 ;) (; has Stack IR ;) (type $5) (result i32) + (loop $loop-in + (nop) + (return + (i32.const 1) + ) + ) + ) + (func $unreachable-loop0-toplevel (; 37 ;) (; has Stack IR ;) (type $5) (result i32) + (loop $loop-in + (return + (i32.const 1) + ) + ) + ) + (func $unreachable-ifs (; 38 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (if + (unreachable) + (nop) + ) + (if + (unreachable) + (unreachable) + ) + (if + (unreachable) + (nop) + (nop) + ) + (if + (unreachable) + (unreachable) + (nop) + ) + (if + (unreachable) + (nop) + (unreachable) + ) + (if + (unreachable) + (unreachable) + (unreachable) + ) + (if + (i32.const 1) + (unreachable) + (nop) + ) + (if + (i32.const 1) + (nop) + (unreachable) + ) + (if + (i32.const 1) + (unreachable) + (unreachable) + ) + ) + (func $unreachable-if-arm (; 39 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (if + (i32.const 1) + (block $block + (nop) + ) + (block $block12 + (unreachable) + (drop + (i32.const 1) + ) + ) + ) + ) + (func $local-to-stack (; 40 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (drop + (call $local-to-stack + (i32.const 2) + ) + ) + (get_local $temp) + ) + (func $local-to-stack-1 (; 41 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (drop + (call $local-to-stack + (i32.const 2) + ) + ) + (i32.eqz + (get_local $temp) + ) + ) + (func $local-to-stack-1b (; 42 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (drop + (call $local-to-stack + (i32.const 2) + ) + ) + (i32.add + (get_local $temp) + (i32.const 3) + ) + ) + (func $local-to-stack-1c-no (; 43 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (drop + (call $local-to-stack + (i32.const 2) + ) + ) + (i32.add + (i32.const 3) + (get_local $temp) + ) + ) + (func $local-to-stack-2-no (; 44 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (drop + (call $local-to-stack + (i32.const 2) + ) + ) + (i32.add + (get_local $temp) + (get_local $temp) + ) + ) + (func $local-to-stack-3-no (; 45 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (if + (i32.const 1) + (set_local $temp + (call $local-to-stack + (i32.const 1) + ) + ) + (set_local $temp + (call $local-to-stack + (i32.const 2) + ) + ) + ) + (drop + (call $local-to-stack + (i32.const 3) + ) + ) + (get_local $temp) + ) + (func $local-to-stack-multi-4 (; 46 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 2) + ) + ) + (drop + (get_local $temp1) + ) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 4) + ) + ) + (get_local $temp1) + ) + (func $local-to-stack-multi-5 (; 47 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 2) + ) + ) + (drop + (get_local $temp1) + ) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 4) + ) + ) + (get_local $temp2) + ) + (func $local-to-stack-multi-6-justone (; 48 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 2) + ) + ) + (drop + (get_local $temp1) + ) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 4) + ) + ) + (i32.add + (get_local $temp2) + (get_local $temp2) + ) + ) + (func $local-to-stack-multi-7-justone (; 49 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 2) + ) + ) + (drop + (i32.add + (get_local $temp1) + (get_local $temp1) + ) + ) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 4) + ) + ) + (get_local $temp2) + ) + (func $local-to-stack-overlapping-multi-8-no (; 50 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (i32.add + (get_local $temp2) + (get_local $temp1) + ) + ) + (func $local-to-stack-overlapping-multi-9-yes (; 51 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (call $local-to-stack-multi-4 + (i32.const 3) + ) + ) + (i32.add + (get_local $temp1) + (get_local $temp2) + ) + ) + (func $local-to-stack-through-control-flow (; 52 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp2 + (call $local-to-stack-multi-4 + (i32.const 0) + ) + ) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (if + (i32.const 0) + (nop) + ) + (drop + (get_local $temp1) + ) + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 2) + ) + ) + (block $block + (br $block) + ) + (drop + (get_local $temp1) + ) + (drop + (get_local $temp2) + ) + ) + (func $local-to-stack-in-control-flow (; 53 ;) (; has Stack IR ;) (type $FUNCSIG$v) + (local $temp1 i32) + (if + (i32.const 0) + (block $block + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 0) + ) + ) + (drop + (get_local $temp1) + ) + ) + (block $block13 + (set_local $temp1 + (call $local-to-stack-multi-4 + (i32.const 1) + ) + ) + (drop + (get_local $temp1) + ) + ) + ) + ) + (func $remove-block (; 54 ;) (; has Stack IR ;) (type $6) (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $remove-block + (i32.const 0) + ) + (i32.eqz + (block $block (result i32) + (set_local $temp + (call $remove-block + (i32.const 1) + ) + ) + (drop + (call $remove-block + (i32.const 2) + ) + ) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.wast b/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.wast new file mode 100644 index 000000000..9176ff5bc --- /dev/null +++ b/test/passes/generate-stack-ir_optimize-stack-ir_print-stack-ir_optimize-level=3.wast @@ -0,0 +1,712 @@ +(module + (type $FUNCSIG$vf (func (param f32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$id (func (param f64) (result i32))) + (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + (type $4 (func (result f64))) + (type $5 (func (result i32))) + (type $6 (func (param i32) (result i32))) + (type $7 (func (param f64) (result f64))) + (type $8 (func (result i64))) + (type $9 (func (param i32 i64))) + (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) + (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) + (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) + (table 10 anyfunc) + (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (memory $0 4096 4096) + (data (i32.const 1026) "\14\00") + (export "big_negative" (func $big_negative)) + (func $big_negative (type $FUNCSIG$v) + (local $temp f64) + (block $block0 + (set_local $temp + (f64.const -2147483648) + ) + (set_local $temp + (f64.const -2147483648) + ) + (set_local $temp + (f64.const -21474836480) + ) + (set_local $temp + (f64.const 0.039625) + ) + (set_local $temp + (f64.const -0.039625) + ) + ) + ) + (func $importedDoubles (type $4) (result f64) + (local $temp f64) + (block $topmost (result f64) + (set_local $temp + (f64.add + (f64.add + (f64.add + (f64.load + (i32.const 8) + ) + (f64.load + (i32.const 16) + ) + ) + (f64.neg + (f64.load + (i32.const 16) + ) + ) + ) + (f64.neg + (f64.load + (i32.const 8) + ) + ) + ) + ) + (if + (i32.gt_s + (i32.load + (i32.const 24) + ) + (i32.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (f64.gt + (f64.load + (i32.const 32) + ) + (f64.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (f64.const 1.2) + ) + ) + (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) + (local $t f64) + (local $Int f64) + (local $Double i32) + (block $topmost (result f64) + (if + (f64.gt + (get_local $x) + (f64.const 0) + ) + (br $topmost + (f64.const 1.2) + ) + ) + (if + (f64.gt + (get_local $Int) + (f64.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (i32.gt_s + (get_local $Double) + (i32.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (if + (f64.lt + (get_local $x) + (get_local $y) + ) + (br $topmost + (get_local $x) + ) + ) + (get_local $y) + ) + ) + (func $intOps (type $5) (result i32) + (local $x i32) + (i32.eq + (get_local $x) + (i32.const 0) + ) + ) + (func $hexLiterals (type $FUNCSIG$v) + (drop + (i32.add + (i32.add + (i32.const 0) + (i32.const 313249263) + ) + (i32.const -19088752) + ) + ) + ) + (func $conversions (type $FUNCSIG$v) + (local $i i32) + (local $d f64) + (block $block0 + (set_local $i + (call $f64-to-int + (get_local $d) + ) + ) + (set_local $d + (f64.convert_s/i32 + (get_local $i) + ) + ) + (set_local $d + (f64.convert_u/i32 + (i32.shr_u + (get_local $i) + (i32.const 0) + ) + ) + ) + ) + ) + (func $seq (type $FUNCSIG$v) + (local $J f64) + (set_local $J + (f64.sub + (block $block0 (result f64) + (drop + (f64.const 0.1) + ) + (f64.const 5.1) + ) + (block $block1 (result f64) + (drop + (f64.const 3.2) + ) + (f64.const 4.2) + ) + ) + ) + ) + (func $switcher (type $6) (param $x i32) (result i32) + (block $topmost (result i32) + (block $switch$0 + (block $switch-default$3 + (block $switch-case$2 + (block $switch-case$1 + (br_table $switch-case$1 $switch-case$2 $switch-default$3 + (i32.sub + (get_local $x) + (i32.const 1) + ) + ) + ) + (br $topmost + (i32.const 1) + ) + ) + (br $topmost + (i32.const 2) + ) + ) + (nop) + ) + (block $switch$4 + (block $switch-default$7 + (block $switch-case$6 + (block $switch-case$5 + (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 + (i32.sub + (get_local $x) + (i32.const 5) + ) + ) + ) + (br $topmost + (i32.const 121) + ) + ) + (br $topmost + (i32.const 51) + ) + ) + (nop) + ) + (block $label$break$Lout + (block $switch-default$16 + (block $switch-case$15 + (block $switch-case$12 + (block $switch-case$9 + (block $switch-case$8 + (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 + (i32.sub + (get_local $x) + (i32.const 2) + ) + ) + ) + (br $label$break$Lout) + ) + (br $label$break$Lout) + ) + (block $while-out$10 + (loop $while-in$11 + (block $block1 + (br $while-out$10) + (br $while-in$11) + ) + ) + (br $label$break$Lout) + ) + ) + (block $while-out$13 + (loop $while-in$14 + (block $block3 + (br $label$break$Lout) + (br $while-in$14) + ) + ) + (br $label$break$Lout) + ) + ) + (nop) + ) + (i32.const 0) + ) + ) + (func $blocker (type $FUNCSIG$v) + (block $label$break$L + (br $label$break$L) + ) + ) + (func $frem (type $4) (result f64) + (call $f64-rem + (f64.const 5.5) + (f64.const 1.2) + ) + ) + (func $big_uint_div_u (type $5) (result i32) + (local $x i32) + (block $topmost (result i32) + (set_local $x + (i32.and + (i32.div_u + (i32.const -1) + (i32.const 2) + ) + (i32.const -1) + ) + ) + (get_local $x) + ) + ) + (func $fr (type $FUNCSIG$vf) (param $x f32) + (local $y f32) + (local $z f64) + (block $block0 + (drop + (f32.demote/f64 + (get_local $z) + ) + ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + ) + ) + (func $negZero (type $4) (result f64) + (f64.const -0) + ) + (func $abs (type $FUNCSIG$v) + (local $x i32) + (local $y f64) + (local $z f32) + (local $asm2wasm_i32_temp i32) + (block $block0 + (set_local $x + (block $block1 (result i32) + (set_local $asm2wasm_i32_temp + (i32.const 0) + ) + (select + (i32.sub + (i32.const 0) + (get_local $asm2wasm_i32_temp) + ) + (get_local $asm2wasm_i32_temp) + (i32.lt_s + (get_local $asm2wasm_i32_temp) + (i32.const 0) + ) + ) + ) + ) + (set_local $y + (f64.abs + (f64.const 0) + ) + ) + (set_local $z + (f32.abs + (f32.const 0) + ) + ) + ) + ) + (func $neg (type $FUNCSIG$v) + (local $x f32) + (block $block0 + (set_local $x + (f32.neg + (get_local $x) + ) + ) + (call_indirect (type $FUNCSIG$vf) + (get_local $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + ) + (func $cneg (type $FUNCSIG$vf) (param $x f32) + (call_indirect (type $FUNCSIG$vf) + (get_local $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + (func $___syscall_ret (type $FUNCSIG$v) + (local $$0 i32) + (drop + (i32.gt_u + (i32.shr_u + (get_local $$0) + (i32.const 0) + ) + (i32.const -4096) + ) + ) + ) + (func $z (type $FUNCSIG$v) + (nop) + ) + (func $w (type $FUNCSIG$v) + (nop) + ) + (func $block_and_after (type $5) (result i32) + (block $waka + (drop + (i32.const 1) + ) + (br $waka) + ) + (i32.const 0) + ) + (func $loop-roundtrip (type $7) (param $0 f64) (result f64) + (loop $loop-in1 (result f64) + (drop + (get_local $0) + ) + (get_local $0) + ) + ) + (func $big-i64 (type $8) (result i64) + (i64.const -9218868437227405313) + ) + (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) + (i64.store32 + (get_local $0) + (get_local $1) + ) + ) + (func $return-unreachable (result i32) + (return (i32.const 1)) + ) + (func $unreachable-block (result i32) + (f64.abs + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (drop (i32.const 1)) + (return (i32.const 2)) + ) + ) + ) + (func $unreachable-block-toplevel (result i32) + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (drop (i32.const 1)) + (return (i32.const 2)) + ) + ) + (func $unreachable-block0 (result i32) + (f64.abs + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 2)) + ) + ) + ) + (func $unreachable-block0-toplevel (result i32) + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 2)) + ) + ) + (func $unreachable-block-with-br (result i32) + (block $block ;; unreachable type due to last element having that type, but the block is exitable + (drop (i32.const 1)) + (br $block) + ) + (i32.const 1) + ) + (func $unreachable-if (result i32) + (f64.abs + (if ;; note no type - valid in binaryen IR, in wasm must be i32 + (i32.const 3) + (return (i32.const 2)) + (return (i32.const 1)) + ) + ) + ) + (func $unreachable-if-toplevel (result i32) + (if ;; note no type - valid in binaryen IR, in wasm must be i32 + (i32.const 3) + (return (i32.const 2)) + (return (i32.const 1)) + ) + ) + (func $unreachable-loop (result i32) + (f64.abs + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (nop) + (return (i32.const 1)) + ) + ) + ) + (func $unreachable-loop0 (result i32) + (f64.abs + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 1)) + ) + ) + ) + (func $unreachable-loop-toplevel (result i32) + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (nop) + (return (i32.const 1)) + ) + ) + (func $unreachable-loop0-toplevel (result i32) + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 1)) + ) + ) + (func $unreachable-ifs + (if (unreachable) (nop)) + (if (unreachable) (unreachable)) + (if (unreachable) (nop) (nop)) + (if (unreachable) (unreachable) (nop)) + (if (unreachable) (nop) (unreachable)) + (if (unreachable) (unreachable) (unreachable)) + ;; + (if (i32.const 1) (unreachable) (nop)) + (if (i32.const 1) (nop) (unreachable)) + (if (i32.const 1) (unreachable) (unreachable)) + ) + (func $unreachable-if-arm + (if + (i32.const 1) + (block + (nop) + ) + (block + (unreachable) + (drop + (i32.const 1) + ) + ) + ) + ) + (func $local-to-stack (param $x i32) (result i32) + (local $temp i32) + (set_local $temp (call $local-to-stack (i32.const 1))) ;; this set could just be on the stack + (drop (call $local-to-stack (i32.const 2))) + (get_local $temp) + ) + (func $local-to-stack-1 (param $x i32) (result i32) + (local $temp i32) + (set_local $temp (call $local-to-stack (i32.const 1))) + (drop (call $local-to-stack (i32.const 2))) + (i32.eqz + (get_local $temp) + ) + ) + (func $local-to-stack-1b (param $x i32) (result i32) + (local $temp i32) + (set_local $temp (call $local-to-stack (i32.const 1))) + (drop (call $local-to-stack (i32.const 2))) + (i32.add + (get_local $temp) + (i32.const 3) + ) + ) + (func $local-to-stack-1c-no (param $x i32) (result i32) + (local $temp i32) + (set_local $temp (call $local-to-stack (i32.const 1))) + (drop (call $local-to-stack (i32.const 2))) + (i32.add + (i32.const 3) ;; this is in the way + (get_local $temp) + ) + ) + (func $local-to-stack-2-no (param $x i32) (result i32) + (local $temp i32) + (set_local $temp (call $local-to-stack (i32.const 1))) + (drop (call $local-to-stack (i32.const 2))) + (i32.add + (get_local $temp) + (get_local $temp) ;; a second use - so cannot stack it + ) + ) + (func $local-to-stack-3-no (param $x i32) (result i32) + (local $temp i32) + (if (i32.const 1) + (set_local $temp (call $local-to-stack (i32.const 1))) + (set_local $temp (call $local-to-stack (i32.const 2))) ;; two sets for that get + ) + (drop (call $local-to-stack (i32.const 3))) + (get_local $temp) + ) + (func $local-to-stack-multi-4 (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 2))) + (drop (get_local $temp1)) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 3))) ;; same local, used later + (drop (call $local-to-stack-multi-4 (i32.const 4))) + (get_local $temp1) + ) + (func $local-to-stack-multi-5 (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 2))) + (drop (get_local $temp1)) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later + (drop (call $local-to-stack-multi-4 (i32.const 4))) + (get_local $temp2) + ) + (func $local-to-stack-multi-6-justone (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 2))) + (drop (get_local $temp1)) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later + (drop (call $local-to-stack-multi-4 (i32.const 4))) + (i32.add + (get_local $temp2) + (get_local $temp2) + ) + ) + (func $local-to-stack-multi-7-justone (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 2))) + (drop + (i32.add + (get_local $temp1) + (get_local $temp1) + ) + ) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later + (drop (call $local-to-stack-multi-4 (i32.const 4))) + (get_local $temp2) + ) + (func $local-to-stack-overlapping-multi-8-no (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 3))) + (i32.add + (get_local $temp2) ;; the timing + (get_local $temp1) ;; it sucks + ) + ) + (func $local-to-stack-overlapping-multi-9-yes (param $x i32) (result i32) + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (call $local-to-stack-multi-4 (i32.const 3))) + (i32.add + (get_local $temp1) ;; the stars align + (get_local $temp2) ;; and a time presents itself + ) + ) + (func $local-to-stack-through-control-flow + (local $temp1 i32) + (local $temp2 i32) + (set_local $temp2 (call $local-to-stack-multi-4 (i32.const 0))) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (if (i32.const 0) (nop)) + (drop (get_local $temp1)) + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 2))) + (block $block (br $block)) + (drop (get_local $temp1)) + (drop (get_local $temp2)) + ) + (func $local-to-stack-in-control-flow + (local $temp1 i32) + (if (i32.const 0) + (block + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 0))) + (drop (get_local $temp1)) + ) + (block + (set_local $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (get_local $temp1)) + ) + ) + ) + (func $remove-block (param $x i32) (result i32) + (local $temp i32) + (i32.add + (call $remove-block (i32.const 0)) + (i32.eqz + (block (result i32) ;; after we use the stack instead of the local, we can remove this block + (set_local $temp (call $remove-block (i32.const 1))) + (drop (call $remove-block (i32.const 2))) + (get_local $temp) + ) + ) + ) + ) +) diff --git a/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.txt b/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.txt new file mode 100644 index 000000000..126b2926e --- /dev/null +++ b/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.txt @@ -0,0 +1,41 @@ +$0: +0 block +1 block +2 loop +3 block +4 unreachable (unreachable) +5 unreachable (unreachable) +6 end (none) +7 unreachable (unreachable) +8 set_local (unreachable) +9 unreachable (unreachable) +10 unreachable (unreachable) +11 end (none) +12 unreachable (unreachable) +13 unreachable (unreachable) +14 unreachable (unreachable) +15 end (none) +16 unreachable (unreachable) +17 break (unreachable) +18 unreachable (unreachable) +19 end (none) + +(module + (type $0 (func (param i64))) + (func $0 (; 0 ;) (; has Stack IR ;) (type $0) (param $var$0 i64) + (block $label$1 + (br_if $label$1 + (block $label$2 + (loop $label$3 + (tee_local $var$0 + (block $label$4 + (unreachable) + ) + ) + ) + (unreachable) + ) + ) + ) + ) +) diff --git a/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.wast b/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.wast new file mode 100644 index 000000000..6a771aa4d --- /dev/null +++ b/test/passes/remove-unused-brs_generate-stack-ir_print-stack-ir.wast @@ -0,0 +1,21 @@ +(module + (type $0 (func (param i64))) + (func $0 (; 0 ;) (type $0) (param $var$0 i64) + (block $label$1 + (br_if $label$1 + (block $label$2 (result i32) + (loop $label$3 + (set_local $var$0 + (block $label$4 (result i64) + (unreachable) + ) + ) + ) + (unreachable) + ) + ) + (nop) + ) + ) +) + diff --git a/test/threads.fromasm b/test/threads.fromasm index 4d191732c..2c1059dcc 100644 --- a/test/threads.fromasm +++ b/test/threads.fromasm @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "threads.asm.js") (export "test" (func $test)) - (func $test (; 0 ;) + (func $test (; 0 ;) (; has Stack IR ;) (local $0 i32) (drop (i32.atomic.load diff --git a/test/threads.fromasm.clamp b/test/threads.fromasm.clamp index 4d191732c..2c1059dcc 100644 --- a/test/threads.fromasm.clamp +++ b/test/threads.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "threads.asm.js") (export "test" (func $test)) - (func $test (; 0 ;) + (func $test (; 0 ;) (; has Stack IR ;) (local $0 i32) (drop (i32.atomic.load diff --git a/test/threads.fromasm.imprecise b/test/threads.fromasm.imprecise index c8967ab2e..a35be0f7d 100644 --- a/test/threads.fromasm.imprecise +++ b/test/threads.fromasm.imprecise @@ -1,7 +1,7 @@ (module (import "env" "memory" (memory $0 (shared 256 256))) (export "test" (func $test)) - (func $test (; 0 ;) + (func $test (; 0 ;) (; has Stack IR ;) (local $0 i32) (drop (i32.atomic.load diff --git a/test/threads.wasm-only.fromasm b/test/threads.wasm-only.fromasm index f633af016..4a692c18c 100644 --- a/test/threads.wasm-only.fromasm +++ b/test/threads.wasm-only.fromasm @@ -6,7 +6,7 @@ (export "test64" (func $legalstub$test64)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $test64 (; 0 ;) (result i64) + (func $test64 (; 0 ;) (; has Stack IR ;) (result i64) (local $0 i64) (local $1 i64) (local $2 i32) @@ -50,7 +50,7 @@ ) (get_local $1) ) - (func $legalstub$test64 (; 1 ;) (result i32) + (func $legalstub$test64 (; 1 ;) (; has Stack IR ;) (result i32) (local $0 i64) (set_local $0 (call $test64) @@ -67,10 +67,10 @@ (get_local $0) ) ) - (func $getTempRet0 (; 2 ;) (result i32) + (func $getTempRet0 (; 2 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 3 ;) (param $0 i32) + (func $setTempRet0 (; 3 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) diff --git a/test/threads.wasm-only.fromasm.clamp b/test/threads.wasm-only.fromasm.clamp index f633af016..4a692c18c 100644 --- a/test/threads.wasm-only.fromasm.clamp +++ b/test/threads.wasm-only.fromasm.clamp @@ -6,7 +6,7 @@ (export "test64" (func $legalstub$test64)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $test64 (; 0 ;) (result i64) + (func $test64 (; 0 ;) (; has Stack IR ;) (result i64) (local $0 i64) (local $1 i64) (local $2 i32) @@ -50,7 +50,7 @@ ) (get_local $1) ) - (func $legalstub$test64 (; 1 ;) (result i32) + (func $legalstub$test64 (; 1 ;) (; has Stack IR ;) (result i32) (local $0 i64) (set_local $0 (call $test64) @@ -67,10 +67,10 @@ (get_local $0) ) ) - (func $getTempRet0 (; 2 ;) (result i32) + (func $getTempRet0 (; 2 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 3 ;) (param $0 i32) + (func $setTempRet0 (; 3 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) diff --git a/test/threads.wasm-only.fromasm.imprecise b/test/threads.wasm-only.fromasm.imprecise index 2c6fa3f18..446dc7f7a 100644 --- a/test/threads.wasm-only.fromasm.imprecise +++ b/test/threads.wasm-only.fromasm.imprecise @@ -4,7 +4,7 @@ (export "test64" (func $legalstub$test64)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $test64 (; 0 ;) (result i64) + (func $test64 (; 0 ;) (; has Stack IR ;) (result i64) (local $0 i64) (local $1 i64) (local $2 i32) @@ -48,7 +48,7 @@ ) (get_local $1) ) - (func $legalstub$test64 (; 1 ;) (result i32) + (func $legalstub$test64 (; 1 ;) (; has Stack IR ;) (result i32) (local $0 i64) (set_local $0 (call $test64) @@ -65,10 +65,10 @@ (get_local $0) ) ) - (func $getTempRet0 (; 2 ;) (result i32) + (func $getTempRet0 (; 2 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 3 ;) (param $0 i32) + (func $setTempRet0 (; 3 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) diff --git a/test/two_sides.fromasm b/test/two_sides.fromasm index 57d11e478..af5ff5386 100644 --- a/test/two_sides.fromasm +++ b/test/two_sides.fromasm @@ -5,7 +5,7 @@ (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) (data (get_global $memoryBase) "two_sides.asm.js") (export "_test" (func $_test)) - (func $_test (; 1 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_test (; 1 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 f64) (if (result i32) (get_local $4) diff --git a/test/two_sides.fromasm.clamp b/test/two_sides.fromasm.clamp index de51f2281..c21a6b868 100644 --- a/test/two_sides.fromasm.clamp +++ b/test/two_sides.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "two_sides.asm.js") (export "_test" (func $_test)) - (func $f64-to-int (; 0 ;) (param $0 f64) (result i32) + (func $f64-to-int (; 0 ;) (; has Stack IR ;) (param $0 f64) (result i32) (if (result i32) (f64.ne (get_local $0) @@ -29,7 +29,7 @@ ) ) ) - (func $_test (; 1 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_test (; 1 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 f64) (if (result i32) (get_local $4) diff --git a/test/two_sides.fromasm.imprecise b/test/two_sides.fromasm.imprecise index c4dbbb386..9115e679a 100644 --- a/test/two_sides.fromasm.imprecise +++ b/test/two_sides.fromasm.imprecise @@ -1,6 +1,6 @@ (module (export "_test" (func $_test)) - (func $_test (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $_test (; 0 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 f64) (if (result i32) (get_local $4) diff --git a/test/unit.fromasm b/test/unit.fromasm index bddac1e56..edefbfff7 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -77,10 +77,10 @@ (export "relocatableAndModules" (func $relocatableAndModules)) (export "exported_f32_user" (func $legalstub$exported_f32_user)) (export "keepAlive" (func $keepAlive)) - (func $big_negative (; 8 ;) + (func $big_negative (; 8 ;) (; has Stack IR ;) (nop) ) - (func $importedDoubles (; 9 ;) (result f64) + (func $importedDoubles (; 9 ;) (; has Stack IR ;) (result f64) (if (i32.gt_s (get_global $Int) @@ -101,7 +101,7 @@ ) (f64.const 1.2) ) - (func $doubleCompares (; 10 ;) (param $0 f64) (param $1 f64) (result f64) + (func $doubleCompares (; 10 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) (if (f64.gt (get_local $0) @@ -140,12 +140,12 @@ ) (get_local $1) ) - (func $intOps (; 11 ;) (param $0 i32) (result i32) + (func $intOps (; 11 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.eqz (get_local $0) ) ) - (func $switcher (; 12 ;) (param $0 i32) (result i32) + (func $switcher (; 12 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $switch (block $switch-case0 (block $switch-case @@ -224,22 +224,22 @@ ) (i32.const 0) ) - (func $frem (; 13 ;) (result f64) + (func $frem (; 13 ;) (; has Stack IR ;) (result f64) (call $f64-rem (f64.const 5.5) (f64.const 1.2) ) ) - (func $big_uint_div_u (; 14 ;) (result i32) + (func $big_uint_div_u (; 14 ;) (; has Stack IR ;) (result i32) (i32.const 2147483647) ) - (func $trapping_sint_div_s (; 15 ;) (result i32) + (func $trapping_sint_div_s (; 15 ;) (; has Stack IR ;) (result i32) (i32.const 0) ) - (func $negZero (; 16 ;) (result f64) + (func $negZero (; 16 ;) (; has Stack IR ;) (result f64) (f64.const -0) ) - (func $neg (; 17 ;) + (func $neg (; 17 ;) (; has Stack IR ;) (local $0 f32) (call_indirect (type $FUNCSIG$vf) (f32.neg @@ -248,13 +248,13 @@ (i32.const 9) ) ) - (func $cneg (; 18 ;) (param $0 f32) + (func $cneg (; 18 ;) (; has Stack IR ;) (param $0 f32) (call_indirect (type $FUNCSIG$vf) (get_local $0) (i32.const 9) ) ) - (func $smallCompare (; 19 ;) (param $0 i32) (param $1 i32) (result i32) + (func $smallCompare (; 19 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (i32.lt_s (get_local $0) @@ -281,13 +281,13 @@ ) (get_local $0) ) - (func $cneg_nosemicolon (; 20 ;) + (func $cneg_nosemicolon (; 20 ;) (; has Stack IR ;) (call_indirect (type $FUNCSIG$vi) (i32.const 1) (i32.const 17) ) ) - (func $forLoop (; 21 ;) + (func $forLoop (; 21 ;) (; has Stack IR ;) (local $0 i32) (set_local $0 (i32.const 1) @@ -313,7 +313,7 @@ ) ) ) - (func $aborts (; 22 ;) + (func $aborts (; 22 ;) (; has Stack IR ;) (drop (call $abort (f64.const 0) @@ -342,7 +342,7 @@ ) ) ) - (func $continues (; 23 ;) + (func $continues (; 23 ;) (; has Stack IR ;) (loop $while-in (call $print (i32.const 1) @@ -361,7 +361,7 @@ (br $while-in) ) ) - (func $recursiveBlockMerging (; 24 ;) (param $0 i32) (result i32) + (func $recursiveBlockMerging (; 24 ;) (; has Stack IR ;) (param $0 i32) (result i32) (drop (call $lb (i32.add @@ -436,7 +436,7 @@ ) ) ) - (func $lb (; 25 ;) (param $0 i32) (result i32) + (func $lb (; 25 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.store (get_local $0) (i32.add @@ -446,7 +446,7 @@ ) (i32.const 0) ) - (func $zeroInit (; 26 ;) (param $0 i32) + (func $zeroInit (; 26 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (call $lb @@ -476,7 +476,7 @@ ) ) ) - (func $phi (; 27 ;) (result i32) + (func $phi (; 27 ;) (; has Stack IR ;) (result i32) (block $do-once (result i32) (drop (br_if $do-once @@ -489,7 +489,7 @@ (i32.const 1) ) ) - (func $smallIf (; 28 ;) + (func $smallIf (; 28 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -499,7 +499,7 @@ ) ) ) - (func $dropCall (; 29 ;) (result i32) + (func $dropCall (; 29 ;) (; has Stack IR ;) (result i32) (if (call $return_int) (block @@ -520,7 +520,7 @@ ) (call $phi) ) - (func $useSetGlobal (; 30 ;) (result i32) + (func $useSetGlobal (; 30 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 10) ) @@ -532,13 +532,13 @@ ) (get_global $Int) ) - (func $usesSetGlobal2 (; 31 ;) (result i32) + (func $usesSetGlobal2 (; 31 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 40) ) (i32.const 50) ) - (func $breakThroughMany (; 32 ;) (param $0 i32) + (func $breakThroughMany (; 32 ;) (; has Stack IR ;) (param $0 i32) (block $label$break$L1 (if (get_local $0) @@ -556,7 +556,7 @@ ) ) ) - (func $ifChainEmpty (; 33 ;) (param $0 i32) (result i32) + (func $ifChainEmpty (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (i32.eq (get_local $0) @@ -568,12 +568,12 @@ ) (i32.const 0) ) - (func $heap8NoShift (; 34 ;) (param $0 i32) (result i32) + (func $heap8NoShift (; 34 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.load8_s (get_local $0) ) ) - (func $conditionalTypeFun (; 35 ;) + (func $conditionalTypeFun (; 35 ;) (; has Stack IR ;) (drop (if (result i32) (call $return_int) @@ -599,7 +599,7 @@ ) ) ) - (func $loadSigned (; 36 ;) (param $0 i32) + (func $loadSigned (; 36 ;) (; has Stack IR ;) (param $0 i32) (call $loadSigned (i32.load8_s (get_local $0) @@ -665,13 +665,13 @@ ) ) ) - (func $z (; 37 ;) (param $0 f32) + (func $z (; 37 ;) (; has Stack IR ;) (param $0 f32) (nop) ) - (func $w (; 38 ;) (result f64) + (func $w (; 38 ;) (; has Stack IR ;) (result f64) (f64.const 0) ) - (func $globalOpts (; 39 ;) + (func $globalOpts (; 39 ;) (; has Stack IR ;) (local $0 i32) (i32.store8 (i32.const 13) @@ -701,7 +701,7 @@ (get_local $0) ) ) - (func $dropCallImport (; 40 ;) + (func $dropCallImport (; 40 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -709,7 +709,7 @@ ) ) ) - (func $loophi (; 41 ;) (param $0 i32) (param $1 i32) + (func $loophi (; 41 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (local $2 i32) (loop $while-in (block $while-out @@ -739,7 +739,7 @@ ) ) ) - (func $loophi2 (; 42 ;) (result i32) + (func $loophi2 (; 42 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) @@ -772,7 +772,7 @@ ) (get_local $1) ) - (func $loophi2b (; 43 ;) (result i32) + (func $loophi2b (; 43 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (loop $label$continue$L7 @@ -804,7 +804,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading (; 44 ;) (param $0 i32) (result i32) + (func $relooperJumpThreading (; 44 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $__rjto$0 (block $__rjti$0 (if @@ -973,7 +973,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 45 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) + (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 45 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (loop $while-in (block $__rjto$1 (block $__rjti$1 @@ -1000,7 +1000,7 @@ (br $while-in) ) ) - (func $relooperJumpThreading_irreducible (; 46 ;) (param $0 i32) + (func $relooperJumpThreading_irreducible (; 46 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (i32.eq @@ -1052,7 +1052,7 @@ ) ) ) - (func $__Z12multi_varargiz (; 47 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $__Z12multi_varargiz (; 47 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (if (get_local $3) (loop $while-in @@ -1069,10 +1069,10 @@ ) ) ) - (func $jumpThreadDrop (; 48 ;) (result i32) + (func $jumpThreadDrop (; 48 ;) (; has Stack IR ;) (result i32) (call $return_int) ) - (func $dropIgnoredImportInIf (; 49 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportInIf (; 49 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (if (get_local $0) (drop @@ -1082,7 +1082,7 @@ ) ) ) - (func $dropIgnoredImportsInIf (; 50 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportsInIf (; 50 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (drop (if (result i32) (get_local $0) @@ -1095,7 +1095,7 @@ ) ) ) - (func $store_fround (; 51 ;) (param $0 i32) + (func $store_fround (; 51 ;) (; has Stack IR ;) (param $0 i32) (f64.store (i32.const 80) (f64.promote/f32 @@ -1105,7 +1105,7 @@ ) ) ) - (func $relocatableAndModules (; 52 ;) (result i32) + (func $relocatableAndModules (; 52 ;) (; has Stack IR ;) (result i32) (call_indirect (type $FUNCSIG$v) (i32.const 10) ) @@ -1118,7 +1118,7 @@ (i32.const 30) ) ) - (func $sqrts (; 53 ;) (param $0 f64) (result f64) + (func $sqrts (; 53 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.add (f64.sqrt (get_local $0) @@ -1132,7 +1132,7 @@ ) ) ) - (func $keepAlive (; 54 ;) + (func $keepAlive (; 54 ;) (; has Stack IR ;) (drop (call $sqrts (f64.const 3.14159) @@ -1181,13 +1181,13 @@ ) ) ) - (func $vi (; 55 ;) (param $0 i32) + (func $vi (; 55 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $ii (; 56 ;) (param $0 i32) (result i32) + (func $ii (; 56 ;) (; has Stack IR ;) (param $0 i32) (result i32) (get_local $0) ) - (func $legalstub$conversions (; 57 ;) (param $0 i32) (param $1 f64) (param $2 f64) + (func $legalstub$conversions (; 57 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (drop (call $f64-to-int (get_local $1) @@ -1203,7 +1203,7 @@ ) ) ) - (func $legalstub$frem_float (; 58 ;) (result f64) + (func $legalstub$frem_float (; 58 ;) (; has Stack IR ;) (result f64) (f64.promote/f32 (f32.demote/f64 (call $f64-rem @@ -1213,16 +1213,16 @@ ) ) ) - (func $legalstub$fr (; 59 ;) (param $0 f64) + (func $legalstub$fr (; 59 ;) (; has Stack IR ;) (param $0 f64) (nop) ) - (func $legalstub$ceiling_32_64 (; 60 ;) (param $0 f64) (param $1 f64) + (func $legalstub$ceiling_32_64 (; 60 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (nop) ) - (func $legalstub$bitcasts (; 61 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 61 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) - (func $legalstub$exported_f32_user (; 62 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) + (func $legalstub$exported_f32_user (; 62 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) (f64.promote/f32 (f32.demote/f64 (get_local $1) diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp index 501fa7145..ee2c395df 100644 --- a/test/unit.fromasm.clamp +++ b/test/unit.fromasm.clamp @@ -75,10 +75,10 @@ (export "relocatableAndModules" (func $relocatableAndModules)) (export "exported_f32_user" (func $legalstub$exported_f32_user)) (export "keepAlive" (func $keepAlive)) - (func $big_negative (; 7 ;) + (func $big_negative (; 7 ;) (; has Stack IR ;) (nop) ) - (func $importedDoubles (; 8 ;) (result f64) + (func $importedDoubles (; 8 ;) (; has Stack IR ;) (result f64) (if (i32.gt_s (get_global $Int) @@ -99,7 +99,7 @@ ) (f64.const 1.2) ) - (func $doubleCompares (; 9 ;) (param $0 f64) (param $1 f64) (result f64) + (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) (if (f64.gt (get_local $0) @@ -138,12 +138,12 @@ ) (get_local $1) ) - (func $intOps (; 10 ;) (param $0 i32) (result i32) + (func $intOps (; 10 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.eqz (get_local $0) ) ) - (func $f64-to-int (; 11 ;) (param $0 f64) (result i32) + (func $f64-to-int (; 11 ;) (; has Stack IR ;) (param $0 f64) (result i32) (if (result i32) (f64.ne (get_local $0) @@ -169,7 +169,7 @@ ) ) ) - (func $f32-to-int (; 12 ;) (param $0 f32) (result i32) + (func $f32-to-int (; 12 ;) (; has Stack IR ;) (param $0 f32) (result i32) (if (result i32) (f32.ne (get_local $0) @@ -195,7 +195,7 @@ ) ) ) - (func $switcher (; 13 ;) (param $0 i32) (result i32) + (func $switcher (; 13 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $switch (block $switch-case0 (block $switch-case @@ -274,22 +274,22 @@ ) (i32.const 0) ) - (func $frem (; 14 ;) (result f64) + (func $frem (; 14 ;) (; has Stack IR ;) (result f64) (call $f64-rem (f64.const 5.5) (f64.const 1.2) ) ) - (func $big_uint_div_u (; 15 ;) (result i32) + (func $big_uint_div_u (; 15 ;) (; has Stack IR ;) (result i32) (i32.const 2147483647) ) - (func $trapping_sint_div_s (; 16 ;) (result i32) + (func $trapping_sint_div_s (; 16 ;) (; has Stack IR ;) (result i32) (i32.const 0) ) - (func $negZero (; 17 ;) (result f64) + (func $negZero (; 17 ;) (; has Stack IR ;) (result f64) (f64.const -0) ) - (func $neg (; 18 ;) + (func $neg (; 18 ;) (; has Stack IR ;) (local $0 f32) (call_indirect (type $FUNCSIG$vf) (f32.neg @@ -298,13 +298,13 @@ (i32.const 9) ) ) - (func $cneg (; 19 ;) (param $0 f32) + (func $cneg (; 19 ;) (; has Stack IR ;) (param $0 f32) (call_indirect (type $FUNCSIG$vf) (get_local $0) (i32.const 9) ) ) - (func $smallCompare (; 20 ;) (param $0 i32) (param $1 i32) (result i32) + (func $smallCompare (; 20 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (i32.lt_s (get_local $0) @@ -331,13 +331,13 @@ ) (get_local $0) ) - (func $cneg_nosemicolon (; 21 ;) + (func $cneg_nosemicolon (; 21 ;) (; has Stack IR ;) (call_indirect (type $FUNCSIG$vi) (i32.const 1) (i32.const 17) ) ) - (func $forLoop (; 22 ;) + (func $forLoop (; 22 ;) (; has Stack IR ;) (local $0 i32) (set_local $0 (i32.const 1) @@ -363,7 +363,7 @@ ) ) ) - (func $aborts (; 23 ;) + (func $aborts (; 23 ;) (; has Stack IR ;) (drop (call $abort (f64.const 0) @@ -392,7 +392,7 @@ ) ) ) - (func $continues (; 24 ;) + (func $continues (; 24 ;) (; has Stack IR ;) (loop $while-in (call $print (i32.const 1) @@ -411,7 +411,7 @@ (br $while-in) ) ) - (func $recursiveBlockMerging (; 25 ;) (param $0 i32) (result i32) + (func $recursiveBlockMerging (; 25 ;) (; has Stack IR ;) (param $0 i32) (result i32) (drop (call $lb (i32.add @@ -486,7 +486,7 @@ ) ) ) - (func $lb (; 26 ;) (param $0 i32) (result i32) + (func $lb (; 26 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.store (get_local $0) (i32.add @@ -496,7 +496,7 @@ ) (i32.const 0) ) - (func $zeroInit (; 27 ;) (param $0 i32) + (func $zeroInit (; 27 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (call $lb @@ -526,7 +526,7 @@ ) ) ) - (func $phi (; 28 ;) (result i32) + (func $phi (; 28 ;) (; has Stack IR ;) (result i32) (block $do-once (result i32) (drop (br_if $do-once @@ -539,7 +539,7 @@ (i32.const 1) ) ) - (func $smallIf (; 29 ;) + (func $smallIf (; 29 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -549,7 +549,7 @@ ) ) ) - (func $dropCall (; 30 ;) (result i32) + (func $dropCall (; 30 ;) (; has Stack IR ;) (result i32) (if (call $return_int) (block @@ -570,7 +570,7 @@ ) (call $phi) ) - (func $useSetGlobal (; 31 ;) (result i32) + (func $useSetGlobal (; 31 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 10) ) @@ -582,13 +582,13 @@ ) (get_global $Int) ) - (func $usesSetGlobal2 (; 32 ;) (result i32) + (func $usesSetGlobal2 (; 32 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 40) ) (i32.const 50) ) - (func $breakThroughMany (; 33 ;) (param $0 i32) + (func $breakThroughMany (; 33 ;) (; has Stack IR ;) (param $0 i32) (block $label$break$L1 (if (get_local $0) @@ -606,7 +606,7 @@ ) ) ) - (func $ifChainEmpty (; 34 ;) (param $0 i32) (result i32) + (func $ifChainEmpty (; 34 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (i32.eq (get_local $0) @@ -618,12 +618,12 @@ ) (i32.const 0) ) - (func $heap8NoShift (; 35 ;) (param $0 i32) (result i32) + (func $heap8NoShift (; 35 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.load8_s (get_local $0) ) ) - (func $conditionalTypeFun (; 36 ;) + (func $conditionalTypeFun (; 36 ;) (; has Stack IR ;) (drop (if (result i32) (call $return_int) @@ -649,7 +649,7 @@ ) ) ) - (func $loadSigned (; 37 ;) (param $0 i32) + (func $loadSigned (; 37 ;) (; has Stack IR ;) (param $0 i32) (call $loadSigned (i32.load8_s (get_local $0) @@ -715,13 +715,13 @@ ) ) ) - (func $z (; 38 ;) (param $0 f32) + (func $z (; 38 ;) (; has Stack IR ;) (param $0 f32) (nop) ) - (func $w (; 39 ;) (result f64) + (func $w (; 39 ;) (; has Stack IR ;) (result f64) (f64.const 0) ) - (func $globalOpts (; 40 ;) + (func $globalOpts (; 40 ;) (; has Stack IR ;) (local $0 i32) (i32.store8 (i32.const 13) @@ -751,7 +751,7 @@ (get_local $0) ) ) - (func $dropCallImport (; 41 ;) + (func $dropCallImport (; 41 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -759,7 +759,7 @@ ) ) ) - (func $loophi (; 42 ;) (param $0 i32) (param $1 i32) + (func $loophi (; 42 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (local $2 i32) (loop $while-in (block $while-out @@ -789,7 +789,7 @@ ) ) ) - (func $loophi2 (; 43 ;) (result i32) + (func $loophi2 (; 43 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) @@ -822,7 +822,7 @@ ) (get_local $1) ) - (func $loophi2b (; 44 ;) (result i32) + (func $loophi2b (; 44 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (loop $label$continue$L7 @@ -854,7 +854,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading (; 45 ;) (param $0 i32) (result i32) + (func $relooperJumpThreading (; 45 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $__rjto$0 (block $__rjti$0 (if @@ -1023,7 +1023,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 46 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) + (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 46 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (loop $while-in (block $__rjto$1 (block $__rjti$1 @@ -1050,7 +1050,7 @@ (br $while-in) ) ) - (func $relooperJumpThreading_irreducible (; 47 ;) (param $0 i32) + (func $relooperJumpThreading_irreducible (; 47 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (i32.eq @@ -1102,7 +1102,7 @@ ) ) ) - (func $__Z12multi_varargiz (; 48 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $__Z12multi_varargiz (; 48 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (if (get_local $3) (loop $while-in @@ -1119,10 +1119,10 @@ ) ) ) - (func $jumpThreadDrop (; 49 ;) (result i32) + (func $jumpThreadDrop (; 49 ;) (; has Stack IR ;) (result i32) (call $return_int) ) - (func $dropIgnoredImportInIf (; 50 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportInIf (; 50 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (if (get_local $0) (drop @@ -1132,7 +1132,7 @@ ) ) ) - (func $dropIgnoredImportsInIf (; 51 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportsInIf (; 51 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (drop (if (result i32) (get_local $0) @@ -1145,7 +1145,7 @@ ) ) ) - (func $store_fround (; 52 ;) (param $0 i32) + (func $store_fround (; 52 ;) (; has Stack IR ;) (param $0 i32) (f64.store (i32.const 80) (f64.promote/f32 @@ -1155,7 +1155,7 @@ ) ) ) - (func $relocatableAndModules (; 53 ;) (result i32) + (func $relocatableAndModules (; 53 ;) (; has Stack IR ;) (result i32) (call_indirect (type $FUNCSIG$v) (i32.const 10) ) @@ -1168,7 +1168,7 @@ (i32.const 30) ) ) - (func $sqrts (; 54 ;) (param $0 f64) (result f64) + (func $sqrts (; 54 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.add (f64.sqrt (get_local $0) @@ -1182,7 +1182,7 @@ ) ) ) - (func $f64-to-uint (; 55 ;) (param $0 f64) (result i32) + (func $f64-to-uint (; 55 ;) (; has Stack IR ;) (param $0 f64) (result i32) (if (result i32) (f64.ne (get_local $0) @@ -1208,7 +1208,7 @@ ) ) ) - (func $keepAlive (; 56 ;) + (func $keepAlive (; 56 ;) (; has Stack IR ;) (drop (call $sqrts (f64.const 3.14159) @@ -1257,13 +1257,13 @@ ) ) ) - (func $vi (; 57 ;) (param $0 i32) + (func $vi (; 57 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $ii (; 58 ;) (param $0 i32) (result i32) + (func $ii (; 58 ;) (; has Stack IR ;) (param $0 i32) (result i32) (get_local $0) ) - (func $legalstub$conversions (; 59 ;) (param $0 i32) (param $1 f64) (param $2 f64) + (func $legalstub$conversions (; 59 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (drop (call $f64-to-int (get_local $1) @@ -1277,7 +1277,7 @@ ) ) ) - (func $legalstub$frem_float (; 60 ;) (result f64) + (func $legalstub$frem_float (; 60 ;) (; has Stack IR ;) (result f64) (f64.promote/f32 (f32.demote/f64 (call $f64-rem @@ -1287,16 +1287,16 @@ ) ) ) - (func $legalstub$fr (; 61 ;) (param $0 f64) + (func $legalstub$fr (; 61 ;) (; has Stack IR ;) (param $0 f64) (nop) ) - (func $legalstub$ceiling_32_64 (; 62 ;) (param $0 f64) (param $1 f64) + (func $legalstub$ceiling_32_64 (; 62 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (nop) ) - (func $legalstub$bitcasts (; 63 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 63 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) - (func $legalstub$exported_f32_user (; 64 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) + (func $legalstub$exported_f32_user (; 64 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) (f64.promote/f32 (f32.demote/f64 (get_local $1) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index bc293072a..b8f679fb4 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -73,10 +73,10 @@ (export "relocatableAndModules" (func $relocatableAndModules)) (export "exported_f32_user" (func $legalstub$exported_f32_user)) (export "keepAlive" (func $keepAlive)) - (func $big_negative (; 7 ;) + (func $big_negative (; 7 ;) (; has Stack IR ;) (nop) ) - (func $importedDoubles (; 8 ;) (result f64) + (func $importedDoubles (; 8 ;) (; has Stack IR ;) (result f64) (if (i32.gt_s (get_global $Int) @@ -97,7 +97,7 @@ ) (f64.const 1.2) ) - (func $doubleCompares (; 9 ;) (param $0 f64) (param $1 f64) (result f64) + (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) (if (f64.gt (get_local $0) @@ -136,12 +136,12 @@ ) (get_local $1) ) - (func $intOps (; 10 ;) (param $0 i32) (result i32) + (func $intOps (; 10 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.eqz (get_local $0) ) ) - (func $switcher (; 11 ;) (param $0 i32) (result i32) + (func $switcher (; 11 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $switch (block $switch-case0 (block $switch-case @@ -220,25 +220,25 @@ ) (i32.const 0) ) - (func $frem (; 12 ;) (result f64) + (func $frem (; 12 ;) (; has Stack IR ;) (result f64) (call $f64-rem (f64.const 5.5) (f64.const 1.2) ) ) - (func $big_uint_div_u (; 13 ;) (result i32) + (func $big_uint_div_u (; 13 ;) (; has Stack IR ;) (result i32) (i32.const 2147483647) ) - (func $trapping_sint_div_s (; 14 ;) (result i32) + (func $trapping_sint_div_s (; 14 ;) (; has Stack IR ;) (result i32) (i32.div_s (i32.const -2147483648) (i32.const -1) ) ) - (func $negZero (; 15 ;) (result f64) + (func $negZero (; 15 ;) (; has Stack IR ;) (result f64) (f64.const -0) ) - (func $neg (; 16 ;) + (func $neg (; 16 ;) (; has Stack IR ;) (local $0 f32) (call_indirect (type $FUNCSIG$vf) (f32.neg @@ -247,13 +247,13 @@ (i32.const 9) ) ) - (func $cneg (; 17 ;) (param $0 f32) + (func $cneg (; 17 ;) (; has Stack IR ;) (param $0 f32) (call_indirect (type $FUNCSIG$vf) (get_local $0) (i32.const 9) ) ) - (func $smallCompare (; 18 ;) (param $0 i32) (param $1 i32) (result i32) + (func $smallCompare (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (if (i32.lt_s (get_local $0) @@ -280,13 +280,13 @@ ) (get_local $0) ) - (func $cneg_nosemicolon (; 19 ;) + (func $cneg_nosemicolon (; 19 ;) (; has Stack IR ;) (call_indirect (type $FUNCSIG$vi) (i32.const 1) (i32.const 17) ) ) - (func $forLoop (; 20 ;) + (func $forLoop (; 20 ;) (; has Stack IR ;) (local $0 i32) (set_local $0 (i32.const 1) @@ -312,7 +312,7 @@ ) ) ) - (func $aborts (; 21 ;) + (func $aborts (; 21 ;) (; has Stack IR ;) (drop (call $abort (f64.const 0) @@ -341,7 +341,7 @@ ) ) ) - (func $continues (; 22 ;) + (func $continues (; 22 ;) (; has Stack IR ;) (loop $while-in (call $print (i32.const 1) @@ -360,7 +360,7 @@ (br $while-in) ) ) - (func $recursiveBlockMerging (; 23 ;) (param $0 i32) (result i32) + (func $recursiveBlockMerging (; 23 ;) (; has Stack IR ;) (param $0 i32) (result i32) (drop (call $lb (i32.add @@ -435,7 +435,7 @@ ) ) ) - (func $lb (; 24 ;) (param $0 i32) (result i32) + (func $lb (; 24 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.store (get_local $0) (i32.add @@ -445,7 +445,7 @@ ) (i32.const 0) ) - (func $zeroInit (; 25 ;) (param $0 i32) + (func $zeroInit (; 25 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (call $lb @@ -475,7 +475,7 @@ ) ) ) - (func $phi (; 26 ;) (result i32) + (func $phi (; 26 ;) (; has Stack IR ;) (result i32) (block $do-once (result i32) (drop (br_if $do-once @@ -488,7 +488,7 @@ (i32.const 1) ) ) - (func $smallIf (; 27 ;) + (func $smallIf (; 27 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -498,7 +498,7 @@ ) ) ) - (func $dropCall (; 28 ;) (result i32) + (func $dropCall (; 28 ;) (; has Stack IR ;) (result i32) (if (call $return_int) (block @@ -519,7 +519,7 @@ ) (call $phi) ) - (func $useSetGlobal (; 29 ;) (result i32) + (func $useSetGlobal (; 29 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 10) ) @@ -531,13 +531,13 @@ ) (get_global $Int) ) - (func $usesSetGlobal2 (; 30 ;) (result i32) + (func $usesSetGlobal2 (; 30 ;) (; has Stack IR ;) (result i32) (set_global $Int (i32.const 40) ) (i32.const 50) ) - (func $breakThroughMany (; 31 ;) (param $0 i32) + (func $breakThroughMany (; 31 ;) (; has Stack IR ;) (param $0 i32) (block $label$break$L1 (if (get_local $0) @@ -555,7 +555,7 @@ ) ) ) - (func $ifChainEmpty (; 32 ;) (param $0 i32) (result i32) + (func $ifChainEmpty (; 32 ;) (; has Stack IR ;) (param $0 i32) (result i32) (if (i32.eq (get_local $0) @@ -567,12 +567,12 @@ ) (i32.const 0) ) - (func $heap8NoShift (; 33 ;) (param $0 i32) (result i32) + (func $heap8NoShift (; 33 ;) (; has Stack IR ;) (param $0 i32) (result i32) (i32.load8_s (get_local $0) ) ) - (func $conditionalTypeFun (; 34 ;) + (func $conditionalTypeFun (; 34 ;) (; has Stack IR ;) (drop (if (result i32) (call $return_int) @@ -598,7 +598,7 @@ ) ) ) - (func $loadSigned (; 35 ;) (param $0 i32) + (func $loadSigned (; 35 ;) (; has Stack IR ;) (param $0 i32) (call $loadSigned (i32.load8_s (get_local $0) @@ -664,13 +664,13 @@ ) ) ) - (func $z (; 36 ;) (param $0 f32) + (func $z (; 36 ;) (; has Stack IR ;) (param $0 f32) (nop) ) - (func $w (; 37 ;) (result f64) + (func $w (; 37 ;) (; has Stack IR ;) (result f64) (f64.const 0) ) - (func $globalOpts (; 38 ;) + (func $globalOpts (; 38 ;) (; has Stack IR ;) (local $0 i32) (i32.store8 (i32.const 13) @@ -700,7 +700,7 @@ (get_local $0) ) ) - (func $dropCallImport (; 39 ;) + (func $dropCallImport (; 39 ;) (; has Stack IR ;) (if (call $return_int) (drop @@ -708,7 +708,7 @@ ) ) ) - (func $loophi (; 40 ;) (param $0 i32) (param $1 i32) + (func $loophi (; 40 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (local $2 i32) (loop $while-in (block $while-out @@ -738,7 +738,7 @@ ) ) ) - (func $loophi2 (; 41 ;) (result i32) + (func $loophi2 (; 41 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) @@ -771,7 +771,7 @@ ) (get_local $1) ) - (func $loophi2b (; 42 ;) (result i32) + (func $loophi2b (; 42 ;) (; has Stack IR ;) (result i32) (local $0 i32) (local $1 i32) (loop $label$continue$L7 @@ -803,7 +803,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading (; 43 ;) (param $0 i32) (result i32) + (func $relooperJumpThreading (; 43 ;) (; has Stack IR ;) (param $0 i32) (result i32) (block $__rjto$0 (block $__rjti$0 (if @@ -972,7 +972,7 @@ ) (get_local $0) ) - (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 44 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) + (func $relooperJumpThreading__ZN4game14preloadweaponsEv (; 44 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (loop $while-in (block $__rjto$1 (block $__rjti$1 @@ -999,7 +999,7 @@ (br $while-in) ) ) - (func $relooperJumpThreading_irreducible (; 45 ;) (param $0 i32) + (func $relooperJumpThreading_irreducible (; 45 ;) (; has Stack IR ;) (param $0 i32) (local $1 i32) (if (i32.eq @@ -1051,7 +1051,7 @@ ) ) ) - (func $__Z12multi_varargiz (; 46 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $__Z12multi_varargiz (; 46 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (if (get_local $3) (loop $while-in @@ -1068,10 +1068,10 @@ ) ) ) - (func $jumpThreadDrop (; 47 ;) (result i32) + (func $jumpThreadDrop (; 47 ;) (; has Stack IR ;) (result i32) (call $return_int) ) - (func $dropIgnoredImportInIf (; 48 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportInIf (; 48 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (if (get_local $0) (drop @@ -1081,7 +1081,7 @@ ) ) ) - (func $dropIgnoredImportsInIf (; 49 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $dropIgnoredImportsInIf (; 49 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (drop (if (result i32) (get_local $0) @@ -1094,7 +1094,7 @@ ) ) ) - (func $store_fround (; 50 ;) (param $0 i32) + (func $store_fround (; 50 ;) (; has Stack IR ;) (param $0 i32) (f64.store (i32.const 80) (f64.promote/f32 @@ -1104,7 +1104,7 @@ ) ) ) - (func $relocatableAndModules (; 51 ;) (result i32) + (func $relocatableAndModules (; 51 ;) (; has Stack IR ;) (result i32) (call_indirect (type $FUNCSIG$v) (i32.const 10) ) @@ -1117,7 +1117,7 @@ (i32.const 30) ) ) - (func $sqrts (; 52 ;) (param $0 f64) (result f64) + (func $sqrts (; 52 ;) (; has Stack IR ;) (param $0 f64) (result f64) (f64.add (f64.sqrt (get_local $0) @@ -1131,7 +1131,7 @@ ) ) ) - (func $keepAlive (; 53 ;) + (func $keepAlive (; 53 ;) (; has Stack IR ;) (drop (call $sqrts (f64.const 3.14159) @@ -1168,16 +1168,16 @@ ) ) ) - (func $vi (; 54 ;) (param $0 i32) + (func $vi (; 54 ;) (; has Stack IR ;) (param $0 i32) (nop) ) - (func $ii (; 55 ;) (param $0 i32) (result i32) + (func $ii (; 55 ;) (; has Stack IR ;) (param $0 i32) (result i32) (get_local $0) ) - (func $legalstub$conversions (; 56 ;) (param $0 i32) (param $1 f64) (param $2 f64) + (func $legalstub$conversions (; 56 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (nop) ) - (func $legalstub$frem_float (; 57 ;) (result f64) + (func $legalstub$frem_float (; 57 ;) (; has Stack IR ;) (result f64) (f64.promote/f32 (f32.demote/f64 (call $f64-rem @@ -1187,16 +1187,16 @@ ) ) ) - (func $legalstub$fr (; 58 ;) (param $0 f64) + (func $legalstub$fr (; 58 ;) (; has Stack IR ;) (param $0 f64) (nop) ) - (func $legalstub$ceiling_32_64 (; 59 ;) (param $0 f64) (param $1 f64) + (func $legalstub$ceiling_32_64 (; 59 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (nop) ) - (func $legalstub$bitcasts (; 60 ;) (param $0 i32) (param $1 f64) + (func $legalstub$bitcasts (; 60 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (nop) ) - (func $legalstub$exported_f32_user (; 61 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) + (func $legalstub$exported_f32_user (; 61 ;) (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f64) (f64.promote/f32 (f32.demote/f64 (get_local $1) diff --git a/test/unreachable-import_wasm-only.fromasm b/test/unreachable-import_wasm-only.fromasm index f15b613d5..ab59d9b8b 100644 --- a/test/unreachable-import_wasm-only.fromasm +++ b/test/unreachable-import_wasm-only.fromasm @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "unreachable-import_wasm-only.asm.js") (export "__ZN10WasmAssertC2Ev__async_cb" (func $__ZN10WasmAssertC2Ev__async_cb)) - (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (param $0 i32) + (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (; has Stack IR ;) (param $0 i32) (i32.store (i32.const 12) (i32.const 26) diff --git a/test/unreachable-import_wasm-only.fromasm.clamp b/test/unreachable-import_wasm-only.fromasm.clamp index f15b613d5..ab59d9b8b 100644 --- a/test/unreachable-import_wasm-only.fromasm.clamp +++ b/test/unreachable-import_wasm-only.fromasm.clamp @@ -3,7 +3,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (data (get_global $memoryBase) "unreachable-import_wasm-only.asm.js") (export "__ZN10WasmAssertC2Ev__async_cb" (func $__ZN10WasmAssertC2Ev__async_cb)) - (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (param $0 i32) + (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (; has Stack IR ;) (param $0 i32) (i32.store (i32.const 12) (i32.const 26) diff --git a/test/unreachable-import_wasm-only.fromasm.imprecise b/test/unreachable-import_wasm-only.fromasm.imprecise index c80b32eb0..1f079f7c1 100644 --- a/test/unreachable-import_wasm-only.fromasm.imprecise +++ b/test/unreachable-import_wasm-only.fromasm.imprecise @@ -1,7 +1,7 @@ (module (import "env" "memory" (memory $0 256 256)) (export "__ZN10WasmAssertC2Ev__async_cb" (func $__ZN10WasmAssertC2Ev__async_cb)) - (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (param $0 i32) + (func $__ZN10WasmAssertC2Ev__async_cb (; 0 ;) (; has Stack IR ;) (param $0 i32) (i32.store (i32.const 12) (i32.const 26) diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index 22414155e..0593e609a 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -19,7 +19,7 @@ (export "keepAlive" (func $keepAlive)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $loads (; 4 ;) + (func $loads (; 4 ;) (; has Stack IR ;) (drop (i32.load8_s (i32.const 100) @@ -131,7 +131,7 @@ ) ) ) - (func $stores (; 5 ;) + (func $stores (; 5 ;) (; has Stack IR ;) (local $0 i32) (local $1 f64) (local $2 f32) @@ -224,7 +224,7 @@ (get_local $1) ) ) - (func $test (; 6 ;) + (func $test (; 6 ;) (; has Stack IR ;) (local $0 f32) (local $1 i32) (set_local $1 @@ -233,7 +233,7 @@ ) ) ) - (func $i64s-div (; 7 ;) (param $0 i64) (param $1 i64) (result i64) + (func $i64s-div (; 7 ;) (; has Stack IR ;) (param $0 i64) (param $1 i64) (result i64) (if (result i64) (i64.eqz (get_local $1) @@ -258,7 +258,7 @@ ) ) ) - (func $f32-to-int64 (; 8 ;) (param $0 f32) (result i64) + (func $f32-to-int64 (; 8 ;) (; has Stack IR ;) (param $0 f32) (result i64) (if (result i64) (f32.ne (get_local $0) @@ -284,7 +284,7 @@ ) ) ) - (func $f64-to-int64 (; 9 ;) (param $0 f64) (result i64) + (func $f64-to-int64 (; 9 ;) (; has Stack IR ;) (param $0 f64) (result i64) (if (result i64) (f64.ne (get_local $0) @@ -310,7 +310,7 @@ ) ) ) - (func $f32-to-uint64 (; 10 ;) (param $0 f32) (result i64) + (func $f32-to-uint64 (; 10 ;) (; has Stack IR ;) (param $0 f32) (result i64) (if (result i64) (f32.ne (get_local $0) @@ -336,7 +336,7 @@ ) ) ) - (func $f64-to-uint64 (; 11 ;) (param $0 f64) (result i64) + (func $f64-to-uint64 (; 11 ;) (; has Stack IR ;) (param $0 f64) (result i64) (if (result i64) (f64.ne (get_local $0) @@ -362,7 +362,7 @@ ) ) ) - (func $test64 (; 12 ;) + (func $test64 (; 12 ;) (; has Stack IR ;) (local $0 i64) (local $1 f32) (local $2 f64) @@ -461,7 +461,7 @@ ) ) ) - (func $imports (; 13 ;) (result i64) + (func $imports (; 13 ;) (; has Stack IR ;) (result i64) (call $legalfunc$illegalImport (f64.const -3.13159) (i64.const 94489280523) @@ -479,7 +479,7 @@ ) ) ) - (func $arg (; 14 ;) (param $0 i64) + (func $arg (; 14 ;) (; has Stack IR ;) (param $0 i64) (i64.store (i32.const 100) (get_local $0) @@ -488,7 +488,7 @@ (get_local $0) ) ) - (func $illegalParam (; 15 ;) (param $0 i32) (param $1 i64) (param $2 f64) + (func $illegalParam (; 15 ;) (; has Stack IR ;) (param $0 i32) (param $1 i64) (param $2 f64) (i64.store (i32.const 100) (get_local $1) @@ -499,12 +499,12 @@ (f64.const 12.34) ) ) - (func $call1 (; 16 ;) (param $0 i64) (result i64) + (func $call1 (; 16 ;) (; has Stack IR ;) (param $0 i64) (result i64) (call $call1 (get_local $0) ) ) - (func $call2 (; 17 ;) (param $0 i64) (result i64) + (func $call2 (; 17 ;) (; has Stack IR ;) (param $0 i64) (result i64) (drop (call $call2 (call $call2 @@ -514,13 +514,13 @@ ) (i64.const 245127260211081) ) - (func $ifValue32 (; 18 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ifValue32 (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call $ifValue32 (get_local $0) (get_local $1) ) ) - (func $switch64 (; 19 ;) (param $0 i64) (result i32) + (func $switch64 (; 19 ;) (; has Stack IR ;) (param $0 i64) (result i32) (block $switch (result i32) (block $switch-default (block $switch-case0 @@ -555,7 +555,7 @@ (i32.const 1) ) ) - (func $unreachable_leftovers (; 20 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $unreachable_leftovers (; 20 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (block $__rjto$0 (if (i32.eqz @@ -578,7 +578,7 @@ ) ) ) - (func $switch64TOOMUCH (; 21 ;) (param $0 i64) (result i32) + (func $switch64TOOMUCH (; 21 ;) (; has Stack IR ;) (param $0 i64) (result i32) (local $1 i32) (local $2 i64) (block $switch-default @@ -655,7 +655,7 @@ ) (i32.const 44) ) - (func $_memchr (; 22 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 22 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -886,7 +886,7 @@ (get_local $0) ) ) - (func $keepAlive (; 23 ;) + (func $keepAlive (; 23 ;) (; has Stack IR ;) (call $loads) (call $loads) (call $stores) @@ -980,7 +980,7 @@ ) ) ) - (func $legalstub$illegalParam (; 24 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) + (func $legalstub$illegalParam (; 24 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam (get_local $0) (i64.or @@ -997,13 +997,13 @@ (get_local $3) ) ) - (func $legalstub$illegalResult (; 25 ;) (result i32) + (func $legalstub$illegalResult (; 25 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) (i32.const 1) ) - (func $legalfunc$illegalImport (; 26 ;) (param $0 f64) (param $1 i64) (param $2 i32) + (func $legalfunc$illegalImport (; 26 ;) (; has Stack IR ;) (param $0 f64) (param $1 i64) (param $2 i32) (call $legalimport$illegalImport (get_local $0) (i32.wrap/i64 @@ -1018,7 +1018,7 @@ (get_local $2) ) ) - (func $legalfunc$_fabsf (; 27 ;) (param $0 f32) (result f32) + (func $legalfunc$_fabsf (; 27 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.demote/f64 (call $legalimport$_fabsf (f64.promote/f32 @@ -1027,7 +1027,7 @@ ) ) ) - (func $legalfunc$do_i64 (; 28 ;) (result i64) + (func $legalfunc$do_i64 (; 28 ;) (; has Stack IR ;) (result i64) (i64.or (i64.extend_u/i32 (call $legalimport$do_i64) @@ -1040,10 +1040,10 @@ ) ) ) - (func $getTempRet0 (; 29 ;) (result i32) + (func $getTempRet0 (; 29 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 30 ;) (param $0 i32) + (func $setTempRet0 (; 30 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) diff --git a/test/wasm-only.fromasm.clamp b/test/wasm-only.fromasm.clamp index 22414155e..0593e609a 100644 --- a/test/wasm-only.fromasm.clamp +++ b/test/wasm-only.fromasm.clamp @@ -19,7 +19,7 @@ (export "keepAlive" (func $keepAlive)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $loads (; 4 ;) + (func $loads (; 4 ;) (; has Stack IR ;) (drop (i32.load8_s (i32.const 100) @@ -131,7 +131,7 @@ ) ) ) - (func $stores (; 5 ;) + (func $stores (; 5 ;) (; has Stack IR ;) (local $0 i32) (local $1 f64) (local $2 f32) @@ -224,7 +224,7 @@ (get_local $1) ) ) - (func $test (; 6 ;) + (func $test (; 6 ;) (; has Stack IR ;) (local $0 f32) (local $1 i32) (set_local $1 @@ -233,7 +233,7 @@ ) ) ) - (func $i64s-div (; 7 ;) (param $0 i64) (param $1 i64) (result i64) + (func $i64s-div (; 7 ;) (; has Stack IR ;) (param $0 i64) (param $1 i64) (result i64) (if (result i64) (i64.eqz (get_local $1) @@ -258,7 +258,7 @@ ) ) ) - (func $f32-to-int64 (; 8 ;) (param $0 f32) (result i64) + (func $f32-to-int64 (; 8 ;) (; has Stack IR ;) (param $0 f32) (result i64) (if (result i64) (f32.ne (get_local $0) @@ -284,7 +284,7 @@ ) ) ) - (func $f64-to-int64 (; 9 ;) (param $0 f64) (result i64) + (func $f64-to-int64 (; 9 ;) (; has Stack IR ;) (param $0 f64) (result i64) (if (result i64) (f64.ne (get_local $0) @@ -310,7 +310,7 @@ ) ) ) - (func $f32-to-uint64 (; 10 ;) (param $0 f32) (result i64) + (func $f32-to-uint64 (; 10 ;) (; has Stack IR ;) (param $0 f32) (result i64) (if (result i64) (f32.ne (get_local $0) @@ -336,7 +336,7 @@ ) ) ) - (func $f64-to-uint64 (; 11 ;) (param $0 f64) (result i64) + (func $f64-to-uint64 (; 11 ;) (; has Stack IR ;) (param $0 f64) (result i64) (if (result i64) (f64.ne (get_local $0) @@ -362,7 +362,7 @@ ) ) ) - (func $test64 (; 12 ;) + (func $test64 (; 12 ;) (; has Stack IR ;) (local $0 i64) (local $1 f32) (local $2 f64) @@ -461,7 +461,7 @@ ) ) ) - (func $imports (; 13 ;) (result i64) + (func $imports (; 13 ;) (; has Stack IR ;) (result i64) (call $legalfunc$illegalImport (f64.const -3.13159) (i64.const 94489280523) @@ -479,7 +479,7 @@ ) ) ) - (func $arg (; 14 ;) (param $0 i64) + (func $arg (; 14 ;) (; has Stack IR ;) (param $0 i64) (i64.store (i32.const 100) (get_local $0) @@ -488,7 +488,7 @@ (get_local $0) ) ) - (func $illegalParam (; 15 ;) (param $0 i32) (param $1 i64) (param $2 f64) + (func $illegalParam (; 15 ;) (; has Stack IR ;) (param $0 i32) (param $1 i64) (param $2 f64) (i64.store (i32.const 100) (get_local $1) @@ -499,12 +499,12 @@ (f64.const 12.34) ) ) - (func $call1 (; 16 ;) (param $0 i64) (result i64) + (func $call1 (; 16 ;) (; has Stack IR ;) (param $0 i64) (result i64) (call $call1 (get_local $0) ) ) - (func $call2 (; 17 ;) (param $0 i64) (result i64) + (func $call2 (; 17 ;) (; has Stack IR ;) (param $0 i64) (result i64) (drop (call $call2 (call $call2 @@ -514,13 +514,13 @@ ) (i64.const 245127260211081) ) - (func $ifValue32 (; 18 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ifValue32 (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call $ifValue32 (get_local $0) (get_local $1) ) ) - (func $switch64 (; 19 ;) (param $0 i64) (result i32) + (func $switch64 (; 19 ;) (; has Stack IR ;) (param $0 i64) (result i32) (block $switch (result i32) (block $switch-default (block $switch-case0 @@ -555,7 +555,7 @@ (i32.const 1) ) ) - (func $unreachable_leftovers (; 20 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $unreachable_leftovers (; 20 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (block $__rjto$0 (if (i32.eqz @@ -578,7 +578,7 @@ ) ) ) - (func $switch64TOOMUCH (; 21 ;) (param $0 i64) (result i32) + (func $switch64TOOMUCH (; 21 ;) (; has Stack IR ;) (param $0 i64) (result i32) (local $1 i32) (local $2 i64) (block $switch-default @@ -655,7 +655,7 @@ ) (i32.const 44) ) - (func $_memchr (; 22 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 22 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -886,7 +886,7 @@ (get_local $0) ) ) - (func $keepAlive (; 23 ;) + (func $keepAlive (; 23 ;) (; has Stack IR ;) (call $loads) (call $loads) (call $stores) @@ -980,7 +980,7 @@ ) ) ) - (func $legalstub$illegalParam (; 24 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) + (func $legalstub$illegalParam (; 24 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam (get_local $0) (i64.or @@ -997,13 +997,13 @@ (get_local $3) ) ) - (func $legalstub$illegalResult (; 25 ;) (result i32) + (func $legalstub$illegalResult (; 25 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) (i32.const 1) ) - (func $legalfunc$illegalImport (; 26 ;) (param $0 f64) (param $1 i64) (param $2 i32) + (func $legalfunc$illegalImport (; 26 ;) (; has Stack IR ;) (param $0 f64) (param $1 i64) (param $2 i32) (call $legalimport$illegalImport (get_local $0) (i32.wrap/i64 @@ -1018,7 +1018,7 @@ (get_local $2) ) ) - (func $legalfunc$_fabsf (; 27 ;) (param $0 f32) (result f32) + (func $legalfunc$_fabsf (; 27 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.demote/f64 (call $legalimport$_fabsf (f64.promote/f32 @@ -1027,7 +1027,7 @@ ) ) ) - (func $legalfunc$do_i64 (; 28 ;) (result i64) + (func $legalfunc$do_i64 (; 28 ;) (; has Stack IR ;) (result i64) (i64.or (i64.extend_u/i32 (call $legalimport$do_i64) @@ -1040,10 +1040,10 @@ ) ) ) - (func $getTempRet0 (; 29 ;) (result i32) + (func $getTempRet0 (; 29 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 30 ;) (param $0 i32) + (func $setTempRet0 (; 30 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index e79bbc901..6077f9429 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -17,7 +17,7 @@ (export "keepAlive" (func $keepAlive)) (export "getTempRet0" (func $getTempRet0)) (export "setTempRet0" (func $setTempRet0)) - (func $stores (; 4 ;) + (func $stores (; 4 ;) (; has Stack IR ;) (local $0 i32) (local $1 f64) (local $2 f32) @@ -110,7 +110,7 @@ (get_local $1) ) ) - (func $test (; 5 ;) + (func $test (; 5 ;) (; has Stack IR ;) (local $0 f32) (local $1 i32) (set_local $1 @@ -119,7 +119,7 @@ ) ) ) - (func $test64 (; 6 ;) + (func $test64 (; 6 ;) (; has Stack IR ;) (local $0 i64) (local $1 i32) (local $2 i64) @@ -161,7 +161,7 @@ ) ) ) - (func $imports (; 7 ;) (result i64) + (func $imports (; 7 ;) (; has Stack IR ;) (result i64) (call $legalfunc$illegalImport (f64.const -3.13159) (i64.const 94489280523) @@ -179,7 +179,7 @@ ) ) ) - (func $arg (; 8 ;) (param $0 i64) + (func $arg (; 8 ;) (; has Stack IR ;) (param $0 i64) (i64.store (i32.const 100) (get_local $0) @@ -188,7 +188,7 @@ (get_local $0) ) ) - (func $illegalParam (; 9 ;) (param $0 i32) (param $1 i64) (param $2 f64) + (func $illegalParam (; 9 ;) (; has Stack IR ;) (param $0 i32) (param $1 i64) (param $2 f64) (i64.store (i32.const 100) (get_local $1) @@ -199,12 +199,12 @@ (f64.const 12.34) ) ) - (func $call1 (; 10 ;) (param $0 i64) (result i64) + (func $call1 (; 10 ;) (; has Stack IR ;) (param $0 i64) (result i64) (call $call1 (get_local $0) ) ) - (func $call2 (; 11 ;) (param $0 i64) (result i64) + (func $call2 (; 11 ;) (; has Stack IR ;) (param $0 i64) (result i64) (drop (call $call2 (call $call2 @@ -214,13 +214,13 @@ ) (i64.const 245127260211081) ) - (func $ifValue32 (; 12 ;) (param $0 i32) (param $1 i32) (result i32) + (func $ifValue32 (; 12 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) (call $ifValue32 (get_local $0) (get_local $1) ) ) - (func $switch64 (; 13 ;) (param $0 i64) (result i32) + (func $switch64 (; 13 ;) (; has Stack IR ;) (param $0 i64) (result i32) (block $switch (result i32) (block $switch-default (block $switch-case0 @@ -255,7 +255,7 @@ (i32.const 1) ) ) - (func $unreachable_leftovers (; 14 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $unreachable_leftovers (; 14 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (block $__rjto$0 (if (i32.eqz @@ -278,7 +278,7 @@ ) ) ) - (func $switch64TOOMUCH (; 15 ;) (param $0 i64) (result i32) + (func $switch64TOOMUCH (; 15 ;) (; has Stack IR ;) (param $0 i64) (result i32) (local $1 i32) (local $2 i64) (block $switch-default @@ -355,7 +355,7 @@ ) (i32.const 44) ) - (func $_memchr (; 16 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $_memchr (; 16 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -586,7 +586,7 @@ (get_local $0) ) ) - (func $keepAlive (; 17 ;) + (func $keepAlive (; 17 ;) (; has Stack IR ;) (call $stores) (call $stores) (call $test) @@ -678,7 +678,7 @@ ) ) ) - (func $legalstub$illegalParam (; 18 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) + (func $legalstub$illegalParam (; 18 ;) (; has Stack IR ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam (get_local $0) (i64.or @@ -695,13 +695,13 @@ (get_local $3) ) ) - (func $legalstub$illegalResult (; 19 ;) (result i32) + (func $legalstub$illegalResult (; 19 ;) (; has Stack IR ;) (result i32) (set_global $tempRet0 (i32.const 2) ) (i32.const 1) ) - (func $legalfunc$illegalImport (; 20 ;) (param $0 f64) (param $1 i64) (param $2 i32) + (func $legalfunc$illegalImport (; 20 ;) (; has Stack IR ;) (param $0 f64) (param $1 i64) (param $2 i32) (call $legalimport$illegalImport (get_local $0) (i32.wrap/i64 @@ -716,7 +716,7 @@ (get_local $2) ) ) - (func $legalfunc$_fabsf (; 21 ;) (param $0 f32) (result f32) + (func $legalfunc$_fabsf (; 21 ;) (; has Stack IR ;) (param $0 f32) (result f32) (f32.demote/f64 (call $legalimport$_fabsf (f64.promote/f32 @@ -725,7 +725,7 @@ ) ) ) - (func $legalfunc$do_i64 (; 22 ;) (result i64) + (func $legalfunc$do_i64 (; 22 ;) (; has Stack IR ;) (result i64) (i64.or (i64.extend_u/i32 (call $legalimport$do_i64) @@ -738,10 +738,10 @@ ) ) ) - (func $getTempRet0 (; 23 ;) (result i32) + (func $getTempRet0 (; 23 ;) (; has Stack IR ;) (result i32) (get_global $tempRet0) ) - (func $setTempRet0 (; 24 ;) (param $0 i32) + (func $setTempRet0 (; 24 ;) (; has Stack IR ;) (param $0 i32) (set_global $tempRet0 (get_local $0) ) |