[llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri May 26 18:18:17 PDT 2006
Changes in directory llvm/lib/Transforms/Utils:
Local.cpp updated: 1.57 -> 1.58
---
Log message:
Refactor some code to expose an interface to constant fold and instruction given it's opcode, typeand operands.
---
Diffs of the changes: (+49 -35)
Local.cpp | 84 ++++++++++++++++++++++++++++++++++++--------------------------
1 files changed, 49 insertions(+), 35 deletions(-)
Index: llvm/lib/Transforms/Utils/Local.cpp
diff -u llvm/lib/Transforms/Utils/Local.cpp:1.57 llvm/lib/Transforms/Utils/Local.cpp:1.58
--- llvm/lib/Transforms/Utils/Local.cpp:1.57 Thu May 25 16:25:12 2006
+++ llvm/lib/Transforms/Utils/Local.cpp Fri May 26 20:18:04 2006
@@ -64,18 +64,6 @@
// If we reach here, all incoming values are the same constant.
return Result;
- } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
- if (Function *F = CI->getCalledFunction())
- if (canConstantFoldCallTo(F)) {
- std::vector<Constant*> Args;
- for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
- if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
- Args.push_back(Op);
- else
- return 0;
- return ConstantFoldCall(F, Args);
- }
- return 0;
}
Constant *Op0 = 0, *Op1 = 0;
@@ -91,37 +79,63 @@
case 0: return 0;
}
- if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
- return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+ if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
+ if (Constant *Op0 = dyn_cast<Constant>(I->getOperand(0)))
+ if (Constant *Op1 = dyn_cast<Constant>(I->getOperand(1)))
+ return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+ return 0; // Operands not constants.
+ }
- switch (I->getOpcode()) {
+ // Scan the operand list, checking to see if the are all constants, if so,
+ // hand off to ConstantFoldInstOperands.
+ std::vector<Constant*> Ops;
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
+ Ops.push_back(Op);
+ else
+ return 0; // All operands not constant!
+
+ return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops);
+}
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified opcode and operands. If successful, the constant result is
+/// returned, if not, null is returned. Note that this function can fail when
+/// attempting to fold instructions like loads and stores, which have no
+/// constant expression form.
+///
+Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
+ const std::vector<Constant*> &Ops) {
+ if (Opc >= Instruction::BinaryOpsBegin && Opc < Instruction::BinaryOpsEnd)
+ return ConstantExpr::get(Opc, Ops[0], Ops[1]);
+
+ switch (Opc) {
default: return 0;
+ case Instruction::Call:
+ if (Function *F = dyn_cast<Function>(Ops[0])) {
+ if (canConstantFoldCallTo(F)) {
+ std::vector<Constant*> Args(Ops.begin()+1, Ops.end());
+ return ConstantFoldCall(F, Args);
+ }
+ }
+ return 0;
+ case Instruction::Shl:
+ case Instruction::Shr:
+ return ConstantExpr::get(Opc, Ops[0], Ops[1]);
case Instruction::Cast:
- return ConstantExpr::getCast(Op0, I->getType());
+ return ConstantExpr::getCast(Ops[0], DestTy);
case Instruction::Select:
- if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
- return ConstantExpr::getSelect(Op0, Op1, Op2);
- return 0;
+ return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
case Instruction::ExtractElement:
- return ConstantExpr::getExtractElement(Op0, Op1);
+ return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
case Instruction::InsertElement:
- if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
- return ConstantExpr::getInsertElement(Op0, Op1, Op2);
- return 0;
+ return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
case Instruction::ShuffleVector:
- if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
- return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
- return 0;
+ return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr:
- std::vector<Constant*> IdxList;
- IdxList.reserve(I->getNumOperands()-1);
- if (Op1) IdxList.push_back(Op1);
- for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
- if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
- IdxList.push_back(C);
- else
- return 0; // Non-constant operand
- return ConstantExpr::getGetElementPtr(Op0, IdxList);
+ return ConstantExpr::getGetElementPtr(Ops[0],
+ std::vector<Constant*>(Ops.begin()+1,
+ Ops.end()));
}
}
More information about the llvm-commits
mailing list