aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/LoopUnswitch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp41
1 files changed, 12 insertions, 29 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 1c93a703d6..ee232687ff 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/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