X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFolding.h;h=1479fe01ef889d6bfee42aa4b32c480874145227;hb=67e08db3b97e83637c596e3ef4866e64552762cc;hp=4facdc38e1fe156184c8107fe634aadfd9fd7524;hpb=6bb09d96a05f9cfab4b0ef4a2b834d6ff4e6caa5;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h index 4facdc38e1f..1479fe01ef8 100644 --- a/lib/VMCore/ConstantFolding.h +++ b/lib/VMCore/ConstantFolding.h @@ -5,17 +5,15 @@ // // Unfortunately we can't overload operators on pointer types (like this:) // -// inline bool operator==(const ConstPoolVal *V1, const ConstPoolVal *V2) +// inline bool operator==(const Constant *V1, const Constant *V2) // // so we must make due with references, even though it leads to some butt ugly -// looking code downstream. *sigh* (ex: ConstPoolVal *Result = *V1 + *v2; ) +// looking code downstream. *sigh* (ex: Constant *Result = *V1 + *v2; ) // //===----------------------------------------------------------------------===// // -// WARNING: These operators return pointers to newly 'new'd objects. You MUST -// make sure to free them if you don't want them hanging around. Also, -// note that these may return a null object if I don't know how to -// perform those operations on the specified constant types. +// WARNING: These operators may return a null object if I don't know how to +// perform the specified operation on the specified constant types. // //===----------------------------------------------------------------------===// // @@ -32,82 +30,131 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OPT_CONSTANTHANDLING_H -#define LLVM_OPT_CONSTANTHANDLING_H +#ifndef LLVM_CONSTANTHANDLING_H +#define LLVM_CONSTANTHANDLING_H -#include "llvm/ConstPoolVals.h" +#include "llvm/ConstantVals.h" #include "llvm/Instruction.h" #include "llvm/Type.h" +class PointerType; //===----------------------------------------------------------------------===// -// Implement == directly... +// Implement == and != directly... //===----------------------------------------------------------------------===// -inline ConstPoolBool *operator==(const ConstPoolVal &V1, - const ConstPoolVal &V2) { +inline ConstantBool *operator==(const Constant &V1, + const Constant &V2) { assert(V1.getType() == V2.getType() && "Constant types must be identical!"); - return new ConstPoolBool(V1.equals(&V2)); + return ConstantBool::get(&V1 == &V2); +} + +inline ConstantBool *operator!=(const Constant &V1, + const Constant &V2) { + return ConstantBool::get(&V1 != &V2); } //===----------------------------------------------------------------------===// // Implement all other operators indirectly through TypeRules system //===----------------------------------------------------------------------===// -class ConstRules { +class ConstRules : public Annotation { protected: - inline ConstRules() {} // Can only be subclassed... + inline ConstRules() : Annotation(AID) {} // Can only be subclassed... public: + static AnnotationID AID; // AnnotationID for this class + // Unary Operators... - virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0; - virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0; + virtual Constant *op_not(const Constant *V) const = 0; // Binary Operators... - virtual ConstPoolVal *add(const ConstPoolVal *V1, - const ConstPoolVal *V2) const = 0; - virtual ConstPoolVal *sub(const ConstPoolVal *V1, - const ConstPoolVal *V2) const = 0; - - virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, - const ConstPoolVal *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 ConstantBool *lessthan(const Constant *V1, + const Constant *V2) const = 0; + + // Casting operators. ick + virtual ConstantBool *castToBool (const Constant *V) const = 0; + virtual ConstantSInt *castToSByte (const Constant *V) const = 0; + virtual ConstantUInt *castToUByte (const Constant *V) const = 0; + virtual ConstantSInt *castToShort (const Constant *V) const = 0; + virtual ConstantUInt *castToUShort(const Constant *V) const = 0; + virtual ConstantSInt *castToInt (const Constant *V) const = 0; + virtual ConstantUInt *castToUInt (const Constant *V) const = 0; + virtual ConstantSInt *castToLong (const Constant *V) const = 0; + virtual ConstantUInt *castToULong (const Constant *V) const = 0; + virtual ConstantFP *castToFloat (const Constant *V) const = 0; + virtual ConstantFP *castToDouble(const Constant *V) const = 0; + virtual ConstantPointer *castToPointer(const Constant *V, + const PointerType *Ty) const = 0; + + inline Constant *castTo(const Constant *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); + case Type::PointerTyID:return castToPointer(V, (PointerType*)Ty); + 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... // - static inline const ConstRules *get(const ConstPoolVal &V) { - const ConstRules *Result = V.getType()->getConstRules(); - return Result ? Result : find(V.getType()); + static inline ConstRules *get(const Constant &V) { + return (ConstRules*)V.getType()->getOrCreateAnnotation(AID); } private : - static const ConstRules *find(const Type *Ty); + static Annotation *find(AnnotationID AID, const Annotable *Ty, void *); ConstRules(const ConstRules &); // Do not implement ConstRules &operator=(const ConstRules &); // Do not implement }; -inline ConstPoolVal *operator-(const ConstPoolVal &V) { - return ConstRules::get(V)->neg(&V); -} - -inline ConstPoolVal *operator!(const ConstPoolVal &V) { - return ConstRules::get(V)->not(&V); +inline Constant *operator!(const Constant &V) { + return ConstRules::get(V)->op_not(&V); } -inline ConstPoolVal *operator+(const ConstPoolVal &V1, const ConstPoolVal &V2) { +inline Constant *operator+(const Constant &V1, const Constant &V2) { assert(V1.getType() == V2.getType() && "Constant types must be identical!"); return ConstRules::get(V1)->add(&V1, &V2); } -inline ConstPoolVal *operator-(const ConstPoolVal &V1, const ConstPoolVal &V2) { +inline Constant *operator-(const Constant &V1, const Constant &V2) { assert(V1.getType() == V2.getType() && "Constant types must be identical!"); return ConstRules::get(V1)->sub(&V1, &V2); } -inline ConstPoolBool *operator<(const ConstPoolVal &V1, - const ConstPoolVal &V2) { +inline Constant *operator*(const Constant &V1, const Constant &V2) { + assert(V1.getType() == V2.getType() && "Constant types must be identical!"); + return ConstRules::get(V1)->mul(&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)->div(&V1, &V2); +} + +inline ConstantBool *operator<(const Constant &V1, + const Constant &V2) { assert(V1.getType() == V2.getType() && "Constant types must be identical!"); return ConstRules::get(V1)->lessthan(&V1, &V2); } @@ -117,30 +164,19 @@ inline ConstPoolBool *operator<(const ConstPoolVal &V1, // Implement 'derived' operators based on what we already have... //===----------------------------------------------------------------------===// -inline ConstPoolBool *operator>(const ConstPoolVal &V1, - const ConstPoolVal &V2) { +inline ConstantBool *operator>(const Constant &V1, + const Constant &V2) { return V2 < V1; } -inline ConstPoolBool *operator!=(const ConstPoolVal &V1, - const ConstPoolVal &V2) { - ConstPoolBool *Result = V1 == V2; - Result->setValue(!Result->getValue()); // Invert value - return Result; // !(V1 == V2) +inline ConstantBool *operator>=(const Constant &V1, + const Constant &V2) { + return (V1 < V2)->inverted(); // !(V1 < V2) } -inline ConstPoolBool *operator>=(const ConstPoolVal &V1, - const ConstPoolVal &V2) { - ConstPoolBool *Result = V1 < V2; - Result->setValue(!Result->getValue()); // Invert value - return Result; // !(V1 < V2) -} - -inline ConstPoolBool *operator<=(const ConstPoolVal &V1, - const ConstPoolVal &V2) { - ConstPoolBool *Result = V1 > V2; - Result->setValue(!Result->getValue()); // Invert value - return Result; // !(V1 > V2) +inline ConstantBool *operator<=(const Constant &V1, + const Constant &V2) { + return (V1 > V2)->inverted(); // !(V1 > V2) } @@ -148,21 +184,28 @@ inline ConstPoolBool *operator<=(const ConstPoolVal &V1, // Implement higher level instruction folding type instructions //===----------------------------------------------------------------------===// -inline ConstPoolVal *ConstantFoldUnaryInstruction(unsigned Opcode, - ConstPoolVal *V) { +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; - case Instruction::Neg: return -*V; + // TODO: Handle get element ptr instruction here in the future? GEP null? } return 0; } -inline ConstPoolVal *ConstantFoldBinaryInstruction(unsigned Opcode, - ConstPoolVal *V1, - ConstPoolVal *V2) { +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;