summaryrefslogtreecommitdiff
path: root/src/passes/RelooperJumpThreading.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-11-07 10:20:42 -0800
committerGitHub <noreply@github.com>2016-11-07 10:20:42 -0800
commit89d393ed02f6b15a3a8dc60b489f969184070625 (patch)
tree01b3e429c5afb8794c972c27276385345f53e8b8 /src/passes/RelooperJumpThreading.cpp
parent033b5e161e677173bda01aad9e6850545b93c97e (diff)
parent4a3892d31288bded757e3805cb53d4e20ccc6be0 (diff)
downloadbinaryen-89d393ed02f6b15a3a8dc60b489f969184070625.tar.gz
binaryen-89d393ed02f6b15a3a8dc60b489f969184070625.tar.bz2
binaryen-89d393ed02f6b15a3a8dc60b489f969184070625.zip
Merge pull request #827 from WebAssembly/relooper
Reloop if-loops with label targets
Diffstat (limited to 'src/passes/RelooperJumpThreading.cpp')
-rw-r--r--src/passes/RelooperJumpThreading.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/passes/RelooperJumpThreading.cpp b/src/passes/RelooperJumpThreading.cpp
index 7f74220d5..bd257c568 100644
--- a/src/passes/RelooperJumpThreading.cpp
+++ b/src/passes/RelooperJumpThreading.cpp
@@ -182,7 +182,21 @@ private:
assert(labelChecksInOrigin[num] == 0);
if (labelSetsInOrigin[num] != labelSets[num]) {
assert(labelSetsInOrigin[num] < labelSets[num]);
- return true; // label set somewhere outside of origin TODO: if set in the if body here, it might be safe in some cases
+ // the label is set outside of the origin
+ // if the only other location is inside the if body, then it is ok - it must be in a loop
+ // and returning to the top of the loop body, so we don't need to do anything for that
+ // label setting anyhow
+ std::map<Index, Index> labelChecksInIfTrue;
+ std::map<Index, Index> labelSetsInIfTrue;
+ LabelUseFinder finder(labelIndex, labelChecksInIfTrue, labelSetsInIfTrue);
+ finder.walk(iff->ifTrue);
+ if (labelSetsInOrigin[num] + labelSetsInIfTrue[num] < labelSets[num]) {
+ // label set somewhere we can't see now, could be irreducible control flow
+ // TODO: one case where this happens is instead of an if-chain, we have
+ // ifs and a switch on label|0, in separate elements. perhaps not
+ // emitting switches on label|0 in the relooper would avoid that.
+ return true;
+ }
}
iff = isLabelCheckingIf(iff->ifFalse, labelIndex);
}