summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-11-15 11:21:44 -0800
committerGitHub <noreply@github.com>2022-11-15 11:21:44 -0800
commit0ffafa5d4f4bca8a6ab77e193caacc5292218a5d (patch)
treeb0ea0aa88f03e231ec746f2ad18f394106ac6c3e /src
parent59cbdd818dc3397a823a37e9821fd32f4522b2fc (diff)
downloadbinaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.tar.gz
binaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.tar.bz2
binaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.zip
GlobalStructInference: Handle the case of just 1 value (#5259)
#5253 handled the case of just one possible global. It is also possible we have multiple globals but just one value. This handles that case. (It slightly overlaps with other passes, but as this pass actually identifies the creations of the objects in globals, it has a guarantee of success that the others don't, and it is very easy to just do given all the work done to handle the case of 2 values). Also fix a minor bug in #5253 - we need to trap if the old reference were null. That is, we know the reference must point to the only object ever created of that type, but that is only if it is not null; if it's null we need to trap.
Diffstat (limited to 'src')
-rw-r--r--src/passes/GlobalStructInference.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp
index 39761c1d6..8bb4c0ba9 100644
--- a/src/passes/GlobalStructInference.cpp
+++ b/src/passes/GlobalStructInference.cpp
@@ -219,15 +219,16 @@ struct GlobalStructInference : public Pass {
}
auto& wasm = *getModule();
+ Builder builder(wasm);
if (globals.size() == 1) {
// Leave it to other passes to infer the constant value of the field,
// if there is one: just change the reference to the global, which
- // will unlock those other optimizations.
+ // will unlock those other optimizations. Note we must trap if the ref
+ // is null, so add RefAsNonNull here.
auto global = globals[0];
- Builder builder(wasm);
curr->ref = builder.makeSequence(
- builder.makeDrop(curr->ref),
+ builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)),
builder.makeGlobalGet(global, wasm.getGlobal(globals[0])->type));
return;
}
@@ -293,12 +294,14 @@ struct GlobalStructInference : public Pass {
}
// We have some globals (at least 2), and so must have at least one
- // value. And we have already exited if we have more than 2, so that
- // only leaves 1 and 2. We are looking for the case of 2 here, since
- // other passes (ConstantFieldPropagation) can handle 1.
- // TODO: We can perhaps do better than CFP, as we know the structs are
- // created in globals.
+ // value. And we have already exited if we have more than 2 values (see
+ // the early return above) so that only leaves 1 and 2.
if (values.size() == 1) {
+ // The case of 1 value is simple: trap if the ref is null, and
+ // otherwise return the value.
+ replaceCurrent(builder.makeSequence(
+ builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)),
+ builder.makeConstantExpression(values[0])));
return;
}
assert(values.size() == 2);
@@ -321,7 +324,6 @@ struct GlobalStructInference : public Pass {
//
// Note that we must trap on null, so add a ref.as_non_null here.
auto checkGlobal = globalsForValue[0][0];
- Builder builder(wasm);
replaceCurrent(builder.makeSelect(
builder.makeRefEq(builder.makeRefAs(RefAsNonNull, curr->ref),
builder.makeGlobalGet(