initial trivial support for folding branches that have now-constant destinations.

llvm-svn: 26279
This commit is contained in:
Chris Lattner 2006-02-18 01:27:45 +00:00
parent 5caed8a231
commit 29f771ba21
1 changed files with 33 additions and 2 deletions

View File

@ -76,12 +76,14 @@ namespace {
unsigned getLoopUnswitchCost(Loop *L, Value *LIC); unsigned getLoopUnswitchCost(Loop *L, Value *LIC);
void VersionLoop(Value *LIC, Constant *OnVal, void VersionLoop(Value *LIC, Constant *OnVal,
Loop *L, Loop *&Out1, Loop *&Out2); 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 *SplitEdge(BasicBlock *From, BasicBlock *To);
BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt); BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt);
void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,Constant *Val, void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,Constant *Val,
bool isEqual); bool isEqual);
void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, bool TryToRemoveEdge(TerminatorInst *TI, unsigned SuccNo,
bool EntersWhenTrue, BasicBlock *ExitBlock); std::vector<Instruction*> &Worklist);
}; };
RegisterOpt<LoopUnswitch> X("loop-unswitch", "Unswitch loops"); RegisterOpt<LoopUnswitch> X("loop-unswitch", "Unswitch loops");
} }
@ -717,7 +719,25 @@ static void ReplaceUsesOfWith(Instruction *I, Value *V,
++NumSimplify; ++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 // 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 // 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. // Remove Succ from the loop tree.
LI->removeBlock(Succ); LI->removeBlock(Succ);
Succ->eraseFromParent(); Succ->eraseFromParent();
++NumSimplify;
break; 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; break;
} }