mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Add a helper to remove a branch and DCE the condition, and use it
consistently for deleting branches. In addition to being slightly more readable, this makes SimplifyCFG a bit better about cleaning up after itself when it makes conditions unused. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61100 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
00dc84a2ca
commit
080efb8cea
@ -386,6 +386,7 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
|
||||
// We can hoist loads that are non-volatile and obviously cannot trap.
|
||||
if (cast<LoadInst>(I)->isVolatile())
|
||||
return false;
|
||||
// FIXME: A computation of a constant can trap!
|
||||
if (!isa<AllocaInst>(I->getOperand(0)) &&
|
||||
!isa<Constant>(I->getOperand(0)))
|
||||
return false;
|
||||
@ -494,6 +495,19 @@ static bool GatherValueComparisons(Instruction *Cond, Value *&CompVal,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) {
|
||||
Instruction* Cond = 0;
|
||||
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
||||
Cond = dyn_cast<Instruction>(SI->getCondition());
|
||||
} else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
|
||||
if (BI->isConditional())
|
||||
Cond = dyn_cast<Instruction>(BI->getCondition());
|
||||
}
|
||||
|
||||
TI->eraseFromParent();
|
||||
if (Cond) RecursivelyDeleteTriviallyDeadInstructions(Cond);
|
||||
}
|
||||
|
||||
/// isValueEqualityComparison - Return true if the specified terminator checks
|
||||
/// to see if a value is equal to constant integer value.
|
||||
static Value *isValueEqualityComparison(TerminatorInst *TI) {
|
||||
@ -617,11 +631,10 @@ static bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
|
||||
// PredCases. If there are any cases in ThisCases that are in PredCases, we
|
||||
// can simplify TI.
|
||||
if (ValuesOverlap(PredCases, ThisCases)) {
|
||||
if (BranchInst *BTI = dyn_cast<BranchInst>(TI)) {
|
||||
if (isa<BranchInst>(TI)) {
|
||||
// Okay, one of the successors of this condbr is dead. Convert it to a
|
||||
// uncond br.
|
||||
assert(ThisCases.size() == 1 && "Branch can only have one case!");
|
||||
Value *Cond = BTI->getCondition();
|
||||
// Insert the new branch.
|
||||
Instruction *NI = BranchInst::Create(ThisDef, TI);
|
||||
|
||||
@ -631,10 +644,7 @@ static bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
|
||||
DOUT << "Threading pred instr: " << *Pred->getTerminator()
|
||||
<< "Through successor TI: " << *TI << "Leaving: " << *NI << "\n";
|
||||
|
||||
TI->eraseFromParent(); // Nuke the old one.
|
||||
// If condition is now dead, nuke it.
|
||||
if (Instruction *CondI = dyn_cast<Instruction>(Cond))
|
||||
RecursivelyDeleteTriviallyDeadInstructions(CondI);
|
||||
EraseTerminatorInstAndDCECond(TI);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
@ -697,12 +707,8 @@ static bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
|
||||
|
||||
DOUT << "Threading pred instr: " << *Pred->getTerminator()
|
||||
<< "Through successor TI: " << *TI << "Leaving: " << *NI << "\n";
|
||||
Instruction *Cond = 0;
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(TI))
|
||||
Cond = dyn_cast<Instruction>(BI->getCondition());
|
||||
TI->eraseFromParent(); // Nuke the old one.
|
||||
|
||||
if (Cond) RecursivelyDeleteTriviallyDeadInstructions(Cond);
|
||||
EraseTerminatorInstAndDCECond(TI);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -811,14 +817,7 @@ static bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI) {
|
||||
for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
|
||||
NewSI->addCase(PredCases[i].first, PredCases[i].second);
|
||||
|
||||
Instruction *DeadCond = 0;
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(PTI))
|
||||
// If PTI is a branch, remember the condition.
|
||||
DeadCond = dyn_cast<Instruction>(BI->getCondition());
|
||||
Pred->getInstList().erase(PTI);
|
||||
|
||||
// If the condition is dead now, remove the instruction tree.
|
||||
if (DeadCond) RecursivelyDeleteTriviallyDeadInstructions(DeadCond);
|
||||
EraseTerminatorInstAndDCECond(PTI);
|
||||
|
||||
// Okay, last check. If BB is still a successor of PSI, then we must
|
||||
// have an infinite loop case. If so, add an infinitely looping block
|
||||
@ -921,7 +920,7 @@ HoistTerminator:
|
||||
for (succ_iterator SI = succ_begin(BB1), E = succ_end(BB1); SI != E; ++SI)
|
||||
AddPredecessorToBlock(*SI, BIParent, BB1);
|
||||
|
||||
BI->eraseFromParent();
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1331,7 +1330,7 @@ static bool SimplifyCondBranchToTwoReturns(BranchInst *BI) {
|
||||
TrueSucc->removePredecessor(BI->getParent());
|
||||
FalseSucc->removePredecessor(BI->getParent());
|
||||
ReturnInst::Create(0, BI);
|
||||
BI->eraseFromParent();
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1386,10 +1385,8 @@ static bool SimplifyCondBranchToTwoReturns(BranchInst *BI) {
|
||||
<< "\n " << *BI << "NewRet = " << *RI
|
||||
<< "TRUEBLOCK: " << *TrueSucc << "FALSEBLOCK: "<< *FalseSucc;
|
||||
|
||||
BI->eraseFromParent();
|
||||
|
||||
if (Instruction *BrCondI = dyn_cast<Instruction>(BrCond))
|
||||
RecursivelyDeleteTriviallyDeadInstructions(BrCondI);
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1910,10 +1907,10 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
|
||||
} else {
|
||||
if (BI->getSuccessor(0) == BB) {
|
||||
BranchInst::Create(BI->getSuccessor(1), BI);
|
||||
BI->eraseFromParent();
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
} else if (BI->getSuccessor(1) == BB) {
|
||||
BranchInst::Create(BI->getSuccessor(0), BI);
|
||||
BI->eraseFromParent();
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
@ -2086,11 +2083,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
|
||||
}
|
||||
|
||||
// Erase the old branch instruction.
|
||||
(*PI)->getInstList().erase(BI);
|
||||
|
||||
// Erase the potentially condition tree that was used to computed the
|
||||
// branch condition.
|
||||
RecursivelyDeleteTriviallyDeadInstructions(Cond);
|
||||
EraseTerminatorInstAndDCECond(BI);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
46
test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
Normal file
46
test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | not grep icmp
|
||||
; ModuleID = '/tmp/x.bc'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-pc-linux-gnu"
|
||||
|
||||
define i32 @x(i32 %x) {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, 8 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %ifthen, label %ifend
|
||||
|
||||
ifthen: ; preds = %entry
|
||||
%call = call i32 (...)* @foo() ; <i32> [#uses=0]
|
||||
br label %ifend
|
||||
|
||||
ifend: ; preds = %ifthen, %entry
|
||||
%cmp2 = icmp ne i32 %x, 8 ; <i1> [#uses=1]
|
||||
br i1 %cmp2, label %ifthen3, label %ifend5
|
||||
|
||||
ifthen3: ; preds = %ifend
|
||||
%call4 = call i32 (...)* @foo() ; <i32> [#uses=0]
|
||||
br label %ifend5
|
||||
|
||||
ifend5: ; preds = %ifthen3, %ifend
|
||||
%cmp7 = icmp eq i32 %x, 9 ; <i1> [#uses=1]
|
||||
br i1 %cmp7, label %ifthen8, label %ifend10
|
||||
|
||||
ifthen8: ; preds = %ifend5
|
||||
%call9 = call i32 (...)* @bar() ; <i32> [#uses=0]
|
||||
br label %ifend10
|
||||
|
||||
ifend10: ; preds = %ifthen8, %ifend5
|
||||
%cmp12 = icmp ne i32 %x, 9 ; <i1> [#uses=1]
|
||||
br i1 %cmp12, label %ifthen13, label %ifend15
|
||||
|
||||
ifthen13: ; preds = %ifend10
|
||||
%call14 = call i32 (...)* @bar() ; <i32> [#uses=0]
|
||||
br label %ifend15
|
||||
|
||||
ifend15: ; preds = %ifthen13, %ifend10
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @foo(...)
|
||||
|
||||
declare i32 @bar(...)
|
||||
|
Loading…
Reference in New Issue
Block a user