GVN: Fix quadratic runtime on the number of switch cases.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 24 Aug 2012 15:06:28 +0000 (15:06 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 24 Aug 2012 15:06:28 +0000 (15:06 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162559 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/GVN.cpp

index 4822fd09448c10be4c87b2fe8126c6bf22ace7e3..3a89623219022d8861aa2d4e130f716a27a6676a 100644 (file)
@@ -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;
   }