summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-04-07 19:53:15 -0700
committerGitHub <noreply@github.com>2020-04-07 19:53:15 -0700
commitc8a1489f2720ccde4aa79f68f4bb75cc1b20d579 (patch)
tree4d9ac99372c4a04f1b763c99d972da16b510f57f
parente77d85fecd2bfe707f3e9b7ab84cfd6744bdc7b7 (diff)
downloadbinaryen-c8a1489f2720ccde4aa79f68f4bb75cc1b20d579.tar.gz
binaryen-c8a1489f2720ccde4aa79f68f4bb75cc1b20d579.tar.bz2
binaryen-c8a1489f2720ccde4aa79f68f4bb75cc1b20d579.zip
Optimize ReorderLocals maps to vectors (#2727)
The original code here is quite old and I guess we assumed that it was ok to use maps for this, but on really huge amounts of locals it ends up mattering a lot. This makes the pass 3x faster on poppler after --flatten --flatten (double flatten creates lots of new locals, and is generally similar to what wasm2js does).
-rw-r--r--src/passes/ReorderLocals.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/passes/ReorderLocals.cpp b/src/passes/ReorderLocals.cpp
index f5736930a..04e9c274b 100644
--- a/src/passes/ReorderLocals.cpp
+++ b/src/passes/ReorderLocals.cpp
@@ -34,12 +34,25 @@ struct ReorderLocals : public WalkerPass<PostWalker<ReorderLocals>> {
Pass* create() override { return new ReorderLocals; }
- std::map<Index, Index> counts; // local => times it is used
- // local => index in the list of which local is first seen
- std::map<Index, Index> firstUses;
+ // local index => times it is used
+ std::vector<Index> counts;
+ // local index => how many locals we saw before this one, before a use of
+ // this one appeared. that is, one local has 0, another has 1, and so forth,
+ // in the order in which we saw the first uses of them.
+ std::vector<Index> firstUses;
+ Index firstUseIndex = 0;
- void visitFunction(Function* curr) {
+ static const Index UNSEEN = -1;
+
+ void doWalkFunction(Function* curr) {
Index num = curr->getNumLocals();
+ counts.resize(num);
+ std::fill(counts.begin(), counts.end(), 0);
+ firstUses.resize(num);
+ std::fill(firstUses.begin(), firstUses.end(), UNSEEN);
+ // Gather information about local usages.
+ walk(curr->body);
+ // Use the information about local usages.
std::vector<Index> newToOld;
for (size_t i = 0; i < num; i++) {
newToOld.push_back(i);
@@ -128,15 +141,15 @@ struct ReorderLocals : public WalkerPass<PostWalker<ReorderLocals>> {
void visitLocalGet(LocalGet* curr) {
counts[curr->index]++;
- if (firstUses.count(curr->index) == 0) {
- firstUses[curr->index] = firstUses.size();
+ if (firstUses[curr->index] == UNSEEN) {
+ firstUses[curr->index] = firstUseIndex++;
}
}
void visitLocalSet(LocalSet* curr) {
counts[curr->index]++;
- if (firstUses.count(curr->index) == 0) {
- firstUses[curr->index] = firstUses.size();
+ if (firstUses[curr->index] == UNSEEN) {
+ firstUses[curr->index] = firstUseIndex++;
}
}
};