diff options
author | Alon Zakai <azakai@google.com> | 2021-08-03 15:08:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-03 15:08:00 -0700 |
commit | 4ba4d31eafb723a28503faffae1702940b6926ca (patch) | |
tree | f772824da56a880d21e3d820e8088ceef1996096 /src | |
parent | 221730366af40a3eb96fd99fcefefc30e4cd9739 (diff) | |
download | binaryen-4ba4d31eafb723a28503faffae1702940b6926ca.tar.gz binaryen-4ba4d31eafb723a28503faffae1702940b6926ca.tar.bz2 binaryen-4ba4d31eafb723a28503faffae1702940b6926ca.zip |
Refactor isSingleConstantExpression(). (#4047)
Define a "single constant expression" consistently, as a thing that is a
compile-time constant. Move I31New out of there, and also clean up
the function it is moved into, canInitializeGlobal(), to be consistent
in validating children.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/global-utils.h | 17 | ||||
-rw-r--r-- | src/ir/properties.h | 7 |
2 files changed, 17 insertions, 7 deletions
diff --git a/src/ir/global-utils.h b/src/ir/global-utils.h index 0d91dcbb5..cf0c8e1a9 100644 --- a/src/ir/global-utils.h +++ b/src/ir/global-utils.h @@ -20,6 +20,7 @@ #include <algorithm> #include <vector> +#include "ir/iteration.h" #include "ir/module-utils.h" #include "literal.h" #include "wasm.h" @@ -53,7 +54,7 @@ getGlobalInitializedToImport(Module& wasm, Name module, Name base) { return ret; } -inline bool canInitializeGlobal(const Expression* curr) { +inline bool canInitializeGlobal(Expression* curr) { if (auto* tuple = curr->dynCast<TupleMake>()) { for (auto* op : tuple->operands) { if (!canInitializeGlobal(op)) { @@ -62,9 +63,17 @@ inline bool canInitializeGlobal(const Expression* curr) { } return true; } - return Properties::isSingleConstantExpression(curr) || - curr->is<GlobalGet>() || curr->is<RttCanon>() || curr->is<RttSub>() || - curr->is<StructNew>(); + if (Properties::isSingleConstantExpression(curr) || curr->is<GlobalGet>() || + curr->is<RttCanon>() || curr->is<RttSub>() || curr->is<StructNew>() || + curr->is<ArrayNew>() || curr->is<I31New>()) { + for (auto* child : ChildIterator(curr)) { + if (!canInitializeGlobal(child)) { + return false; + } + } + return true; + } + return false; } } // namespace GlobalUtils diff --git a/src/ir/properties.h b/src/ir/properties.h index 8e5297092..d477cb11c 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -84,11 +84,12 @@ inline bool isNamedControlFlow(Expression* curr) { // A constant expression is something like a Const: it has a fixed value known // at compile time, and passes that propagate constants can try to propagate it. -// Constant expressions are also allowed in global initializers in wasm. +// Constant expressions are also allowed in global initializers in wasm. Also +// when two constant expressions compare equal at compile time, their values at +// runtime will be equal as well. // TODO: look into adding more things here like RttCanon. inline bool isSingleConstantExpression(const Expression* curr) { - return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>() || - (curr->is<I31New>() && curr->cast<I31New>()->value->is<Const>()); + return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>(); } inline bool isConstantExpression(const Expression* curr) { |