Implement creation of ICmp and FCmp constant expressions.
authorReid Spencer <rspencer@reidspencer.com>
Sun, 3 Dec 2006 05:48:19 +0000 (05:48 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Sun, 3 Dec 2006 05:48:19 +0000 (05:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32147 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Constants.h
lib/VMCore/Constants.cpp

index a0ad89fac4f9ae841a0847f741a72d085fc72fa5..06aaca65d5de785f5113ec38b7aaa96dce8bd564 100644 (file)
@@ -547,7 +547,6 @@ public:
   /// @brief Return true if this is a convert constant expression
   bool isCast() const;
 
-
   /// Select constant expr
   ///
   static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
@@ -591,6 +590,8 @@ public:
   static Constant *getSetGT(Constant *C1, Constant *C2);
   static Constant *getSetLE(Constant *C1, Constant *C2);
   static Constant *getSetGE(Constant *C1, Constant *C2);
+  static Constant* getICmp(unsigned short pred, Constant* LHS, Constant* RHS);
+  static Constant* getFCmp(unsigned short pred, Constant* LHS, Constant* RHS);
   static Constant *getShl(Constant *C1, Constant *C2);
   static Constant *getLShr(Constant *C1, Constant *C2);
   static Constant *getAShr(Constant *C1, Constant *C2);
@@ -606,7 +607,7 @@ public:
   static Constant *getExtractElement(Constant *Vec, Constant *Idx);
   static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
   static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
-  
+
   /// isNullValue - Return true if this is the value that would be returned by
   /// getNullValue.
   virtual bool isNullValue() const { return false; }
@@ -614,6 +615,10 @@ public:
   /// getOpcode - Return the opcode at the root of this constant expression
   unsigned getOpcode() const { return SubclassData; }
 
+  /// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is
+  /// not an ICMP or FCMP constant expression.
+  unsigned getPredicate() const;
+
   /// getOpcodeName - Return a string representation for an opcode.
   const char *getOpcodeName() const;
 
index c36fea94869f38f46c40b9494a67aa979c5c9ebc..71615b2c4a98ec4b9af7be02118149be0d6782fe 100644 (file)
@@ -312,26 +312,27 @@ ConstantPacked::~ConstantPacked() {
   delete [] OperandList;
 }
 
+static bool isSetCC(unsigned Opcode) {
+  return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
+         Opcode == Instruction::SetLT || Opcode == Instruction::SetGT ||
+         Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
+}
+
+// We declare several classes private to this file, so use an anonymous
+// namespace
+namespace {
+
 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement unary constant exprs.
-namespace {
 class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr {
   Use Op;
 public:
   UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
     : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {}
 };
-}
-
-static bool isSetCC(unsigned Opcode) {
-  return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
-         Opcode == Instruction::SetLT || Opcode == Instruction::SetGT ||
-         Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
-}
 
 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement binary constant exprs.
-namespace {
 class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr {
   Use Ops[2];
 public:
@@ -342,11 +343,9 @@ public:
     Ops[1].init(C2, this);
   }
 };
-}
 
 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement select constant exprs.
-namespace {
 class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -357,12 +356,10 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// ExtractElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// extractelement constant exprs.
-namespace {
 class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr {
   Use Ops[2];
 public:
@@ -373,12 +370,10 @@ public:
     Ops[1].init(C2, this);
   }
 };
-}
 
 /// InsertElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// insertelement constant exprs.
-namespace {
 class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -390,12 +385,10 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// ShuffleVectorConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// shufflevector constant exprs.
-namespace {
 class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -407,11 +400,9 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
 /// used behind the scenes to implement getelementpr constant exprs.
-namespace {
 struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
   GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
                             const Type *DestTy)
@@ -425,7 +416,23 @@ struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
     delete [] OperandList;
   }
 };
-}
+
+// CompareConstantExpr - This class is private to Constants.cpp, and is used
+// behind the scenes to implement ICmp and FCmp constant expressions. This is
+// needed in order to store the predicate value for these instructions.
+struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
+  unsigned short predicate;
+  Use Ops[2];
+  CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, 
+                      Constant* LHS, Constant* RHS)
+    : ConstantExpr(Type::BoolTy, Instruction::OtherOps(opc), Ops, 2),
+      predicate(pred) {
+    OperandList[0].init(LHS, this);
+    OperandList[1].init(RHS, this);
+  }
+};
+
+} // end anonymous namespace
 
 
 // Utility function for determining if a ConstantExpr is a CastOp or not. This
@@ -503,6 +510,27 @@ Constant *ConstantExpr::getSetLE(Constant *C1, Constant *C2) {
 Constant *ConstantExpr::getSetGE(Constant *C1, Constant *C2) {
   return get(Instruction::SetGE, C1, C2);
 }
+Constant *
+ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(LHS->getType() == RHS->getType());
+  assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && 
+         pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
+  CompareConstantExpr *Result = 
+    new CompareConstantExpr(Instruction::ICmp, pred, LHS, RHS);
+  return Result;
+}
+Constant *
+ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(LHS->getType() == RHS->getType());
+  assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid ICmp Predicate");
+  CompareConstantExpr *Result = 
+    new CompareConstantExpr(Instruction::FCmp, pred, LHS, RHS);
+  return Result;
+}
+unsigned ConstantExpr::getPredicate() const {
+  assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
+  return dynamic_cast<const CompareConstantExpr*>(this)->predicate;
+}
 Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
   return get(Instruction::Shl, C1, C2);
 }
@@ -1340,8 +1368,6 @@ void UndefValue::destroyConstant() {
 }
 
 
-
-
 //---- ConstantExpr::get() implementations...
 //
 typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
@@ -1349,7 +1375,8 @@ typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
 namespace llvm {
   template<>
   struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
-    static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V) {
+    static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V,
+        unsigned short pred = 0) {
       if (Instruction::isCast(V.first))
         return new UnaryConstantExpr(V.first, V.second[0], Ty);
       if ((V.first >= Instruction::BinaryOpsBegin &&
@@ -1368,9 +1395,14 @@ namespace llvm {
       if (V.first == Instruction::ShuffleVector)
         return new ShuffleVectorConstantExpr(V.second[0], V.second[1],
                                              V.second[2]);
-      
-      assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
+      if (V.first == Instruction::ICmp)
+        return new CompareConstantExpr(Instruction::ICmp, pred, 
+                                       V.second[0], V.second[1]);
+      if (V.first == Instruction::FCmp) 
+        return new CompareConstantExpr(Instruction::FCmp, pred, 
+                                       V.second[0], V.second[1]);
 
+      assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
       std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
       return new GetElementPtrConstantExpr(V.second[0], IdxList, Ty);
     }
@@ -1822,7 +1854,6 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
   return getShuffleVectorTy(V1->getType(), V1, V2, Mask);
 }
 
-
 // destroyConstant - Remove the constant from the constant table...
 //
 void ConstantExpr::destroyConstant() {