diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/possible-constant.h | 38 | ||||
-rw-r--r-- | src/passes/ConstantFieldPropagation.cpp | 26 | ||||
-rw-r--r-- | src/passes/param-utils.cpp | 18 |
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); } |