diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Analysis/LoopInfo.cpp | 11 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 41 | ||||
| -rw-r--r-- | lib/Transforms/Utils/LoopUnroll.cpp | 6 |
3 files changed, 29 insertions, 29 deletions
diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 858cc64..f7a60a1 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -205,6 +205,17 @@ bool Loop::isLoopSimplifyForm() const { return getLoopPreheader() && getLoopLatch() && hasDedicatedExits(); } +/// isSafeToClone - Return true if the loop body is safe to clone in practice. +/// Routines that reform the loop CFG and split edges often fail on indirectbr. +bool Loop::isSafeToClone() const { + // Return false if any loop blocks contain indirectbrs. + for (Loop::block_iterator I = block_begin(), E = block_end(); I != E; ++I) { + if (isa<IndirectBrInst>((*I)->getTerminator())) + return false; + } + return true; +} + /// hasDedicatedExits - Return true if no exit block for the loop /// has a predecessor that is outside the loop. bool Loop::hasDedicatedExits() const { diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 1c93a70..ee23268 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 diff --git a/lib/Transforms/Utils/LoopUnroll.cpp b/lib/Transforms/Utils/LoopUnroll.cpp index 512b689..e15497a 100644 --- a/lib/Transforms/Utils/LoopUnroll.cpp +++ b/lib/Transforms/Utils/LoopUnroll.cpp @@ -149,6 +149,12 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, return false; } + // Loops with indirectbr cannot be cloned. + if (!L->isSafeToClone()) { + DEBUG(dbgs() << " Can't unroll; Loop body cannot be cloned.\n"); + return false; + } + BasicBlock *Header = L->getHeader(); BranchInst *BI = dyn_cast<BranchInst>(LatchBlock->getTerminator()); |
