Implement constant propogation of shift instructions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2471 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-05-06 03:01:37 +00:00
parent cf4929fa27
commit 4c1061f58c
5 changed files with 108 additions and 7 deletions

View File

@ -72,6 +72,8 @@ public:
virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
virtual ConstantBool *lessthan(const Constant *V1,
const Constant *V2) const = 0;
@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
return ConstRules::get(V1)->rem(&V1, &V2);
}
inline Constant *operator<<(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shl(&V1, &V2);
}
inline Constant *operator>>(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shr(&V1, &V2);
}
inline ConstantBool *operator<(const Constant &V1,
const Constant &V2) {
assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
return 0;
}
inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
const Constant *V1,
const Constant *V2) {
switch (Opcode) {
case Instruction::Shl: return *V1 << *V2;
case Instruction::Shr: return *V1 >> *V2;
default: return 0;
}
}
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -72,6 +72,8 @@ public:
virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
virtual ConstantBool *lessthan(const Constant *V1,
const Constant *V2) const = 0;
@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
return ConstRules::get(V1)->rem(&V1, &V2);
}
inline Constant *operator<<(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shl(&V1, &V2);
}
inline Constant *operator>>(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shr(&V1, &V2);
}
inline ConstantBool *operator<(const Constant &V1,
const Constant &V2) {
assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
return 0;
}
inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
const Constant *V1,
const Constant *V2) {
switch (Opcode) {
case Instruction::Shl: return *V1 << *V2;
case Instruction::Shr: return *V1 >> *V2;
default: return 0;
}
}
#endif

View File

@ -72,6 +72,8 @@ public:
virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *div(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
virtual ConstantBool *lessthan(const Constant *V1,
const Constant *V2) const = 0;
@ -155,6 +157,16 @@ inline Constant *operator%(const Constant &V1, const Constant &V2) {
return ConstRules::get(V1)->rem(&V1, &V2);
}
inline Constant *operator<<(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shl(&V1, &V2);
}
inline Constant *operator>>(const Constant &V1, const Constant &V2) {
assert(V1.getType()->isIntegral() && V2.getType() == Type::UByteTy);
return ConstRules::get(V1)->shr(&V1, &V2);
}
inline ConstantBool *operator<(const Constant &V1,
const Constant &V2) {
assert(V1.getType() == V2.getType() && "Constant types must be identical!");
@ -219,4 +231,14 @@ inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
return 0;
}
inline Constant *ConstantFoldShiftInstruction(unsigned Opcode,
const Constant *V1,
const Constant *V2) {
switch (Opcode) {
case Instruction::Shl: return *V1 << *V2;
case Instruction::Shr: return *V1 >> *V2;
default: return 0;
}
}
#endif