diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-18 01:27:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-18 01:27:45 +0000 |
commit | f4412d890dd20af78120a793c973f319e4b506ea (patch) | |
tree | 822318a1825a7e830d36d13eb257096f37d6bb6c /lib/Transforms/Scalar/LoopUnswitch.cpp | |
parent | 5e8b5558f7939cde1f6de2e18d7616903e86e7eb (diff) |
initial trivial support for folding branches that have now-constant destinations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26279 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 6add98d1ce..25c16199b5 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -76,12 +76,14 @@ namespace { unsigned getLoopUnswitchCost(Loop *L, Value *LIC); void VersionLoop(Value *LIC, Constant *OnVal, Loop *L, Loop *&Out1, Loop *&Out2); + void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, + bool EntersWhenTrue, BasicBlock *ExitBlock); BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To); BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt); void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,Constant *Val, bool isEqual); - void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, - bool EntersWhenTrue, BasicBlock *ExitBlock); + bool TryToRemoveEdge(TerminatorInst *TI, unsigned SuccNo, + std::vector<Instruction*> &Worklist); }; RegisterOpt<LoopUnswitch> X("loop-unswitch", "Unswitch loops"); } @@ -717,7 +719,25 @@ static void ReplaceUsesOfWith(Instruction *I, Value *V, ++NumSimplify; } - +/// TryToRemoveEdge - Determine whether this is a case where we're smart enough +/// to remove the specified edge from the CFG and know how to update loop +/// information. If it is, update SSA and the loop information for the future +/// change, then return true. If not, return false. +bool LoopUnswitch::TryToRemoveEdge(TerminatorInst *TI, unsigned DeadSuccNo, + std::vector<Instruction*> &Worklist) { + BasicBlock *BB = TI->getParent(), *Succ = TI->getSuccessor(DeadSuccNo); + Loop *BBLoop = LI->getLoopFor(BB); + Loop *SuccLoop = LI->getLoopFor(Succ); + + // If this edge is not in a loop, or if this edge is leaving a loop to a + // non-loop area, this is trivial. + if (SuccLoop == 0) { + Succ->removePredecessor(BB, true); + return true; + } + + return false; +} // RewriteLoopBodyWithConditionConstant - We know either that the value LIC has // the value specified by Val in the specified loop, or we know it does NOT have @@ -875,7 +895,18 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, // Remove Succ from the loop tree. LI->removeBlock(Succ); Succ->eraseFromParent(); + ++NumSimplify; break; + } else if (ConstantBool *CB = dyn_cast<ConstantBool>(BI->getCondition())){ + // Conditional branch. + if (TryToRemoveEdge(BI, CB->getValue(), Worklist)) { + DEBUG(std::cerr << "Folded branch: " << *BI); + new BranchInst(BI->getSuccessor(!CB->getValue()), BI); + BI->eraseFromParent(); + RemoveFromWorklist(BI, Worklist); + ++NumSimplify; + break; + } } break; } |