mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Implement constant propogation of shift instructions
llvm-svn: 2471
This commit is contained in:
parent
5b5663b806
commit
d12eac0b1b
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user