[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu May 11 10:12:04 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.478 -> 1.479
---
Log message:
Refactor some code, making it simpler.
When doing the initial pass of constant folding, if we get a constantexpr,
simplify the constant expr like we would do if the constant is folded in the
normal loop.
This fixes the missed-optimization regression in
Transforms/InstCombine/getelementptr.ll last night.
---
Diffs of the changes: (+43 -31)
InstructionCombining.cpp | 74 +++++++++++++++++++++++++++--------------------
1 files changed, 43 insertions(+), 31 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.479
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 Wed May 10 14:00:36 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 11 12:11:52 2006
@@ -7317,6 +7317,33 @@
return true;
}
+/// OptimizeConstantExpr - Given a constant expression and target data layout
+/// information, symbolically evaluation the constant expr to something simpler
+/// if possible.
+static Constant *OptimizeConstantExpr(ConstantExpr *CE, const TargetData *TD) {
+ if (!TD) return CE;
+
+ Constant *Ptr = CE->getOperand(0);
+ if (CE->getOpcode() == Instruction::GetElementPtr && Ptr->isNullValue() &&
+ cast<PointerType>(Ptr->getType())->getElementType()->isSized()) {
+ // If this is a constant expr gep that is effectively computing an
+ // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
+ bool isFoldableGEP = true;
+ for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+ if (!isa<ConstantInt>(CE->getOperand(i)))
+ isFoldableGEP = false;
+ if (isFoldableGEP) {
+ std::vector<Value*> Ops(CE->op_begin()+1, CE->op_end());
+ uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), Ops);
+ Constant *C = ConstantUInt::get(Type::ULongTy, Offset);
+ C = ConstantExpr::getCast(C, TD->getIntPtrType());
+ return ConstantExpr::getCast(C, CE->getType());
+ }
+ }
+
+ return CE;
+}
+
/// AddReachableCodeToWorklist - Walk the function in depth-first order, adding
/// all reachable code to the worklist.
@@ -7329,7 +7356,8 @@
///
static void AddReachableCodeToWorklist(BasicBlock *BB,
std::set<BasicBlock*> &Visited,
- std::vector<Instruction*> &WorkList) {
+ std::vector<Instruction*> &WorkList,
+ const TargetData *TD) {
// We have now visited this block! If we've already been here, bail out.
if (!Visited.insert(BB).second) return;
@@ -7346,6 +7374,8 @@
// ConstantProp instruction if trivially constant.
if (Constant *C = ConstantFoldInstruction(Inst)) {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = OptimizeConstantExpr(CE, TD);
DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *Inst);
Inst->replaceAllUsesWith(C);
++NumConstProp;
@@ -7362,7 +7392,8 @@
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (BI->isConditional() && isa<ConstantBool>(BI->getCondition())) {
bool CondVal = cast<ConstantBool>(BI->getCondition())->getValue();
- AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList);
+ AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList,
+ TD);
return;
}
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
@@ -7370,18 +7401,18 @@
// See if this is an explicit destination.
for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i)
if (SI->getCaseValue(i) == Cond) {
- AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList);
+ AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList,TD);
return;
}
// Otherwise it is the default destination.
- AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList);
+ AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList, TD);
return;
}
}
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
- AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList);
+ AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList, TD);
}
bool InstCombiner::runOnFunction(Function &F) {
@@ -7393,7 +7424,7 @@
// the reachable instructions. Ignore blocks that are not reachable. Keep
// track of which blocks we visit.
std::set<BasicBlock*> Visited;
- AddReachableCodeToWorklist(F.begin(), Visited, WorkList);
+ AddReachableCodeToWorklist(F.begin(), Visited, WorkList, TD);
// Do a quick scan over the function. If we find any blocks that are
// unreachable, remove any instructions inside of them. This prevents
@@ -7418,10 +7449,9 @@
Instruction *I = WorkList.back(); // Get an instruction from the worklist
WorkList.pop_back();
- // Check to see if we can DCE or ConstantPropagate the instruction...
- // Check to see if we can DIE the instruction...
+ // Check to see if we can DCE the instruction.
if (isInstructionTriviallyDead(I)) {
- // Add operands to the worklist...
+ // Add operands to the worklist.
if (I->getNumOperands() < 4)
AddUsesToWorkList(*I);
++NumDeadInst;
@@ -7433,31 +7463,13 @@
continue;
}
- // Instruction isn't dead, see if we can constant propagate it...
+ // Instruction isn't dead, see if we can constant propagate it.
if (Constant *C = ConstantFoldInstruction(I)) {
- Value* Ptr = I->getOperand(0);
- if (isa<GetElementPtrInst>(I) &&
- cast<Constant>(Ptr)->isNullValue() &&
- !isa<ConstantPointerNull>(C) &&
- cast<PointerType>(Ptr->getType())->getElementType()->isSized()) {
- // If this is a constant expr gep that is effectively computing an
- // "offsetof", fold it into 'cast int X to T*' instead of 'gep 0, 0, 12'
- bool isFoldableGEP = true;
- for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i)
- if (!isa<ConstantInt>(I->getOperand(i)))
- isFoldableGEP = false;
- if (isFoldableGEP) {
- uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
- std::vector<Value*>(I->op_begin()+1, I->op_end()));
- C = ConstantUInt::get(Type::ULongTy, Offset);
- C = ConstantExpr::getCast(C, TD->getIntPtrType());
- C = ConstantExpr::getCast(C, I->getType());
- }
- }
-
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = OptimizeConstantExpr(CE, TD);
DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *I);
- // Add operands to the worklist...
+ // Add operands to the worklist.
AddUsesToWorkList(*I);
ReplaceInstUsesWith(*I, C);
More information about the llvm-commits
mailing list