diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/ExtractFunction.cpp | 10 | ||||
-rw-r--r-- | src/passes/RelooperJumpThreading.cpp | 16 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp index b342efc3b..b91d2c406 100644 --- a/src/passes/ExtractFunction.cpp +++ b/src/passes/ExtractFunction.cpp @@ -23,12 +23,18 @@ namespace wasm { -Name TO_LEAVE("_bytearray_join"); // TODO: commandline param struct ExtractFunction : public Pass { void run(PassRunner* runner, Module* module) override { + auto* leave = getenv("BYN_LEAVE"); + if (!leave) { + std::cerr << "usage: set BYN_LEAVE in the env\n"; + abort(); + } + Name LEAVE(leave); + std::cerr << "keeping " << LEAVE << "\n"; for (auto& func : module->functions) { - if (func->name != TO_LEAVE) { + if (func->name != LEAVE) { // wipe out the body func->body = module->allocator.alloc<Unreachable>(); } diff --git a/src/passes/RelooperJumpThreading.cpp b/src/passes/RelooperJumpThreading.cpp index 7f74220d5..bd257c568 100644 --- a/src/passes/RelooperJumpThreading.cpp +++ b/src/passes/RelooperJumpThreading.cpp @@ -182,7 +182,21 @@ private: assert(labelChecksInOrigin[num] == 0); if (labelSetsInOrigin[num] != labelSets[num]) { assert(labelSetsInOrigin[num] < labelSets[num]); - return true; // label set somewhere outside of origin TODO: if set in the if body here, it might be safe in some cases + // the label is set outside of the origin + // if the only other location is inside the if body, then it is ok - it must be in a loop + // and returning to the top of the loop body, so we don't need to do anything for that + // label setting anyhow + std::map<Index, Index> labelChecksInIfTrue; + std::map<Index, Index> labelSetsInIfTrue; + LabelUseFinder finder(labelIndex, labelChecksInIfTrue, labelSetsInIfTrue); + finder.walk(iff->ifTrue); + if (labelSetsInOrigin[num] + labelSetsInIfTrue[num] < labelSets[num]) { + // label set somewhere we can't see now, could be irreducible control flow + // TODO: one case where this happens is instead of an if-chain, we have + // ifs and a switch on label|0, in separate elements. perhaps not + // emitting switches on label|0 in the relooper would avoid that. + return true; + } } iff = isLabelCheckingIf(iff->ifFalse, labelIndex); } |