summaryrefslogtreecommitdiff
path: root/src/ir/localize.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/localize.h')
-rw-r--r--src/ir/localize.h42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/ir/localize.h b/src/ir/localize.h
index c8e85822a..44ec5af32 100644
--- a/src/ir/localize.h
+++ b/src/ir/localize.h
@@ -17,7 +17,8 @@
#ifndef wasm_ir_localizer_h
#define wasm_ir_localizer_h
-#include <wasm-builder.h>
+#include "ir/iteration.h"
+#include "wasm-builder.h"
namespace wasm {
@@ -26,7 +27,6 @@ namespace wasm {
//
// Note that if the local is reused, this assumes it is not modified in between
// the set and the get, which the caller must ensure.
-
struct Localizer {
Index index;
Expression* expr;
@@ -44,6 +44,44 @@ struct Localizer {
}
};
+// Replaces all children with gets of locals, if they have any effects. After
+// this, the original input has only local.gets as inputs, or other things that
+// have no interacting effects, and so those children can be reordered.
+// The sets of the locals are emitted on a |sets| property on the class. Those
+// must be emitted right before the input.
+// This stops at the first unreachable child, as there is no code executing
+// after that point anyhow.
+// TODO: use in more places
+struct ChildLocalizer {
+ std::vector<LocalSet*> sets;
+
+ ChildLocalizer(Expression* input,
+ Function* func,
+ Module* wasm,
+ const PassOptions& options) {
+ Builder builder(*wasm);
+ ChildIterator iterator(input);
+ auto& children = iterator.children;
+ // The children are in reverse order, so allocate the output first and
+ // apply items as we go.
+ auto num = children.size();
+ for (Index i = 0; i < num; i++) {
+ auto** childp = children[num - 1 - i];
+ auto* child = *childp;
+ if (child->type == Type::unreachable) {
+ break;
+ }
+ // If there are effects, use a local for this.
+ // TODO: Compare interactions between their side effects.
+ if (EffectAnalyzer(options, *wasm, child).hasAnything()) {
+ auto local = builder.addVar(func, child->type);
+ sets.push_back(builder.makeLocalSet(local, child));
+ *childp = builder.makeLocalGet(local, child->type);
+ }
+ }
+ }
+};
+
} // namespace wasm
#endif // wasm_ir_localizer_h