summaryrefslogtreecommitdiff
path: root/src/ir/properties.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-05-14 10:10:54 -0700
committerGitHub <noreply@github.com>2024-05-14 10:10:54 -0700
commit4ca05f765ca6ec99b7582d357520ca217265677d (patch)
treeacedda233346f51d2314d93748209bce60f25f1e /src/ir/properties.cpp
parent020d08e01ff506099c8293e69cd03f5f75f562d9 (diff)
downloadbinaryen-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.cpp45
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) {