1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 12:02:58 +02:00

Use IRBuilder while simplifying switch instruction.

llvm-svn: 131566
This commit is contained in:
Devang Patel 2011-05-18 20:35:38 +00:00
parent 3d6c5f4876
commit fd9b1daf82

View File

@ -57,16 +57,17 @@ class SimplifyCFGOpt {
BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI, BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
std::vector<std::pair<ConstantInt*, BasicBlock*> > &Cases); std::vector<std::pair<ConstantInt*, BasicBlock*> > &Cases);
bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI, bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
BasicBlock *Pred); BasicBlock *Pred,
IRBuilder<> &Builder);
bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI); bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI);
bool SimplifyReturn(ReturnInst *RI); bool SimplifyReturn(ReturnInst *RI);
bool SimplifyUnwind(UnwindInst *UI, IRBuilder<> &Builder); bool SimplifyUnwind(UnwindInst *UI, IRBuilder<> &Builder);
bool SimplifyUnreachable(UnreachableInst *UI); bool SimplifyUnreachable(UnreachableInst *UI);
bool SimplifySwitch(SwitchInst *SI); bool SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder);
bool SimplifyIndirectBr(IndirectBrInst *IBI); bool SimplifyIndirectBr(IndirectBrInst *IBI);
bool SimplifyUncondBranch(BranchInst *BI, IRBuilder <> &Builder); bool SimplifyUncondBranch(BranchInst *BI, IRBuilder <> &Builder);
bool SimplifyCondBranch(BranchInst *BI); bool SimplifyCondBranch(BranchInst *BI, IRBuilder <>&Builder);
public: public:
explicit SimplifyCFGOpt(const TargetData *td) : TD(td) {} explicit SimplifyCFGOpt(const TargetData *td) : TD(td) {}
@ -543,7 +544,8 @@ ValuesOverlap(std::vector<std::pair<ConstantInt*, BasicBlock*> > &C1,
/// form of jump threading. /// form of jump threading.
bool SimplifyCFGOpt:: bool SimplifyCFGOpt::
SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI, SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
BasicBlock *Pred) { BasicBlock *Pred,
IRBuilder<> &Builder) {
Value *PredVal = isValueEqualityComparison(Pred->getTerminator()); Value *PredVal = isValueEqualityComparison(Pred->getTerminator());
if (!PredVal) return false; // Not a value comparison in predecessor. if (!PredVal) return false; // Not a value comparison in predecessor.
@ -576,7 +578,7 @@ SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
// uncond br. // uncond br.
assert(ThisCases.size() == 1 && "Branch can only have one case!"); assert(ThisCases.size() == 1 && "Branch can only have one case!");
// Insert the new branch. // Insert the new branch.
Instruction *NI = BranchInst::Create(ThisDef, TI); Instruction *NI = Builder.CreateBr(ThisDef);
(void) NI; (void) NI;
// Remove PHI node entries for the dead edge. // Remove PHI node entries for the dead edge.
@ -641,7 +643,7 @@ SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
CheckEdge = 0; CheckEdge = 0;
// Insert the new branch. // Insert the new branch.
Instruction *NI = BranchInst::Create(TheRealDest, TI); Instruction *NI = Builder.CreateBr(TheRealDest);
(void) NI; (void) NI;
DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator() DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
@ -2366,7 +2368,7 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
/// TurnSwitchRangeIntoICmp - Turns a switch with that contains only a /// TurnSwitchRangeIntoICmp - Turns a switch with that contains only a
/// integer range comparison into a sub, an icmp and a branch. /// integer range comparison into a sub, an icmp and a branch.
static bool TurnSwitchRangeIntoICmp(SwitchInst *SI) { static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
assert(SI->getNumCases() > 2 && "Degenerate switch?"); assert(SI->getNumCases() > 2 && "Degenerate switch?");
// Make sure all cases point to the same destination and gather the values. // Make sure all cases point to the same destination and gather the values.
@ -2393,7 +2395,7 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI) {
if (!Offset->isNullValue()) if (!Offset->isNullValue())
Sub = BinaryOperator::CreateAdd(Sub, Offset, Sub->getName()+".off", SI); Sub = BinaryOperator::CreateAdd(Sub, Offset, Sub->getName()+".off", SI);
Value *Cmp = new ICmpInst(SI, ICmpInst::ICMP_ULT, Sub, NumCases, "switch"); Value *Cmp = new ICmpInst(SI, ICmpInst::ICMP_ULT, Sub, NumCases, "switch");
BranchInst::Create(SI->getSuccessor(1), SI->getDefaultDest(), Cmp, SI); Builder.CreateCondBr(Cmp, SI->getSuccessor(1), SI->getDefaultDest());
// Prune obsolete incoming values off the successor's PHI nodes. // Prune obsolete incoming values off the successor's PHI nodes.
for (BasicBlock::iterator BBI = SI->getSuccessor(1)->begin(); for (BasicBlock::iterator BBI = SI->getSuccessor(1)->begin();
@ -2436,7 +2438,7 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI) {
return !DeadCases.empty(); return !DeadCases.empty();
} }
bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI) { bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
// If this switch is too complex to want to look at, ignore it. // If this switch is too complex to want to look at, ignore it.
if (!isValueEqualityComparison(SI)) if (!isValueEqualityComparison(SI))
return false; return false;
@ -2446,7 +2448,7 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI) {
// If we only have one predecessor, and if it is a branch on this value, // If we only have one predecessor, and if it is a branch on this value,
// see if that predecessor totally determines the outcome of this switch. // see if that predecessor totally determines the outcome of this switch.
if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred)) if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred, Builder))
return SimplifyCFG(BB) | true; return SimplifyCFG(BB) | true;
Value *Cond = SI->getCondition(); Value *Cond = SI->getCondition();
@ -2465,7 +2467,7 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI) {
return SimplifyCFG(BB) | true; return SimplifyCFG(BB) | true;
// Try to transform the switch into an icmp and a branch. // Try to transform the switch into an icmp and a branch.
if (TurnSwitchRangeIntoICmp(SI)) if (TurnSwitchRangeIntoICmp(SI, Builder))
return SimplifyCFG(BB) | true; return SimplifyCFG(BB) | true;
// Remove unreachable cases. // Remove unreachable cases.
@ -2536,7 +2538,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI, IRBuilder<> &Builder){
} }
bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI) { bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
BasicBlock *BB = BI->getParent(); BasicBlock *BB = BI->getParent();
// Conditional branch // Conditional branch
@ -2545,7 +2547,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI) {
// see if that predecessor totally determines the outcome of this // see if that predecessor totally determines the outcome of this
// switch. // switch.
if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred)) if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
return SimplifyCFG(BB) | true; return SimplifyCFG(BB) | true;
// This block must be empty, except for the setcond inst, if it exists. // This block must be empty, except for the setcond inst, if it exists.
@ -2659,16 +2661,17 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
if (PN->getNumIncomingValues() == 2) if (PN->getNumIncomingValues() == 2)
Changed |= FoldTwoEntryPHINode(PN, TD, Builder); Changed |= FoldTwoEntryPHINode(PN, TD, Builder);
Builder.SetInsertPoint(BB->getTerminator());
if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) { if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) {
if (BI->isUnconditional()) { if (BI->isUnconditional()) {
if (SimplifyUncondBranch(BI, Builder)) return true; if (SimplifyUncondBranch(BI, Builder)) return true;
} else { } else {
if (SimplifyCondBranch(BI)) return true; if (SimplifyCondBranch(BI, Builder)) return true;
} }
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
if (SimplifyReturn(RI)) return true; if (SimplifyReturn(RI)) return true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) { } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
if (SimplifySwitch(SI)) return true; if (SimplifySwitch(SI, Builder)) return true;
} else if (UnreachableInst *UI = } else if (UnreachableInst *UI =
dyn_cast<UnreachableInst>(BB->getTerminator())) { dyn_cast<UnreachableInst>(BB->getTerminator())) {
if (SimplifyUnreachable(UI)) return true; if (SimplifyUnreachable(UI)) return true;