summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-04-10 05:14:42 +0000
committerAndrew Trick <atrick@apple.com>2012-04-10 05:14:42 +0000
commit4442bfe55931923ae829c22e99de658b2b210436 (patch)
tree521882feee51439c1dffc4a333280dbb8fe73d8c /llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
parent4104ed9c76d0a275c62e2bafd1fda704b782bfaf (diff)
downloadbcm5719-llvm-4442bfe55931923ae829c22e99de658b2b210436.tar.gz
bcm5719-llvm-4442bfe55931923ae829c22e99de658b2b210436.zip
Fix 12513: Loop unrolling breaks with indirect branches.
Take this opportunity to generalize the indirectbr bailout logic for loop transformations. CFG transformations will never get indirectbr right, and there's no point trying. llvm-svn: 154386
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopUnswitch.cpp41
1 files changed, 12 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
index 1c93a703d6f..ee232687ffd 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -192,10 +192,6 @@ namespace {
loopPreheader = currentLoop->getLoopPreheader();
}
- /// HasIndirectBrsInPreds - Returns true if there are predecessors, that are
- /// terminated with indirect branch instruction.
- bool HasIndirectBrsInPreds(const SmallVectorImpl<BasicBlock *> &ExitBlocks);
-
/// Split all of the edges from inside the loop to their exit blocks.
/// Update the appropriate Phi nodes as we do so.
void SplitExitEdges(Loop *L, const SmallVector<BasicBlock *, 8> &ExitBlocks);
@@ -203,7 +199,7 @@ namespace {
bool UnswitchIfProfitable(Value *LoopCond, Constant *Val);
void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
BasicBlock *ExitBlock);
- bool UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L);
+ void UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L);
void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
Constant *Val, bool isEqual);
@@ -409,6 +405,14 @@ bool LoopUnswitch::processCurrentLoop() {
if (!loopPreheader)
return false;
+ // Loops with indirectbr cannot be cloned.
+ if (!currentLoop->isSafeToClone())
+ return false;
+
+ // Without dedicated exits, splitting the exit edge may fail.
+ if (!currentLoop->hasDedicatedExits())
+ return false;
+
LLVMContext &Context = loopHeader->getContext();
// Probably we reach the quota of branches for this loop. If so
@@ -638,7 +642,8 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) {
if (OptimizeForSize || F->hasFnAttr(Attribute::OptimizeForSize))
return false;
- return UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
+ UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
+ return true;
}
/// CloneLoop - Recursively clone the specified loop and all of its children,
@@ -733,24 +738,6 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond,
++NumTrivial;
}
-/// HasIndirectBrsInPreds - Returns true if there are predecessors, that are
-/// terminated with indirect branch instruction.
-bool LoopUnswitch::HasIndirectBrsInPreds(
- const SmallVectorImpl<BasicBlock *> &ExitBlocks){
-
- for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
- const BasicBlock *ExitBlock = ExitBlocks[i];
- for (const_pred_iterator p = pred_begin(ExitBlock), e = pred_end(ExitBlock);
- p != e; ++p) {
- // Cannot split an edge from an IndirectBrInst
- if (isa<IndirectBrInst>((*p)->getTerminator()))
- return true;
-
- }
- }
- return false;
-}
-
/// SplitExitEdges - Split all of the edges from inside the loop to their exit
/// blocks. Update the appropriate Phi nodes as we do so.
void LoopUnswitch::SplitExitEdges(Loop *L,
@@ -776,7 +763,7 @@ void LoopUnswitch::SplitExitEdges(Loop *L,
/// UnswitchNontrivialCondition - We determined that the loop is profitable
/// to unswitch when LIC equal Val. Split it into loop versions and test the
/// condition outside of either loop. Return the loops created as Out1/Out2.
-bool LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
+void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
Loop *L) {
Function *F = loopHeader->getParent();
DEBUG(dbgs() << "loop-unswitch: Unswitching loop %"
@@ -800,8 +787,6 @@ bool LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
- if (HasIndirectBrsInPreds(ExitBlocks))
- return false;
// Split all of the edges from inside the loop to their exit blocks. Update
// the appropriate Phi nodes as we do so.
@@ -916,8 +901,6 @@ bool LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop &&
LICHandle && !isa<Constant>(LICHandle))
RewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val, true);
-
- return true;
}
/// RemoveFromWorklist - Remove all instances of I from the worklist vector
OpenPOWER on IntegriCloud