aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/SimplifyCFG.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-30 19:44:05 +0000
committerChris Lattner <sabre@nondot.org>2004-03-30 19:44:05 +0000
commit552112f2f8702f2cba8cb5775bc24c3e02ba265c (patch)
tree000ca8cbedbae39caae57f41e7959faed3580810 /lib/Transforms/Utils/SimplifyCFG.cpp
parentc32b30a42999e7f67b87125e0301330608ec1287 (diff)
Now that all the code generators support the select instruction, and the instcombine
pass can eliminate many nasty cases of them, start generating them in the optimizers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12545 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp87
1 files changed, 9 insertions, 78 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index a8785fe0a9..8090bc22b9 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -852,84 +852,15 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
Value *FalseVal =
PN->getIncomingValue(PN->getIncomingBlock(0) == IfTrue);
- // FIXME: when we have a 'select' statement, we can be completely
- // generic and clean here and let the instcombine pass clean up
- // after us, by folding the select instructions away when possible.
- //
- if (TrueVal == FalseVal) {
- // Degenerate case...
- PN->replaceAllUsesWith(TrueVal);
- BB->getInstList().erase(PN);
- Changed = true;
- } else if (isa<ConstantBool>(TrueVal) &&
- isa<ConstantBool>(FalseVal)) {
- if (TrueVal == ConstantBool::True) {
- // The PHI node produces the same thing as the condition.
- PN->replaceAllUsesWith(IfCond);
- } else {
- // The PHI node produces the inverse of the condition. Insert a
- // "NOT" instruction, which is really a XOR.
- Value *InverseCond =
- BinaryOperator::createNot(IfCond, IfCond->getName()+".inv",
- AfterPHIIt);
- PN->replaceAllUsesWith(InverseCond);
- }
- BB->getInstList().erase(PN);
- Changed = true;
- } else if (isa<ConstantInt>(TrueVal) && isa<ConstantInt>(FalseVal)){
- // If this is a PHI of two constant integers, we insert a cast of
- // the boolean to the integer type in question, giving us 0 or 1.
- // Then we multiply this by the difference of the two constants,
- // giving us 0 if false, and the difference if true. We add this
- // result to the base constant, giving us our final value. We
- // rely on the instruction combiner to eliminate many special
- // cases, like turning multiplies into shifts when possible.
- std::string Name = PN->getName(); PN->setName("");
- Value *TheCast = new CastInst(IfCond, TrueVal->getType(),
- Name, AfterPHIIt);
- Constant *TheDiff = ConstantExpr::get(Instruction::Sub,
- cast<Constant>(TrueVal),
- cast<Constant>(FalseVal));
- Value *V = TheCast;
- if (TheDiff != ConstantInt::get(TrueVal->getType(), 1))
- V = BinaryOperator::create(Instruction::Mul, TheCast,
- TheDiff, TheCast->getName()+".scale",
- AfterPHIIt);
- if (!cast<Constant>(FalseVal)->isNullValue())
- V = BinaryOperator::create(Instruction::Add, V, FalseVal,
- V->getName()+".offs", AfterPHIIt);
- PN->replaceAllUsesWith(V);
- BB->getInstList().erase(PN);
- Changed = true;
- } else if (isa<ConstantInt>(FalseVal) &&
- cast<Constant>(FalseVal)->isNullValue()) {
- // If the false condition is an integral zero value, we can
- // compute the PHI by multiplying the condition by the other
- // value.
- std::string Name = PN->getName(); PN->setName("");
- Value *TheCast = new CastInst(IfCond, TrueVal->getType(),
- Name+".c", AfterPHIIt);
- Value *V = BinaryOperator::create(Instruction::Mul, TrueVal,
- TheCast, Name, AfterPHIIt);
- PN->replaceAllUsesWith(V);
- BB->getInstList().erase(PN);
- Changed = true;
- } else if (isa<ConstantInt>(TrueVal) &&
- cast<Constant>(TrueVal)->isNullValue()) {
- // If the true condition is an integral zero value, we can compute
- // the PHI by multiplying the inverse condition by the other
- // value.
- std::string Name = PN->getName(); PN->setName("");
- Value *NotCond = BinaryOperator::createNot(IfCond, Name+".inv",
- AfterPHIIt);
- Value *TheCast = new CastInst(NotCond, TrueVal->getType(),
- Name+".inv", AfterPHIIt);
- Value *V = BinaryOperator::create(Instruction::Mul, FalseVal,
- TheCast, Name, AfterPHIIt);
- PN->replaceAllUsesWith(V);
- BB->getInstList().erase(PN);
- Changed = true;
- }
+ // Change the PHI node into a select instruction.
+ BasicBlock::iterator InsertPos = PN;
+ while (isa<PHINode>(InsertPos)) ++InsertPos;
+
+ std::string Name = PN->getName(); PN->setName("");
+ PN->replaceAllUsesWith(new SelectInst(IfCond, TrueVal, FalseVal,
+ Name, InsertPos));
+ BB->getInstList().erase(PN);
+ Changed = true;
}
}
}