summaryrefslogtreecommitdiff
path: root/src/passes/stringify-walker.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/stringify-walker.h')
-rw-r--r--src/passes/stringify-walker.h94
1 files changed, 60 insertions, 34 deletions
diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h
index 6095eb7ad..eb4a4482b 100644
--- a/src/passes/stringify-walker.h
+++ b/src/passes/stringify-walker.h
@@ -19,8 +19,10 @@
#include "ir/iteration.h"
#include "ir/module-utils.h"
+#include "ir/stack-utils.h"
#include "ir/utils.h"
#include "support/suffix_tree.h"
+#include "wasm-ir-builder.h"
#include "wasm-traversal.h"
#include <queue>
@@ -51,13 +53,14 @@ namespace wasm {
*
* Of note:
* - The visits to if-True on line 4 and if-False on line 5 are deferred until
- * after the rest of the siblings of the if expression on line 2 are visited
+ * after the rest of the siblings of the if expression on line 2 are
+ * visited.
* - The if-condition (i32.const 0) on line 3 is visited before the if
* expression on line 2. Similarly, the if-condition (i32.const 1) on line
* 11 is visited before the if expression on line 10.
* - The add (line 7) binary operator's left and right children (lines 8 - 9)
* are visited first as they need to be on the stack before the add
- * operation is executed
+ * operation is executed.
*/
template<typename SubType>
@@ -72,7 +75,7 @@ struct StringifyWalker
};
struct BlockStart {
- Block* curr;
+ Block* block;
};
struct IfStart {
@@ -129,34 +132,38 @@ struct StringifyWalker
return SeparatorReason(TryBodyStart{});
}
static SeparatorReason makeEnd() { return SeparatorReason(End{}); }
- bool isFuncStart() { return std::get_if<FuncStart>(&reason); }
- bool isBlockStart() { return std::get_if<BlockStart>(&reason); }
- bool isIfStart() { return std::get_if<IfStart>(&reason); }
- bool isElseStart() { return std::get_if<ElseStart>(&reason); }
- bool isLoopStart() { return std::get_if<LoopStart>(&reason); }
- bool isTryBodyStart() { return std::get_if<TryBodyStart>(&reason); }
- bool isTryCatchStart() { return std::get_if<TryCatchStart>(&reason); }
- bool isEnd() { return std::get_if<End>(&reason); }
+ FuncStart* getFuncStart() { return std::get_if<FuncStart>(&reason); }
+ BlockStart* getBlockStart() { return std::get_if<BlockStart>(&reason); }
+ IfStart* getIfStart() { return std::get_if<IfStart>(&reason); }
+ ElseStart* getElseStart() { return std::get_if<ElseStart>(&reason); }
+ LoopStart* getLoopStart() { return std::get_if<LoopStart>(&reason); }
+ TryBodyStart* getTryBodyStart() {
+ return std::get_if<TryBodyStart>(&reason);
+ }
+ TryCatchStart* getTryCatchStart() {
+ return std::get_if<TryCatchStart>(&reason);
+ }
+ End* getEnd() { return std::get_if<End>(&reason); }
};
friend std::ostream&
operator<<(std::ostream& o,
typename StringifyWalker::SeparatorReason reason) {
- if (reason.isFuncStart()) {
+ if (reason.getFuncStart()) {
return o << "Func Start";
- } else if (reason.isBlockStart()) {
+ } else if (reason.getBlockStart()) {
return o << "Block Start";
- } else if (reason.isIfStart()) {
+ } else if (reason.getIfStart()) {
return o << "If Start";
- } else if (reason.isElseStart()) {
+ } else if (reason.getElseStart()) {
return o << "Else Start";
- } else if (reason.isLoopStart()) {
+ } else if (reason.getLoopStart()) {
return o << "Loop Start";
- } else if (reason.isTryBodyStart()) {
+ } else if (reason.getTryBodyStart()) {
return o << "Try Body Start";
- } else if (reason.isTryCatchStart()) {
+ } else if (reason.getTryCatchStart()) {
return o << "Try Catch Start";
- } else if (reason.isEnd()) {
+ } else if (reason.getEnd()) {
return o << "End";
}
@@ -214,10 +221,10 @@ struct HashStringifyWalker : public StringifyWalker<HashStringifyWalker> {
// Expression or a separator to mark the end of control flow.
std::vector<uint32_t> hashString;
// A monotonic counter used to ensure that unique expressions in the
- // module are assigned a unique value in the hashString
+ // module are assigned a unique value in the hashString.
uint32_t nextVal = 0;
// A monotonic counter used to ensure that each separator in the
- // module is assigned a unique value in the hashString
+ // module is assigned a unique value in the hashString.
int32_t nextSeparatorVal = -1;
// Contains a mapping of expression pointer to value to ensure we
// use the same value for matching expressions. A custom hasher and
@@ -229,25 +236,44 @@ struct HashStringifyWalker : public StringifyWalker<HashStringifyWalker> {
void addUniqueSymbol(SeparatorReason reason);
void visitExpression(Expression* curr);
+ // Converts the idx from relative to the beginning of the program to
+ // relative to its enclosing function, and returns the name of its function.
+ std::pair<uint32_t, Name> makeRelative(uint32_t idx) const;
+
+private:
+ // Contains the indices that mark the start of each function.
+ std::set<uint32_t> funcIndices;
+ // Maps the start idx of each function to the function name.
+ std::map<uint32_t, Name> idxToFuncName;
};
+struct OutliningSequence {
+ unsigned startIdx;
+ unsigned endIdx;
+ Name func;
+
+ OutliningSequence(unsigned startIdx, unsigned endIdx, Name func)
+ : startIdx(startIdx), endIdx(endIdx), func(func) {}
+};
+
+using Substrings = std::vector<SuffixTree::RepeatedSubstring>;
+
// Functions that filter vectors of SuffixTree::RepeatedSubstring
struct StringifyProcessor {
- static std::vector<SuffixTree::RepeatedSubstring>
- dedupe(const std::vector<SuffixTree::RepeatedSubstring>& substrings);
+ static Substrings repeatSubstrings(std::vector<uint32_t>& hashString);
+ static Substrings dedupe(const Substrings& substrings);
// Filter is the general purpose function backing subsequent filter functions.
// It can be used directly, but generally prefer a wrapper function
- // to encapsulate your condition and make it available for tests
- static std::vector<SuffixTree::RepeatedSubstring>
- filter(const std::vector<SuffixTree::RepeatedSubstring>& substrings,
- const std::vector<Expression*> exprs,
- std::function<bool(const Expression*)> condition);
- static std::vector<SuffixTree::RepeatedSubstring>
- filterLocalSets(const std::vector<SuffixTree::RepeatedSubstring>& substrings,
- const std::vector<Expression*> exprs);
- static std::vector<SuffixTree::RepeatedSubstring>
- filterBranches(const std::vector<SuffixTree::RepeatedSubstring>& substrings,
- const std::vector<Expression*> exprs);
+ // to encapsulate your condition and make it available for tests.
+ static Substrings filter(const Substrings& substrings,
+ const std::vector<Expression*>& exprs,
+ std::function<bool(const Expression*)> condition);
+ static Substrings filterLocalSets(const Substrings& substrings,
+ const std::vector<Expression*>& exprs);
+ static Substrings filterLocalGets(const Substrings& substrings,
+ const std::vector<Expression*>& exprs);
+ static Substrings filterBranches(const Substrings& substrings,
+ const std::vector<Expression*>& exprs);
};
} // namespace wasm