summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/GVN.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-08-24 15:06:28 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-08-24 15:06:28 +0000
commitdd62d6b6c843baf8c8c9b6d353df383694505002 (patch)
treee64cfc7c2345e244f7563d5e69555e35208ab978 /llvm/lib/Transforms/Scalar/GVN.cpp
parent3ac45d9a1fbbf58adfaf7fd5eecbb4f26997c323 (diff)
downloadbcm5719-llvm-dd62d6b6c843baf8c8c9b6d353df383694505002.tar.gz
bcm5719-llvm-dd62d6b6c843baf8c8c9b6d353df383694505002.zip
GVN: Fix quadratic runtime on the number of switch cases.
No intended behavior change. This was introduced in r162023. With the fixed algorithm a Release build of ARMInstPrinter.cpp goes from 16s to 10s on a 2011 MBP. llvm-svn: 162559
Diffstat (limited to 'llvm/lib/Transforms/Scalar/GVN.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 4822fd09448..3a896232190 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2231,12 +2231,20 @@ bool GVN::processInstruction(Instruction *I) {
Value *SwitchCond = SI->getCondition();
BasicBlock *Parent = SI->getParent();
bool Changed = false;
+
+ // Remember how many outgoing edges there are to every successor.
+ SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
+ for (unsigned i = 0, n = SI->getNumSuccessors(); i != n; ++i)
+ ++SwitchEdges[SI->getSuccessor(i)];
+
for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
i != e; ++i) {
BasicBlock *Dst = i.getCaseSuccessor();
- BasicBlockEdge E(Parent, Dst);
- if (E.isSingleEdge())
+ // If there is only a single edge, propagate the case value into it.
+ if (SwitchEdges.lookup(Dst) == 1) {
+ BasicBlockEdge E(Parent, Dst);
Changed |= propagateEquality(SwitchCond, i.getCaseValue(), E);
+ }
}
return Changed;
}
OpenPOWER on IntegriCloud