diff options
author | Alon Zakai <azakai@google.com> | 2021-11-12 08:52:11 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-12 08:52:11 -0800 |
commit | 272ffea1237f1ebb0455949a102a141d55542a47 (patch) | |
tree | e241dbb10dd8a103f43cf571e210c6e56e178e73 /src/ir/iteration.h | |
parent | 50e66800dc28d67ea1cc88172f459df1ca96507d (diff) | |
download | binaryen-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.h | 23 |
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> { |