summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/ConstantProp.cpp37
-rw-r--r--llvm/lib/Transforms/Scalar/SCCP.cpp12
2 files changed, 42 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/ConstantProp.cpp b/llvm/lib/Transforms/Scalar/ConstantProp.cpp
index 77a959910fc..9e519e7cf77 100644
--- a/llvm/lib/Transforms/Scalar/ConstantProp.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantProp.cpp
@@ -97,6 +97,28 @@ ConstantFoldBinaryInst(BasicBlock *BB, BasicBlock::iterator &II,
return true;
}
+inline static bool
+ConstantFoldShiftInst(BasicBlock *BB, BasicBlock::iterator &II,
+ ShiftInst *Op,
+ Constant *D1, Constant *D2) {
+ Constant *ReplaceWith = ConstantFoldShiftInstruction(Op->getOpcode(), D1,D2);
+ if (!ReplaceWith) return false; // Nothing new to change...
+
+ // Replaces all of the uses of a variable with uses of the constant.
+ Op->replaceAllUsesWith(ReplaceWith);
+
+ // Remove the operator from the list of definitions...
+ Op->getParent()->getInstList().remove(II);
+
+ // The new constant inherits the old name of the operator...
+ if (Op->hasName())
+ ReplaceWith->setName(Op->getName(), BB->getParent()->getSymbolTableSure());
+
+ // Delete the operator now...
+ delete Op;
+ return true;
+}
+
// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
@@ -157,12 +179,12 @@ bool ConstantFoldTerminator(BasicBlock *BB, BasicBlock::iterator &II,
//
bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
Instruction *Inst = *II;
- if (isa<BinaryOperator>(Inst)) {
- Constant *D1 = dyn_cast<Constant>(Inst->getOperand(0));
- Constant *D2 = dyn_cast<Constant>(Inst->getOperand(1));
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Inst)) {
+ Constant *D1 = dyn_cast<Constant>(BO->getOperand(0));
+ Constant *D2 = dyn_cast<Constant>(BO->getOperand(1));
if (D1 && D2)
- return ConstantFoldBinaryInst(BB, II, cast<BinaryOperator>(Inst), D1, D2);
+ return ConstantFoldBinaryInst(BB, II, BO, D1, D2);
} else if (CastInst *CI = dyn_cast<CastInst>(Inst)) {
Constant *D = dyn_cast<Constant>(CI->getOperand(0));
@@ -188,7 +210,14 @@ bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
delete PN; // Finally, delete the node...
return true;
}
+ } else if (ShiftInst *SI = dyn_cast<ShiftInst>(Inst)) {
+ Constant *D1 = dyn_cast<Constant>(SI->getOperand(0));
+ Constant *D2 = dyn_cast<Constant>(SI->getOperand(1));
+
+ if (D1 && D2)
+ return ConstantFoldShiftInst(BB, II, SI, D1, D2);
}
+
return false;
}
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 8d1547577b4..015c67a0d22 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -502,9 +502,15 @@ void SCCP::visitBinaryOperator(Instruction *I) {
if (V1State.isOverdefined() || V2State.isOverdefined()) {
markOverdefined(I);
} else if (V1State.isConstant() && V2State.isConstant()) {
- Constant *Result = ConstantFoldBinaryInstruction(I->getOpcode(),
- V1State.getConstant(),
- V2State.getConstant());
+ Constant *Result = 0;
+ if (isa<BinaryOperator>(I))
+ Result = ConstantFoldBinaryInstruction(I->getOpcode(),
+ V1State.getConstant(),
+ V2State.getConstant());
+ else if (isa<ShiftInst>(I))
+ Result = ConstantFoldShiftInstruction(I->getOpcode(),
+ V1State.getConstant(),
+ V2State.getConstant());
if (Result)
markConstant(I, Result); // This instruction constant folds!
else
OpenPOWER on IntegriCloud