hi
diff --git a/src/passes/Outlining.cpp b/src/passes/Outlining.cpp index 91154b1..2a00b12 100644 --- a/src/passes/Outlining.cpp +++ b/src/passes/Outlining.cpp
@@ -21,8 +21,6 @@ #include "support/suffix_tree.h" #include "wasm.h" -#define OUTLINING_DEBUG 0 - #if OUTLINING_DEBUG #define DBG(statement) statement #else @@ -93,23 +91,24 @@ DBG(std::string desc); if (auto curr = reason.getBlockStart()) { - ASSERT_OK(existingBuilder.visitBlockStart(curr->block)); DBG(desc = "Block Start at "); + ASSERT_OK(existingBuilder.visitBlockStart(curr->block)); } else if (auto curr = reason.getIfStart()) { // IR builder needs the condition of the If pushed onto the builder before // visitIfStart(), which will expect to be able to pop the condition. // This is always okay to do because the correct condition was installed // onto the If when the outer scope was visited. existingBuilder.push(curr->iff->condition); - ASSERT_OK(existingBuilder.visitIfStart(curr->iff)); DBG(desc = "If Start at "); + ASSERT_OK(existingBuilder.visitIfStart(curr->iff)); } else if (reason.getElseStart()) { - ASSERT_OK(existingBuilder.visitElse()); DBG(desc = "Else Start at "); + ASSERT_OK(existingBuilder.visitElse()); } else if (auto curr = reason.getLoopStart()) { - ASSERT_OK(existingBuilder.visitLoopStart(curr->loop)); DBG(desc = "Loop Start at "); + ASSERT_OK(existingBuilder.visitLoopStart(curr->loop)); } else if (reason.getEnd()) { + DBG(desc = "End at "); ASSERT_OK(existingBuilder.visitEnd()); // Reset the function in case we just ended the function scope. existingBuilder.setFunction(func); @@ -122,7 +121,6 @@ // its expressions off the stack, so we must call build() after visitEnd() // to clear the internal stack IRBuilder manages. ASSERT_OK(existingBuilder.build()); - DBG(desc = "End at "); } else { DBG(desc = "addUniqueSymbol for unimplemented control flow "); WASM_UNREACHABLE("unimplemented control flow"); @@ -207,18 +205,24 @@ void transitionToInSeq() { Function* outlinedFunc = getModule()->getFunction(sequences[seqCounter].func); + DBG(std::cerr << "\ncreated outlined fn: " << outlinedFunc->name << "\n"); ASSERT_OK(outlinedBuilder.visitFunctionStart(outlinedFunc)); // Add a local.get instruction for every parameter of the outlined function. Signature sig = outlinedFunc->type.getSignature(); + DBG(std::cerr << outlinedFunc->name << " takes " << sig.params.size() + << " parameters\n"); for (Index i = 0; i < sig.params.size(); i++) { + DBG(std::cerr << "adding local.get $" << i << " to " << &outlinedBuilder + << "\n"); ASSERT_OK(outlinedBuilder.makeLocalGet(i)); } // Make a call from the existing function to the outlined function. This // call will replace the instructions moved to the outlined function. + DBG(std::cerr << "\nadding call to outlined fn: " << outlinedFunc->name + << "\n"); ASSERT_OK(existingBuilder.makeCall(outlinedFunc->name, false)); - DBG(std::cerr << "\ncreated outlined fn: " << outlinedFunc->name << "\n"); } void transitionToInSkipSeq() { @@ -302,7 +306,13 @@ // are relative to the enclosing function while substrings have indices // relative to the entire program. auto sequences = makeSequences(module, substrings, stringify); - outline(module, sequences); + outline(module, + sequences +#if OUTLINING_DEBUG + , + stringify +#endif + ); // Position the outlined functions first in the functions vector to make // the outlining lit tests far more readable. moveOutlinedFunctions(module, substrings.size()); @@ -351,15 +361,28 @@ // sequence relative to its function is better for outlining because we // walk functions. auto [relativeIdx, existingFunc] = stringify.makeRelative(seqIdx); - auto seq = - OutliningSequence(relativeIdx, relativeIdx + substring.Length, func); + auto seq = OutliningSequence(relativeIdx, + relativeIdx + substring.Length, + func +#if OUTLINING_DEBUG + , + seqIdx, + substring.Length +#endif + ); seqByFunc[existingFunc].push_back(seq); } } return seqByFunc; } - void outline(Module* module, Sequences seqByFunc) { + void outline(Module* module, + Sequences seqByFunc +#if OUTLINING_DEBUG + , + const HashStringifyWalker& stringify +#endif + ) { // TODO: Make this a function-parallel sub-pass. std::vector<Name> keys(seqByFunc.size()); std::transform(seqByFunc.begin(), @@ -379,6 +402,11 @@ }); ReconstructStringifyWalker reconstruct(module, module->getFunction(func)); reconstruct.sequences = std::move(seqByFunc[func]); + DBG(printReconstruct(module, + stringify.hashString, + stringify.exprs, + func, + reconstruct.sequences)); reconstruct.doWalkFunction(module->getFunction(func)); } } @@ -414,6 +442,31 @@ } } } + + void printReconstruct(Module* module, + const std::vector<uint32_t>& hashString, + const std::vector<Expression*>& exprs, + Name existingFunc, + const std::vector<OutliningSequence>& seqs) { + std::cerr << "\n\nReconstructing existing fn: " << existingFunc << "\n"; + std::cerr << "moving sequences: " << "\n"; + for (auto& seq : seqs) { + for (Index idx = seq.originalIdx; idx < seq.originalIdx + seq.length; + idx++) { + Expression* expr = exprs[idx]; + if (expr == nullptr) { + std::cerr << "unique symbol\n"; + } else { + std::cerr << idx << " - " << hashString[idx] << " - " << seq.startIdx + << " : " << ShallowExpression{expr} << "\n"; + } + } + std::cerr << "to outlined function: " << seq.func << "\n"; + auto outlinedFunction = module->getFunction(seq.func); + std::cerr << "with signature: " << outlinedFunction->type.toString() + << "\n"; + } + } #endif };
diff --git a/src/passes/stringify-walker-impl.h b/src/passes/stringify-walker-impl.h index 040770f..cca2a34 100644 --- a/src/passes/stringify-walker-impl.h +++ b/src/passes/stringify-walker-impl.h
@@ -16,14 +16,6 @@ #include "stringify-walker.h" -#define STRINGIFY_DEBUG 0 - -#if STRINGIFY_DEBUG -#define DBG(statement) statement -#else -#define DBG(statement) -#endif - #ifndef wasm_passes_stringify_walker_impl_h #define wasm_passes_stringify_walker_impl_h @@ -52,8 +44,6 @@ Expression* curr = *currp; if (Properties::isControlFlowStructure(curr)) { self->controlFlowQueue.push(curr); - DBG(std::cerr << "controlFlowQueue.push: " << ShallowExpression{curr} - << ", " << curr << "\n"); self->pushTask(doVisitExpression, currp); // The if-condition is a value child consumed by the if control flow, which // makes the if-condition a true sibling rather than part of its contents in @@ -72,8 +62,6 @@ auto& queue = controlFlowQueue; Expression* curr = queue.front(); queue.pop(); - DBG(std::cerr << "controlFlowQueue.pop: " << ShallowExpression{curr} << ", " - << curr << "\n"); // TODO: Issue #5796, Make a ControlChildIterator switch (curr->_id) {
diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h index c8a3285..92ed007 100644 --- a/src/passes/stringify-walker.h +++ b/src/passes/stringify-walker.h
@@ -27,6 +27,8 @@ #include "wasm-traversal.h" #include <queue> +#define OUTLINING_DEBUG 1 + namespace wasm { /* @@ -254,9 +256,27 @@ unsigned startIdx; unsigned endIdx; Name func; +#if OUTLINING_DEBUG + unsigned originalIdx; + unsigned length; +#endif - OutliningSequence(unsigned startIdx, unsigned endIdx, Name func) - : startIdx(startIdx), endIdx(endIdx), func(func) {} + OutliningSequence(unsigned startIdx, + unsigned endIdx, + Name func +#if OUTLINING_DEBUG + , + unsigned originalIdx, + unsigned length +#endif + ) + : startIdx(startIdx), endIdx(endIdx), func(func) +#if OUTLINING_DEBUG + , + originalIdx(originalIdx), length(length) +#endif + { + } }; using Substrings = std::vector<SuffixTree::RepeatedSubstring>;
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 9371046..81b79d8 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp
@@ -547,7 +547,9 @@ if (scope.unreachable) { return builder.builder.makeUnreachable(); } - return Err{"popping from empty stack"}; + std::stringstream ss; + ss << this; + return Err{"popping from empty stack" + ss.str()}; } CHECK_ERR(builder.packageHoistedValue(*hoisted, size)); @@ -829,7 +831,9 @@ auto hoisted = hoistLastValue(); CHECK_ERR(hoisted); if (!hoisted) { - return Err{"popping from empty stack"}; + std::stringstream ss; + ss << this; + return Err{"popping from empty stack" + ss.str()}; } if (type.isTuple()) {