summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-03-28 09:44:00 -0700
committerGitHub <noreply@github.com>2022-03-28 16:44:00 +0000
commit4643f26e113476ebb273ee4f69e89c61801c7c2f (patch)
tree5de7dc236aa367d11b88f1c639aba44c7efb9b2d /src
parent11932cc31e88d3d368714fcca43df979f7694bd1 (diff)
downloadbinaryen-4643f26e113476ebb273ee4f69e89c61801c7c2f.tar.gz
binaryen-4643f26e113476ebb273ee4f69e89c61801c7c2f.tar.bz2
binaryen-4643f26e113476ebb273ee4f69e89c61801c7c2f.zip
Generalize PossibleConstantValues for immutable globals (#4549)
This moves more logic from ConstantFieldPropagation into PossibleConstantValues, that is, instead of handling the two cases of a Literal or a Name before calling PossibleConstantValues, move that code into the helper class. That way all users of PossibleConstantValues can benefit from it. In particular, this makes DeadArgumentElimination now support optimizing immutable globals, as well as ref.func and ref.null. (Changes to test/lit/passes/dae-gc-refine-params.wast are to avoid the new optimizations from kicking in, so that it still tests what it tested before.)
Diffstat (limited to 'src')
-rw-r--r--src/ir/possible-constant.h38
-rw-r--r--src/passes/ConstantFieldPropagation.cpp26
-rw-r--r--src/passes/param-utils.cpp18
3 files changed, 40 insertions, 42 deletions
diff --git a/src/ir/possible-constant.h b/src/ir/possible-constant.h
index 24f236a3c..c75669dab 100644
--- a/src/ir/possible-constant.h
+++ b/src/ir/possible-constant.h
@@ -19,6 +19,7 @@
#include <variant>
+#include "ir/properties.h"
#include "wasm-builder.h"
#include "wasm.h"
@@ -47,9 +48,29 @@ private:
public:
PossibleConstantValues() : value(None()) {}
- // Note a written value as we see it, and update our internal knowledge based
- // on it and all previous values noted. This can be called using either a
- // Literal or a Name, so it uses a template.
+ // Notes the contents of an expression and update our internal knowledge based
+ // on it and all previous values noted.
+ void note(Expression* expr, Module& wasm) {
+ // If this is a constant literal value, note that.
+ if (Properties::isConstantExpression(expr)) {
+ note(Properties::getLiteral(expr));
+ return;
+ }
+
+ // If this is an immutable global that we get, note that.
+ if (auto* get = expr->dynCast<GlobalGet>()) {
+ auto* global = wasm.getGlobal(get->name);
+ if (global->mutable_ == Immutable) {
+ note(get->name);
+ return;
+ }
+ }
+
+ // Otherwise, this is not something we can reason about.
+ noteUnknown();
+ }
+
+ // Note either a Literal or a Name.
template<typename T> void note(T curr) {
if (std::get_if<None>(&value)) {
// This is the first value.
@@ -120,6 +141,17 @@ public:
return std::get<Name>(value);
}
+ // Assuming we have a single value, make an expression containing that value.
+ Expression* makeExpression(Module& wasm) {
+ Builder builder(wasm);
+ if (isConstantLiteral()) {
+ return builder.makeConstantExpression(getConstantLiteral());
+ } else {
+ auto name = getConstantGlobal();
+ return builder.makeGlobalGet(name, wasm.getGlobal(name)->type);
+ }
+ }
+
// Returns whether we have ever noted a value.
bool hasNoted() const { return !std::get_if<None>(&value); }
diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp
index 44e74f2d4..1755c97f3 100644
--- a/src/passes/ConstantFieldPropagation.cpp
+++ b/src/passes/ConstantFieldPropagation.cpp
@@ -29,7 +29,6 @@
#include "ir/module-utils.h"
#include "ir/possible-constant.h"
-#include "ir/properties.h"
#include "ir/struct-utils.h"
#include "ir/utils.h"
#include "pass.h"
@@ -101,12 +100,7 @@ struct FunctionOptimizer : public WalkerPass<PostWalker<FunctionOptimizer>> {
// ref.as_non_null (we need to trap as the get would have done so), plus the
// constant value. (Leave it to further optimizations to get rid of the
// ref.)
- Expression* value;
- if (info.isConstantLiteral()) {
- value = builder.makeConstantExpression(info.getConstantLiteral());
- } else {
- value = builder.makeGlobalGet(info.getConstantGlobal(), curr->type);
- }
+ Expression* value = info.makeExpression(*getModule());
replaceCurrent(builder.makeSequence(
builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)), value));
changed = true;
@@ -145,23 +139,7 @@ struct PCVScanner
HeapType type,
Index index,
PossibleConstantValues& info) {
- // If this is a constant literal value, note that.
- if (Properties::isConstantExpression(expr)) {
- info.note(Properties::getLiteral(expr));
- return;
- }
-
- // If this is an immutable global that we get, note that.
- if (auto* get = expr->dynCast<GlobalGet>()) {
- auto* global = getModule()->getGlobal(get->name);
- if (global->mutable_ == Immutable) {
- info.note(get->name);
- return;
- }
- }
-
- // Otherwise, this is not something we can reason about.
- info.noteUnknown();
+ info.note(expr, *getModule());
}
void noteDefault(Type fieldType,
diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp
index ae641fd26..cf7873dc0 100644
--- a/src/passes/param-utils.cpp
+++ b/src/passes/param-utils.cpp
@@ -200,25 +200,14 @@ SortedVector applyConstantValues(const std::vector<Function*>& funcs,
auto numParams = first->getNumParams();
for (Index i = 0; i < numParams; i++) {
PossibleConstantValues value;
-
- // Processes one operand.
- auto processOperand = [&](Expression* operand) {
- if (auto* c = operand->dynCast<Const>()) {
- value.note(c->value);
- return;
- }
- // TODO: refnull, immutable globals, etc.
- // Not a constant, give up
- value.noteUnknown();
- };
for (auto* call : calls) {
- processOperand(call->operands[i]);
+ value.note(call->operands[i], *module);
if (!value.isConstant()) {
break;
}
}
for (auto* call : callRefs) {
- processOperand(call->operands[i]);
+ value.note(call->operands[i], *module);
if (!value.isConstant()) {
break;
}
@@ -232,8 +221,7 @@ SortedVector applyConstantValues(const std::vector<Function*>& funcs,
Builder builder(*module);
for (auto* func : funcs) {
func->body = builder.makeSequence(
- builder.makeLocalSet(i, builder.makeConst(value.getConstantLiteral())),
- func->body);
+ builder.makeLocalSet(i, value.makeExpression(*module)), func->body);
}
optimized.insert(i);
}