diff options
-rw-r--r-- | src/passes/hash-stringify-walker.cpp | 21 | ||||
-rw-r--r-- | src/passes/stringify-walker.h | 13 | ||||
-rw-r--r-- | test/gtest/stringify.cpp | 151 |
3 files changed, 125 insertions, 60 deletions
diff --git a/src/passes/hash-stringify-walker.cpp b/src/passes/hash-stringify-walker.cpp index beae3bf44..abcd07162 100644 --- a/src/passes/hash-stringify-walker.cpp +++ b/src/passes/hash-stringify-walker.cpp @@ -82,7 +82,7 @@ void HashStringifyWalker::visitExpression(Expression* curr) { // repeats come first and 2) these are more worthwhile to keep than subsequent // substrings of substrings, even if they appear more times. std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::dedupe( - const std::vector<SuffixTree::RepeatedSubstring>&& substrings) { + const std::vector<SuffixTree::RepeatedSubstring>& substrings) { std::unordered_set<uint32_t> seen; std::vector<SuffixTree::RepeatedSubstring> result; for (auto substring : substrings) { @@ -111,7 +111,7 @@ std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::dedupe( } std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::filter( - const std::vector<SuffixTree::RepeatedSubstring>&& substrings, + const std::vector<SuffixTree::RepeatedSubstring>& substrings, const std::vector<Expression*> exprs, std::function<bool(const Expression*)> condition) { @@ -166,4 +166,21 @@ std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::filter( return result; } +std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::filterLocalSets( + const std::vector<SuffixTree::RepeatedSubstring>& substrings, + const std::vector<Expression*> exprs) { + return StringifyProcessor::filter( + substrings, exprs, [](const Expression* curr) { + return curr->is<LocalSet>(); + }); +} + +std::vector<SuffixTree::RepeatedSubstring> StringifyProcessor::filterBranches( + const std::vector<SuffixTree::RepeatedSubstring>& substrings, + const std::vector<Expression*> exprs) { + return StringifyProcessor::filter( + substrings, exprs, [](const Expression* curr) { + return Properties::isBranch(curr) || curr->is<Return>(); + }); +} } // namespace wasm diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h index 55aa26940..6095eb7ad 100644 --- a/src/passes/stringify-walker.h +++ b/src/passes/stringify-walker.h @@ -234,11 +234,20 @@ struct HashStringifyWalker : public StringifyWalker<HashStringifyWalker> { // Functions that filter vectors of SuffixTree::RepeatedSubstring struct StringifyProcessor { static std::vector<SuffixTree::RepeatedSubstring> - dedupe(const std::vector<SuffixTree::RepeatedSubstring>&& substrings); + dedupe(const std::vector<SuffixTree::RepeatedSubstring>& 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, + 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); }; } // namespace wasm diff --git a/test/gtest/stringify.cpp b/test/gtest/stringify.cpp index 5b5e650e6..8e854ee4b 100644 --- a/test/gtest/stringify.cpp +++ b/test/gtest/stringify.cpp @@ -9,7 +9,7 @@ using StringifyTest = PrintTest; TEST_F(StringifyTest, Print) { auto moduleText = R"wasm( - (module + (module (tag $catch_a (param i32)) (tag $catch_b (param i32)) (tag $catch_c (param i32)) @@ -53,7 +53,7 @@ TEST_F(StringifyTest, Print) { ) ) ) - ) + ) )wasm"; auto stringifyText = R"stringify(adding unique symbol for Func Start @@ -143,44 +143,44 @@ adding unique symbol for End static auto dupModuleText = R"wasm( (module - (func $a - (block $block_a - (drop (i32.const 20)) - (drop (i32.const 10)) - ) - (block $block_b - (drop (if (i32.const 0) - (i32.const 40) - (i32.const 5) - )) - ) - (block $block_c - (drop (if (i32.const 1) - (i32.const 30) - )) - ) - (block $block_d - (drop (i32.const 20)) - (drop (i32.const 10)) - ) - (block $block_e - (drop (if (i32.const 1) - (i32.const 30) - )) - ) - (block $block_f - (drop (if (i32.const 0) - (i32.const 30) - )) + (func $a + (block $block_a + (drop (i32.const 20)) + (drop (i32.const 10)) + ) + (block $block_b + (drop (if (i32.const 0) + (i32.const 40) + (i32.const 5) + )) + ) + (block $block_c + (drop (if (i32.const 1) + (i32.const 30) + )) + ) + (block $block_d + (drop (i32.const 20)) + (drop (i32.const 10)) + ) + (block $block_e + (drop (if (i32.const 1) + (i32.const 30) + )) + ) + (block $block_f + (drop (if (i32.const 0) + (i32.const 30) + )) + ) ) ) - ) )wasm"; std::vector<uint32_t> hashStringifyModule(Module* wasm) { HashStringifyWalker stringify = HashStringifyWalker(); stringify.walkModule(wasm); - return std::move(stringify.hashString); + return stringify.hashString; } TEST_F(StringifyTest, Stringify) { @@ -295,7 +295,7 @@ TEST_F(StringifyTest, DedupeSubstrings) { auto hashString = hashStringifyModule(&wasm); std::vector<SuffixTree::RepeatedSubstring> substrings = repeatSubstrings(hashString); - auto result = StringifyProcessor::dedupe(std::move(substrings)); + auto result = StringifyProcessor::dedupe(substrings); EXPECT_EQ( result, @@ -309,23 +309,23 @@ TEST_F(StringifyTest, DedupeSubstrings) { TEST_F(StringifyTest, FilterLocalSets) { static auto localSetModuleText = R"wasm( (module - (func $a (result i32) - (local $x i32) - (local.set $x - (i32.const 1) - ) - (i32.const 0) - (i32.const 1) - ) - (func $b (result i32) - (local $x i32) - (local.set $x - (i32.const 1) - ) - (i32.const 5) - (i32.const 0) - (i32.const 1) - ) + (func $a (result i32) + (local $x i32) + (local.set $x + (i32.const 1) + ) + (i32.const 0) + (i32.const 1) + ) + (func $b (result i32) + (local $x i32) + (local.set $x + (i32.const 1) + ) + (i32.const 5) + (i32.const 0) + (i32.const 1) + ) ) )wasm"; Module wasm; @@ -333,12 +333,9 @@ TEST_F(StringifyTest, FilterLocalSets) { HashStringifyWalker stringify = HashStringifyWalker(); stringify.walkModule(&wasm); auto substrings = repeatSubstrings(stringify.hashString); - auto result = StringifyProcessor::dedupe(std::move(substrings)); + auto result = StringifyProcessor::dedupe(substrings); - result = StringifyProcessor::filter( - std::move(substrings), stringify.exprs, [](const Expression* curr) { - return curr->is<LocalSet>(); - }); + result = StringifyProcessor::filterLocalSets(substrings, stringify.exprs); EXPECT_EQ( result, @@ -346,3 +343,45 @@ TEST_F(StringifyTest, FilterLocalSets) { // sequence i32.const 0, i32.const 1 appears at idx 6 and again at 16 SuffixTree::RepeatedSubstring{2u, (std::vector<unsigned>{6, 16})}})); } + +TEST_F(StringifyTest, FilterBranches) { + static auto branchesModuleText = R"wasm( + (module + (func $a (result i32) + (block $top (result i32) + (br $top) + ) + (i32.const 7) + (i32.const 1) + (i32.const 2) + (i32.const 4) + (i32.const 3) + (return) + ) + (func $b (result i32) + (block $top (result i32) + (br $top) + ) + (i32.const 0) + (i32.const 1) + (i32.const 2) + (i32.const 5) + (i32.const 3) + (return) + ) + ) + )wasm"; + Module wasm; + parseWast(wasm, branchesModuleText); + HashStringifyWalker stringify = HashStringifyWalker(); + stringify.walkModule(&wasm); + + auto substrings = repeatSubstrings(stringify.hashString); + auto result = StringifyProcessor::filterBranches(substrings, stringify.exprs); + + EXPECT_EQ( + result, + (std::vector<SuffixTree::RepeatedSubstring>{ + // sequence i32.const 1, i32.const 2 is at idx 6 and 21 + SuffixTree::RepeatedSubstring{2u, (std::vector<unsigned>{6, 21})}})); +} |