diff options
author | Alon Zakai <azakai@google.com> | 2024-05-14 10:10:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-14 10:10:54 -0700 |
commit | 4ca05f765ca6ec99b7582d357520ca217265677d (patch) | |
tree | acedda233346f51d2314d93748209bce60f25f1e /src/ir/properties.cpp | |
parent | 020d08e01ff506099c8293e69cd03f5f75f562d9 (diff) | |
download | binaryen-4ca05f765ca6ec99b7582d357520ca217265677d.tar.gz binaryen-4ca05f765ca6ec99b7582d357520ca217265677d.tar.bz2 binaryen-4ca05f765ca6ec99b7582d357520ca217265677d.zip |
LocalCSE: Check effects/generativity early (#6587)
Previously we checked late, and as a result might end up failing to optimize when
a sub-pattern could have worked. E.g.
(call
(A)
)
(call
(A)
)
The call cannot be optimized, but the A pattern repeats. Before this PR we'd
greedily focus on the entire call and then fail. After this PR we skip the call
before we commit to which patterns to try to optimize, so we succeed.
Add a isShallowlyGenerative helper here as we compute this step by step as
we go. Also remove a parameter to the generativity code (it did not use the
features it was passed).
Diffstat (limited to 'src/ir/properties.cpp')
-rw-r--r-- | src/ir/properties.cpp | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp index 05dae897e..1346f6cad 100644 --- a/src/ir/properties.cpp +++ b/src/ir/properties.cpp @@ -19,27 +19,40 @@ namespace wasm::Properties { -bool isGenerative(Expression* curr, FeatureSet features) { - struct Scanner : public PostWalker<Scanner> { - bool generative = false; +namespace { - void visitCall(Call* curr) { - // TODO: We could in principle look at the called function to see if it is - // generative. To do that we'd need to compute generativity like we - // compute global effects (we can't just peek from here, as the - // other function might be modified in parallel). - generative = true; - } - void visitCallIndirect(CallIndirect* curr) { generative = true; } - void visitCallRef(CallRef* curr) { generative = true; } - void visitStructNew(StructNew* curr) { generative = true; } - void visitArrayNew(ArrayNew* curr) { generative = true; } - void visitArrayNewFixed(ArrayNewFixed* curr) { generative = true; } - } scanner; +struct GenerativityScanner : public PostWalker<GenerativityScanner> { + bool generative = false; + + void visitCall(Call* curr) { + // TODO: We could in principle look at the called function to see if it is + // generative. To do that we'd need to compute generativity like we + // compute global effects (we can't just peek from here, as the + // other function might be modified in parallel). + generative = true; + } + void visitCallIndirect(CallIndirect* curr) { generative = true; } + void visitCallRef(CallRef* curr) { generative = true; } + void visitStructNew(StructNew* curr) { generative = true; } + void visitArrayNew(ArrayNew* curr) { generative = true; } + void visitArrayNewFixed(ArrayNewFixed* curr) { generative = true; } +}; + +} // anonymous namespace + +bool isGenerative(Expression* curr) { + GenerativityScanner scanner; scanner.walk(curr); return scanner.generative; } +// As above, but only checks |curr| and not children. +bool isShallowlyGenerative(Expression* curr) { + GenerativityScanner scanner; + scanner.visit(curr); + return scanner.generative; +} + // Checks an expression in a shallow manner (i.e., does not check children) as // to whether it is valid in a wasm constant expression. static bool isValidInConstantExpression(Module& wasm, Expression* expr) { |