X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.h;h=546b37e605fc1cd74550e7feb59cd6d700106f74;hb=ce8a14915d2971039b576e03a32e0ba7c421dba7;hp=9ce1b2cb0871e502ddc110ce59ae4415bcae376d;hpb=0b693fb1251bd39f123f9f88ac43d86152f29720;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index 9ce1b2cb087..546b37e605f 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -5,10 +5,10 @@ // // 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; ) // //===----------------------------------------------------------------------===// // @@ -30,28 +30,26 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OPT_CONSTANTHANDLING_H -#define LLVM_OPT_CONSTANTHANDLING_H +#ifndef LLVM_CONSTANTHANDLING_H +#define LLVM_CONSTANTHANDLING_H -#include "llvm/ConstPoolVals.h" -#include "llvm/Instruction.h" +#include "llvm/Constants.h" #include "llvm/Type.h" - -namespace opt { +class PointerType; //===----------------------------------------------------------------------===// // 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 ConstPoolBool::get(&V1 == &V2); + return ConstantBool::get(&V1 == &V2); } -inline ConstPoolBool *operator!=(const ConstPoolVal &V1, - const ConstPoolVal &V2) { - return ConstPoolBool::get(&V1 != &V2); +inline ConstantBool *operator!=(const Constant &V1, + const Constant &V2) { + return ConstantBool::get(&V1 != &V2); } //===----------------------------------------------------------------------===// @@ -64,34 +62,37 @@ protected: public: static AnnotationID AID; // AnnotationID for this class - // Unary Operators... - virtual ConstPoolVal *op_not(const ConstPoolVal *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 ConstPoolVal *mul(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 Constant *rem(const Constant *V1, const Constant *V2) const = 0; + virtual Constant *op_and(const Constant *V1, const Constant *V2) const = 0; + virtual Constant *op_or (const Constant *V1, const Constant *V2) const = 0; + virtual Constant *op_xor(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; // 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 { + 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); @@ -104,6 +105,7 @@ public: 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; } } @@ -112,7 +114,7 @@ public: // we just want to make sure to hit the cache instead of doing it indirectly, // if possible... // - static inline ConstRules *get(const ConstPoolVal &V) { + static inline ConstRules *get(const Constant &V) { return (ConstRules*)V.getType()->getOrCreateAnnotation(AID); } private : @@ -123,29 +125,61 @@ private : }; -inline ConstPoolVal *operator!(const ConstPoolVal &V) { - return ConstRules::get(V)->op_not(&V); +// Standard binary operators... +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 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 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 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); + return ConstRules::get(V1)->div(&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); + return ConstRules::get(V1)->rem(&V1, &V2); } -inline ConstPoolVal *operator*(const ConstPoolVal &V1, const ConstPoolVal &V2) { +// Logical Operators... +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); + return ConstRules::get(V1)->op_and(&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)->op_or(&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)->op_xor(&V1, &V2); +} + +// Shift Instructions... +inline Constant *operator<<(const Constant &V1, const Constant &V2) { + assert(V1.getType()->isInteger() && V2.getType() == Type::UByteTy); + return ConstRules::get(V1)->shl(&V1, &V2); +} + +inline Constant *operator>>(const Constant &V1, const Constant &V2) { + assert(V1.getType()->isInteger() && 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 ConstRules::get(V1)->lessthan(&V1, &V2); } @@ -155,18 +189,18 @@ 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) { +inline ConstantBool *operator>=(const Constant &V1, + const Constant &V2) { return (V1 < V2)->inverted(); // !(V1 < V2) } -inline ConstPoolBool *operator<=(const ConstPoolVal &V1, - const ConstPoolVal &V2) { +inline ConstantBool *operator<=(const Constant &V1, + const Constant &V2) { return (V1 > V2)->inverted(); // !(V1 > V2) } @@ -175,30 +209,16 @@ inline ConstPoolBool *operator<=(const ConstPoolVal &V1, // 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; -} +// 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 *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, + const Constant *V2); +Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1, + const Constant *V2); -} // end namespace opt #endif