summaryrefslogtreecommitdiff
path: root/src/ir/possible-constant.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/possible-constant.h')
-rw-r--r--src/ir/possible-constant.h38
1 files changed, 35 insertions, 3 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); }