[llvm-commits] [llvm] r61100 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
Eli Friedman
eli.friedman at gmail.com
Tue Dec 16 12:54:33 PST 2008
Author: efriedma
Date: Tue Dec 16 14:54:32 2008
New Revision: 61100
URL: http://llvm.org/viewvc/llvm-project?rev=61100&view=rev
Log:
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.
Added:
llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
Modified:
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=61100&r1=61099&r2=61100&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Tue Dec 16 14:54:32 2008
@@ -386,6 +386,7 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
TrueSucc->removePredecessor(BI->getParent());
FalseSucc->removePredecessor(BI->getParent());
ReturnInst::Create(0, BI);
- BI->eraseFromParent();
+ EraseTerminatorInstAndDCECond(BI);
return true;
}
@@ -1386,10 +1385,8 @@
<< "\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 @@
} 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 @@
}
// 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;
}
}
Added: llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll?rev=61100&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll Tue Dec 16 14:54:32 2008
@@ -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(...)
+
More information about the llvm-commits
mailing list