#define LLVM_CONSTANTHANDLING_H
#include "llvm/Constants.h"
-#include "llvm/Instruction.h"
#include "llvm/Type.h"
class PointerType;
virtual Constant *op_not(const Constant *V) const = 0;
// Binary Operators...
- virtual Constant *add(const Constant *V1,
- const Constant *V2) const = 0;
- virtual Constant *sub(const Constant *V1,
- const Constant *V2) const = 0;
- virtual Constant *mul(const Constant *V1,
- const Constant *V2) const = 0;
- virtual Constant *div(const Constant *V1,
- const Constant *V2) const = 0;
+ virtual Constant *add(const Constant *V1, const Constant *V2) const = 0;
+ virtual Constant *sub(const Constant *V1, const Constant *V2) const = 0;
+ 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;
};
-inline Constant *operator!(const Constant &V) {
+inline Constant *operator~(const Constant &V) {
return ConstRules::get(V)->op_not(&V);
}
return ConstRules::get(V1)->div(&V1, &V2);
}
+inline Constant *operator%(const Constant &V1, const Constant &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ 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!");
// Implement higher level instruction folding type instructions
//===----------------------------------------------------------------------===//
-inline Constant *ConstantFoldCastInstruction(const Constant *V,
- const Type *DestTy) {
- return ConstRules::get(*V)->castTo(V, DestTy);
-}
-
-inline Constant *ConstantFoldUnaryInstruction(unsigned Opcode,
- const Constant *V) {
- switch (Opcode) {
- case Instruction::Not: return !*V;
- // TODO: Handle get element ptr instruction here in the future? GEP null?
- }
- return 0;
-}
-
-inline Constant *ConstantFoldBinaryInstruction(unsigned Opcode,
- const Constant *V1,
- const Constant *V2) {
- switch (Opcode) {
- case Instruction::Add: return *V1 + *V2;
- case Instruction::Sub: return *V1 - *V2;
- case Instruction::Mul: return *V1 * *V2;
- case Instruction::Div: return *V1 / *V2;
-
- case Instruction::SetEQ: return *V1 == *V2;
- case Instruction::SetNE: return *V1 != *V2;
- case Instruction::SetLE: return *V1 <= *V2;
- case Instruction::SetGE: return *V1 >= *V2;
- case Instruction::SetLT: return *V1 < *V2;
- case Instruction::SetGT: return *V1 > *V2;
- }
- return 0;
-}
+// ConstantFoldInstruction - Attempt to constant fold the specified instruction.
+// If successful, the constant result is returned, if not, null is returned.
+//
+Constant *ConstantFoldInstruction(Instruction *I);
+
+// Constant fold various types of instruction...
+Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy);
+Constant *ConstantFoldUnaryInstruction(unsigned Opcode, const Constant *V);
+Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
+ const Constant *V2);
+Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1,
+ const Constant *V2);
#endif