diff options
author | Alon Zakai <azakai@google.com> | 2021-09-09 16:43:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-09 23:43:49 +0000 |
commit | 7ecc77a11a7844e4b8142fad0a718d4f8f4d193b (patch) | |
tree | 23876c2e4a247b97ae2496afc26c3fc0fe2f9356 | |
parent | 0bc719505457acc1a92894b3995ce233fb0cdb20 (diff) | |
download | binaryen-7ecc77a11a7844e4b8142fad0a718d4f8f4d193b.tar.gz binaryen-7ecc77a11a7844e4b8142fad0a718d4f8f4d193b.tar.bz2 binaryen-7ecc77a11a7844e4b8142fad0a718d4f8f4d193b.zip |
Rename isIntrinsicallyNondeterministic() to isGenerative() (#4092)
-rw-r--r-- | src/ir/properties.cpp | 14 | ||||
-rw-r--r-- | src/ir/properties.h | 41 | ||||
-rw-r--r-- | src/passes/LocalCSE.cpp | 3 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 3 | ||||
-rw-r--r-- | src/passes/Precompute.cpp | 4 |
5 files changed, 31 insertions, 34 deletions
diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp index 889ece57b..fa4f299b3 100644 --- a/src/ir/properties.cpp +++ b/src/ir/properties.cpp @@ -21,20 +21,20 @@ namespace wasm { namespace Properties { -bool isIntrinsicallyNondeterministic(Expression* curr, FeatureSet features) { - // Practically no wasm instructions are intrinsically nondeterministic. - // Exceptions occur only in GC atm. +bool isGenerative(Expression* curr, FeatureSet features) { + // Practically no wasm instructions are generative. Exceptions occur only in + // GC atm. if (!features.hasGC()) { return false; } struct Scanner : public PostWalker<Scanner> { - bool deterministic = true; - void visitStructNew(StructNew* curr) { deterministic = false; } - void visitArrayNew(ArrayNew* curr) { deterministic = false; } + bool generative = false; + void visitStructNew(StructNew* curr) { generative = true; } + void visitArrayNew(ArrayNew* curr) { generative = true; } } scanner; scanner.walk(curr); - return !scanner.deterministic; + return scanner.generative; } } // namespace Properties diff --git a/src/ir/properties.h b/src/ir/properties.h index 1640ca814..f3cab1fdc 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -372,11 +372,10 @@ inline bool canEmitSelectWithArms(Expression* ifTrue, Expression* ifFalse) { return ifTrue->type.isSingle() && ifFalse->type.isSingle(); } -// An intrinsically-nondeterministic expression is one that can return different -// results for the same inputs, and that difference is *not* explained by -// other expressions that interact with this one. Hence the cause of -// nondeterminism can be said to be "intrinsic" - it is internal and inherent in -// the expression. +// A "generative" expression is one that can generate different results for the +// same inputs, and that difference is *not* explained by other expressions that +// interact with this one. This is an intrinsic/internal property of the +// expression. // // To see the issue more concretely, consider these: // @@ -396,26 +395,26 @@ inline bool canEmitSelectWithArms(Expression* ifTrue, Expression* ifFalse) { // allocations, though, it doesn't matter what is in "..": there is nothing // in the wasm that we can check to find out if the results are the same or // not. (In fact, in this case they are always not the same.) So the -// nondeterminism is "intrinsic." +// generativity is "intrinsic" to the expression and it is because each call to +// struct.new generates a new value. // -// Thus, loads are nondeterministic but not intrinsically so, while GC -// allocations are actual examples of intrinsically nondeterministic -// instructions. If wasm were to add "get current time" or "get a random number" -// instructions then those would also be intrinsically nondeterministic. +// Thus, loads are nondeterministic but not generative, while GC allocations +// are in fact generative. Note that "generative" need not mean "allocation" as +// if wasm were to add "get current time" or "get a random number" instructions +// then those would also be generative - generating a new current time value or +// a new random number on each execution, respectively. // -// * Note that NaN nondeterminism is ignored here. Technically that allows e.g. -// an f32.add to be nondeterministic, but it is a valid wasm implementation -// to have deterministic NaN behavior, and we optimize under that assumption. -// So NaN nondeterminism does not cause anything to be intrinsically -// nondeterministic. +// * Note that NaN nondeterminism is ignored here. It is a valid wasm +// implementation to have deterministic NaN behavior, and we optimize under +// that simplifying assumption. // * Note that calls are ignored here. In theory this concept could be defined -// either way for them (that is, we could potentially define them as either -// intrinsically nondeterministic, or not, and each could make sense in its -// own way). It is simpler to ignore them here, which means we only consider -// the behavior of the expression provided here (including its chldren), and -// not external code. +// either way for them - that is, we could potentially define them as +// generative, as they might contain such an instruction, or we could define +// this property as only looking at code in the current function. We choose +// the latter because calls are already handled best in other manners (using +// EffectAnalyzer). // -bool isIntrinsicallyNondeterministic(Expression* curr, FeatureSet features); +bool isGenerative(Expression* curr, FeatureSet features); } // namespace Properties diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 863179e49..d63c217de 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -436,8 +436,7 @@ struct Checker // nondeterministic: even if it has no side effects, if it may return a // different result each time, then we cannot optimize away repeats. if (effects.hasSideEffects() || - Properties::isIntrinsicallyNondeterministic(curr, - getModule()->features)) { + Properties::isGenerative(curr, getModule()->features)) { requestInfos.erase(curr); } else { activeOriginals.emplace( diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index cbf5d74d4..357f172d9 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1583,8 +1583,7 @@ private: } // To be equal, they must also be known to return the same result // deterministically. - if (Properties::isIntrinsicallyNondeterministic(left, - getModule()->features)) { + if (Properties::isGenerative(left, getModule()->features)) { return false; } return true; diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 89941a1ae..1ba298605 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -308,8 +308,8 @@ private: // creates a new, unique struct, even if the data is equal), and so // PrecomputingExpressionRunner will return a nonconstant flow for all // GC heap operations. (We could also have used - // Properties::isIntrinsicallyNondeterministic here, but that would be - // less efficient to re-scan the entire expression.) + // Properties::isGenerative here, but that would be less efficient to + // re-scan the entire expression.) // // (Other side effects are fine; if an expression does a call and we // somehow know the entire expression precomputes to a 42, then we can |