summaryrefslogtreecommitdiff
path: root/src/ir/iteration.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-11-12 08:52:11 -0800
committerGitHub <noreply@github.com>2021-11-12 08:52:11 -0800
commit272ffea1237f1ebb0455949a102a141d55542a47 (patch)
treee241dbb10dd8a103f43cf571e210c6e56e178e73 /src/ir/iteration.h
parent50e66800dc28d67ea1cc88172f459df1ca96507d (diff)
downloadbinaryen-272ffea1237f1ebb0455949a102a141d55542a47.tar.gz
binaryen-272ffea1237f1ebb0455949a102a141d55542a47.tar.bz2
binaryen-272ffea1237f1ebb0455949a102a141d55542a47.zip
MergeBlocks: Rewrite to use a generic algorithm (#4323)
Before this we had special logic for various call types. This replaces all that with a single general code path, which unifies everything except for control flow constructs (which remain as before, handled in a special way for each of them). The algorithm is simple and direct, basically it goes through the children and when it finds a block, it sees if it can move the block's contents outside of the parent. While doing so it takes into account effects and so forth. To make this easy, a random-access API is added to ChildIterator. Diff without whitespace makes the existing test updates a lot simpler. Note that this is not NFC as the old algorithm had some quirks like not taking into account effects when there were more than 2 children; the new code is uniform in how it handles things. This ends up removing 19% of all blocks in j2wasm, which reduces 1% of total code size.
Diffstat (limited to 'src/ir/iteration.h')
-rw-r--r--src/ir/iteration.h23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/ir/iteration.h b/src/ir/iteration.h
index 29d183678..6574e5dff 100644
--- a/src/ir/iteration.h
+++ b/src/ir/iteration.h
@@ -58,15 +58,21 @@ template<class Specific> class AbstractChildIterator {
void operator++() { index++; }
Expression*& operator*() {
- assert(index < parent.children.size());
-
- // The vector of children is in reverse order, as that is how
- // wasm-delegations-fields works. To get the order of execution, reverse
- // things.
- return *parent.children[parent.children.size() - 1 - index];
+ return *parent.children[parent.mapIndex(index)];
}
};
+ friend struct Iterator;
+
+ Index mapIndex(Index index) const {
+ assert(index < children.size());
+
+ // The vector of children is in reverse order, as that is how
+ // wasm-delegations-fields works. To get the order of execution, reverse
+ // things.
+ return children.size() - 1 - index;
+ }
+
public:
// The vector of children in the order emitted by wasm-delegations-fields
// (which is in reverse execution order).
@@ -112,6 +118,11 @@ public:
void addChild(Expression* parent, Expression** child) {
children.push_back(child);
}
+
+ // API for accessing children in random order.
+ Expression*& getChild(Index index) { return *children[mapIndex(index)]; }
+
+ Index getNumChildren() { return children.size(); }
};
class ChildIterator : public AbstractChildIterator<ChildIterator> {