Constant folding shalt not be built on annotations
authorChris Lattner <sabre@nondot.org>
Mon, 17 Nov 2003 19:05:17 +0000 (19:05 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 17 Nov 2003 19:05:17 +0000 (19:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10052 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ConstantHandling.h
lib/VMCore/ConstantFold.cpp
lib/VMCore/ConstantFold.h
lib/VMCore/ConstantFolding.h

index b392ad1173779d0bfb64dae15eb22f75b7903420..d733ac8096252cda8b9f4e280462b5193f0d2802 100644 (file)
@@ -64,11 +64,8 @@ inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
 
-class ConstRules : public Annotation {
-protected:
-  inline ConstRules() : Annotation(AID) {}  // Can only be subclassed...
-public:
-  static AnnotationID AID;    // AnnotationID for this class
+struct ConstRules {
+  ConstRules() {}
 
   // Binary Operators...
   virtual Constant *add(const Constant *V1, const Constant *V2) const = 0;
@@ -119,19 +116,11 @@ public:
     }
   }
 
-  // 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...
+  // ConstRules::get - Return an instance of ConstRules for the specified
+  // constant operands.
   //
-  static inline ConstRules *get(const Constant &V1, const Constant &V2) {
-    if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2))
-      return getConstantExprRules();
-    return static_cast<ConstRules*>(V1.getType()->getOrCreateAnnotation(AID));
-  }
+  static ConstRules &get(const Constant &V1, const Constant &V2);
 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
 };
@@ -139,71 +128,71 @@ private:
 // Unary operators...
 inline Constant *operator~(const Constant &V) {
   assert(V.getType()->isIntegral() && "Cannot invert non-integral constant!");
-  return ConstRules::get(V, V)->op_xor(&V,
+  return ConstRules::get(V, V).op_xor(&V,
                                     ConstantInt::getAllOnesValue(V.getType()));
 }
 
 inline Constant *operator-(const Constant &V) {
-  return ConstRules::get(V, V)->sub(Constant::getNullValue(V.getType()), &V);
+  return ConstRules::get(V, V).sub(Constant::getNullValue(V.getType()), &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, V2)->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, V2)->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, V2)->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, V2)->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);
+  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);
+  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);
+  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);
+  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);
+  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);
+  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, V2)->lessthan(&V1, &V2);
+  return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }
 
 
index 7fb7a05e55d3df40ed8fbb8e5c817e5f1264e7e1..aca7df2589357b2699afc41d19375f4d185acb60 100644 (file)
 #include "llvm/InstrTypes.h"
 #include "llvm/DerivedTypes.h"
 #include <cmath>
-
-namespace llvm {
-
-AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
-                                                     &ConstRules::find));
+using namespace llvm;
 
 // 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 *llvm::ConstantFoldInstruction(Instruction *I) {
   if (PHINode *PN = dyn_cast<PHINode>(I)) {
     if (PN->getNumIncomingValues() == 0)
       return Constant::getNullValue(PN->getType());
@@ -85,7 +81,8 @@ static unsigned getSize(const Type *Ty) {
   return S ? S : 8;  // Treat pointers at 8 bytes
 }
 
-Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
+Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
+                                            const Type *DestTy) {
   if (V->getType() == DestTy) return (Constant*)V;
 
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
@@ -117,11 +114,12 @@ Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
         return ConstantExpr::getCast(CE->getOperand(0), DestTy);
     }
 
-  return ConstRules::get(*V, *V)->castTo(V, DestTy);
+  return ConstRules::get(*V, *V).castTo(V, DestTy);
 }
 
-Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
-                                        const Constant *V2) {
+Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
+                                              const Constant *V1,
+                                              const Constant *V2) {
   switch (Opcode) {
   case Instruction::Add:     return *V1 + *V2;
   case Instruction::Sub:     return *V1 - *V2;
@@ -142,8 +140,9 @@ Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
   return 0;
 }
 
-Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1, 
-                                       const Constant *V2) {
+Constant *llvm::ConstantFoldShiftInstruction(unsigned Opcode,
+                                             const Constant *V1, 
+                                             const Constant *V2) {
   switch (Opcode) {
   case Instruction::Shl:     return *V1 << *V2;
   case Instruction::Shr:     return *V1 >> *V2;
@@ -151,8 +150,8 @@ Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1,
   }
 }
 
-Constant *ConstantFoldGetElementPtr(const Constant *C,
-                                    const std::vector<Constant*> &IdxList) {
+Constant *llvm::ConstantFoldGetElementPtr(const Constant *C,
+                                        const std::vector<Constant*> &IdxList) {
   if (IdxList.size() == 0 ||
       (IdxList.size() == 1 && IdxList[0]->isNullValue()))
     return const_cast<Constant*>(C);
@@ -592,53 +591,41 @@ struct DirectFPRules
   }
 };
 
-//===----------------------------------------------------------------------===//
-//                            DirectRules Subclasses
-//===----------------------------------------------------------------------===//
-//
-// Given the DirectRules class we can now implement lots of types with little
-// code.  Thank goodness C++ compilers are great at stomping out layers of 
-// templates... can you imagine having to do this all by hand? (/me is lazy :)
-//
-
-// ConstRules::find - Return the constant rules that take care of the specified
-// type.
-//
-Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
-  assert(AID == ConstRules::AID && "Bad annotation for factory!");
-  const Type *Ty = cast<Type>((const Value*)TyA);
-  
-  switch (Ty->getPrimitiveID()) {
-  case Type::BoolTyID:    return new BoolRules();
-  case Type::PointerTyID: return new PointerRules();
-  case Type::SByteTyID:
-    return new DirectIntRules<ConstantSInt,   signed char , &Type::SByteTy>();
-  case Type::UByteTyID:
-    return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
-  case Type::ShortTyID:
-    return new DirectIntRules<ConstantSInt,   signed short, &Type::ShortTy>();
-  case Type::UShortTyID:
-    return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
-  case Type::IntTyID:
-    return new DirectIntRules<ConstantSInt,   signed int  , &Type::IntTy>();
-  case Type::UIntTyID:
-    return new DirectIntRules<ConstantUInt, unsigned int  , &Type::UIntTy>();
-  case Type::LongTyID:
-    return new DirectIntRules<ConstantSInt,  int64_t      , &Type::LongTy>();
-  case Type::ULongTyID:
-    return new DirectIntRules<ConstantUInt, uint64_t      , &Type::ULongTy>();
-  case Type::FloatTyID:
-    return new DirectFPRules<ConstantFP  , float         , &Type::FloatTy>();
-  case Type::DoubleTyID:
-    return new DirectFPRules<ConstantFP  , double        , &Type::DoubleTy>();
-  default:
-    return new EmptyRules();
+ConstRules &ConstRules::get(const Constant &V1, const Constant &V2) {
+  static EmptyRules   EmptyR;
+  static BoolRules    BoolR;
+  static PointerRules PointerR;
+  static DirectIntRules<ConstantSInt,   signed char , &Type::SByteTy>  SByteR;
+  static DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>  UByteR;
+  static DirectIntRules<ConstantSInt,   signed short, &Type::ShortTy>  ShortR;
+  static DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy> UShortR;
+  static DirectIntRules<ConstantSInt,   signed int  , &Type::IntTy>    IntR;
+  static DirectIntRules<ConstantUInt, unsigned int  , &Type::UIntTy>   UIntR;
+  static DirectIntRules<ConstantSInt,  int64_t      , &Type::LongTy>   LongR;
+  static DirectIntRules<ConstantUInt, uint64_t      , &Type::ULongTy>  ULongR;
+  static DirectFPRules <ConstantFP  , float         , &Type::FloatTy>  FloatR;
+  static DirectFPRules <ConstantFP  , double        , &Type::DoubleTy> DoubleR;
+
+  if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2))
+    return EmptyR;
+
+  // FIXME: This assert doesn't work because shifts pass both operands in to
+  // check for constant exprs.  :(
+  //assert(V1.getType() == V2.getType() &&"Nonequal types to constant folder?");
+
+  switch (V1.getType()->getPrimitiveID()) {
+  default: assert(0 && "Unknown value type for constant folding!");
+  case Type::BoolTyID:    return BoolR;
+  case Type::PointerTyID: return PointerR;
+  case Type::SByteTyID:   return SByteR;
+  case Type::UByteTyID:   return UByteR;
+  case Type::ShortTyID:   return ShortR;
+  case Type::UShortTyID:  return UShortR;
+  case Type::IntTyID:     return IntR;
+  case Type::UIntTyID:    return UIntR;
+  case Type::LongTyID:    return LongR;
+  case Type::ULongTyID:   return ULongR;
+  case Type::FloatTyID:   return FloatR;
+  case Type::DoubleTyID:  return DoubleR;
   }
 }
-
-ConstRules *ConstRules::getConstantExprRules() {
-  static EmptyRules CERules;
-  return &CERules;
-}
-
-} // End llvm namespace
index b392ad1173779d0bfb64dae15eb22f75b7903420..d733ac8096252cda8b9f4e280462b5193f0d2802 100644 (file)
@@ -64,11 +64,8 @@ inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
 
-class ConstRules : public Annotation {
-protected:
-  inline ConstRules() : Annotation(AID) {}  // Can only be subclassed...
-public:
-  static AnnotationID AID;    // AnnotationID for this class
+struct ConstRules {
+  ConstRules() {}
 
   // Binary Operators...
   virtual Constant *add(const Constant *V1, const Constant *V2) const = 0;
@@ -119,19 +116,11 @@ public:
     }
   }
 
-  // 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...
+  // ConstRules::get - Return an instance of ConstRules for the specified
+  // constant operands.
   //
-  static inline ConstRules *get(const Constant &V1, const Constant &V2) {
-    if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2))
-      return getConstantExprRules();
-    return static_cast<ConstRules*>(V1.getType()->getOrCreateAnnotation(AID));
-  }
+  static ConstRules &get(const Constant &V1, const Constant &V2);
 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
 };
@@ -139,71 +128,71 @@ private:
 // Unary operators...
 inline Constant *operator~(const Constant &V) {
   assert(V.getType()->isIntegral() && "Cannot invert non-integral constant!");
-  return ConstRules::get(V, V)->op_xor(&V,
+  return ConstRules::get(V, V).op_xor(&V,
                                     ConstantInt::getAllOnesValue(V.getType()));
 }
 
 inline Constant *operator-(const Constant &V) {
-  return ConstRules::get(V, V)->sub(Constant::getNullValue(V.getType()), &V);
+  return ConstRules::get(V, V).sub(Constant::getNullValue(V.getType()), &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, V2)->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, V2)->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, V2)->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, V2)->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);
+  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);
+  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);
+  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);
+  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);
+  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);
+  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, V2)->lessthan(&V1, &V2);
+  return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }
 
 
index b392ad1173779d0bfb64dae15eb22f75b7903420..d733ac8096252cda8b9f4e280462b5193f0d2802 100644 (file)
@@ -64,11 +64,8 @@ inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
 
-class ConstRules : public Annotation {
-protected:
-  inline ConstRules() : Annotation(AID) {}  // Can only be subclassed...
-public:
-  static AnnotationID AID;    // AnnotationID for this class
+struct ConstRules {
+  ConstRules() {}
 
   // Binary Operators...
   virtual Constant *add(const Constant *V1, const Constant *V2) const = 0;
@@ -119,19 +116,11 @@ public:
     }
   }
 
-  // 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...
+  // ConstRules::get - Return an instance of ConstRules for the specified
+  // constant operands.
   //
-  static inline ConstRules *get(const Constant &V1, const Constant &V2) {
-    if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2))
-      return getConstantExprRules();
-    return static_cast<ConstRules*>(V1.getType()->getOrCreateAnnotation(AID));
-  }
+  static ConstRules &get(const Constant &V1, const Constant &V2);
 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
 };
@@ -139,71 +128,71 @@ private:
 // Unary operators...
 inline Constant *operator~(const Constant &V) {
   assert(V.getType()->isIntegral() && "Cannot invert non-integral constant!");
-  return ConstRules::get(V, V)->op_xor(&V,
+  return ConstRules::get(V, V).op_xor(&V,
                                     ConstantInt::getAllOnesValue(V.getType()));
 }
 
 inline Constant *operator-(const Constant &V) {
-  return ConstRules::get(V, V)->sub(Constant::getNullValue(V.getType()), &V);
+  return ConstRules::get(V, V).sub(Constant::getNullValue(V.getType()), &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, V2)->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, V2)->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, V2)->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, V2)->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);
+  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);
+  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);
+  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);
+  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);
+  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);
+  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, V2)->lessthan(&V1, &V2);
+  return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }