X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FConstantHandling.h;h=ef19cd257f8fdb360e188782bf0efbbed3e3f97e;hb=20a277e162f971ec1b9c6f2c90a214c177d54f99;hp=1479fe01ef889d6bfee42aa4b32c480874145227;hpb=66160427de7b88815f2f9847ec60c6ef85577b6b;p=oota-llvm.git diff --git a/include/llvm/ConstantHandling.h b/include/llvm/ConstantHandling.h index 1479fe01ef8..ef19cd257f8 100644 --- a/include/llvm/ConstantHandling.h +++ b/include/llvm/ConstantHandling.h @@ -1,4 +1,11 @@ -//===-- ConstantHandling.h - Stuff for manipulating constants ----*- C++ -*--=// +//===-- ConstantHandling.h - Stuff for manipulating constants ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file contains the declarations of some cool operators that allow you // to do natural things with constant pool values. @@ -33,8 +40,7 @@ #ifndef LLVM_CONSTANTHANDLING_H #define LLVM_CONSTANTHANDLING_H -#include "llvm/ConstantVals.h" -#include "llvm/Instruction.h" +#include "llvm/Constants.h" #include "llvm/Type.h" class PointerType; @@ -42,14 +48,12 @@ class PointerType; // Implement == and != directly... //===----------------------------------------------------------------------===// -inline ConstantBool *operator==(const Constant &V1, - const Constant &V2) { +inline ConstantBool *operator==(const Constant &V1, const Constant &V2) { assert(V1.getType() == V2.getType() && "Constant types must be identical!"); return ConstantBool::get(&V1 == &V2); } -inline ConstantBool *operator!=(const Constant &V1, - const Constant &V2) { +inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) { return ConstantBool::get(&V1 != &V2); } @@ -63,18 +67,17 @@ protected: public: static AnnotationID AID; // AnnotationID for this class - // Unary Operators... - 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 *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; @@ -91,8 +94,8 @@ public: 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; + virtual Constant *castToPointer(const Constant *V, + const PointerType *Ty) const = 0; inline Constant *castTo(const Constant *V, const Type *Ty) const { switch (Ty->getPrimitiveID()) { @@ -116,47 +119,83 @@ public: // we just want to make sure to hit the cache instead of doing it indirectly, // if possible... // - static inline ConstRules *get(const Constant &V) { - return (ConstRules*)V.getType()->getOrCreateAnnotation(AID); + static inline ConstRules *get(const Constant &V1, const Constant &V2) { + if (isa(V1) || isa(V2)) + return getConstantExprRules(); + return (ConstRules*)V1.getType()->getOrCreateAnnotation(AID); } -private : +private: + static ConstRules *getConstantExprRules(); static Annotation *find(AnnotationID AID, const Annotable *Ty, void *); ConstRules(const ConstRules &); // Do not implement ConstRules &operator=(const ConstRules &); // Do not implement }; - -inline Constant *operator!(const Constant &V) { - return ConstRules::get(V)->op_not(&V); +// Unary operators... +inline Constant *operator~(const Constant &V) { + assert(V.getType()->isIntegral() && "Cannot invert non-intergral constant!"); + return ConstRules::get(V, V)->op_xor(&V, + ConstantInt::getAllOnesValue(V.getType())); } - - +// 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); + return ConstRules::get(V1, V2)->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); + return ConstRules::get(V1, V2)->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); + return ConstRules::get(V1, V2)->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); + return ConstRules::get(V1, V2)->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, V2)->rem(&V1, &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, V2)->op_and(&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, V2)->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, V2)->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, V2)->shl(&V1, &V2); +} + +inline Constant *operator>>(const Constant &V1, const Constant &V2) { + assert(V1.getType()->isInteger() && V2.getType() == Type::UByteTy); + return ConstRules::get(V1, V2)->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); + return ConstRules::get(V1, V2)->lessthan(&V1, &V2); } @@ -171,12 +210,16 @@ inline ConstantBool *operator>(const Constant &V1, inline ConstantBool *operator>=(const Constant &V1, const Constant &V2) { - return (V1 < V2)->inverted(); // !(V1 < V2) + if (ConstantBool *V = (V1 < V2)) + return V->inverted(); // !(V1 < V2) + return 0; } inline ConstantBool *operator<=(const Constant &V1, const Constant &V2) { - return (V1 > V2)->inverted(); // !(V1 > V2) + if (ConstantBool *V = (V1 > V2)) + return V->inverted(); // !(V1 > V2) + return 0; } @@ -184,37 +227,17 @@ inline ConstantBool *operator<=(const Constant &V1, // 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 *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, + const Constant *V2); +Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1, + const Constant *V2); +Constant *ConstantFoldGetElementPtr(const Constant *C, + const std::vector &IdxList); #endif