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;
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!");
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
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.
//
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));
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;
}
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
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;
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!");
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
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;
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!");
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