#define LLVM_OPT_CONSTANTHANDLING_H
#include "llvm/ConstPoolVals.h"
+#include "llvm/Instruction.h"
#include "llvm/Type.h"
+namespace opt {
+
//===----------------------------------------------------------------------===//
// Implement == directly...
//===----------------------------------------------------------------------===//
inline ConstRules() {} // Can only be subclassed...
public:
// Unary Operators...
- virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0;
virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0;
// Binary Operators...
const ConstPoolVal *V2) const = 0;
virtual ConstPoolVal *sub(const ConstPoolVal *V1,
const ConstPoolVal *V2) const = 0;
+ virtual ConstPoolVal *mul(const ConstPoolVal *V1,
+ const ConstPoolVal *V2) const = 0;
virtual ConstPoolBool *lessthan(const ConstPoolVal *V1,
const ConstPoolVal *V2) const = 0;
+ // Casting operators. ick
+ virtual ConstPoolBool *castToBool (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolSInt *castToSByte (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolUInt *castToUByte (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolSInt *castToShort (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolUInt *castToUShort(const ConstPoolVal *V) const = 0;
+ virtual ConstPoolSInt *castToInt (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolUInt *castToUInt (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolSInt *castToLong (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolUInt *castToULong (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolFP *castToFloat (const ConstPoolVal *V) const = 0;
+ virtual ConstPoolFP *castToDouble(const ConstPoolVal *V) const = 0;
+
+ inline ConstPoolVal *castTo(const ConstPoolVal *V, const Type *Ty) const {
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID: return castToBool(V);
+ case Type::UByteTyID: return castToUByte(V);
+ case Type::SByteTyID: return castToSByte(V);
+ case Type::UShortTyID: return castToUShort(V);
+ case Type::ShortTyID: return castToShort(V);
+ case Type::UIntTyID: return castToUInt(V);
+ case Type::IntTyID: return castToInt(V);
+ case Type::ULongTyID: return castToULong(V);
+ case Type::LongTyID: return castToLong(V);
+ case Type::FloatTyID: return castToFloat(V);
+ case Type::DoubleTyID: return castToDouble(V);
+ default: return 0;
+ }
+ }
+
// ConstRules::get - A type will cache its own type rules if one is needed...
// we just want to make sure to hit the cache instead of doing it indirectly,
// if possible...
};
-inline ConstPoolVal *operator-(const ConstPoolVal &V) {
- return ConstRules::get(V)->neg(&V);
-}
-
inline ConstPoolVal *operator!(const ConstPoolVal &V) {
return ConstRules::get(V)->not(&V);
}
return ConstRules::get(V1)->sub(&V1, &V2);
}
+inline ConstPoolVal *operator*(const ConstPoolVal &V1, const ConstPoolVal &V2) {
+ assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+ return ConstRules::get(V1)->mul(&V1, &V2);
+}
+
inline ConstPoolBool *operator<(const ConstPoolVal &V1,
const ConstPoolVal &V2) {
assert(V1.getType() == V2.getType() && "Constant types must be identical!");
return Result; // !(V1 > V2)
}
+
+//===----------------------------------------------------------------------===//
+// Implement higher level instruction folding type instructions
+//===----------------------------------------------------------------------===//
+
+inline ConstPoolVal *ConstantFoldUnaryInstruction(unsigned Opcode,
+ ConstPoolVal *V) {
+ switch (Opcode) {
+ case Instruction::Not: return !*V;
+ }
+ return 0;
+}
+
+inline ConstPoolVal *ConstantFoldBinaryInstruction(unsigned Opcode,
+ ConstPoolVal *V1,
+ ConstPoolVal *V2) {
+ switch (Opcode) {
+ case Instruction::Add: return *V1 + *V2;
+ case Instruction::Sub: 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;
+}
+
+} // end namespace opt
#endif