summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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);
}