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()) {