[llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp

Reid Spencer reid at x10sys.com
Sun Dec 3 21:20:05 PST 2006



Changes in directory llvm/lib/VMCore:

Constants.cpp updated: 1.175 -> 1.176
---
Log message:

For PR950: http://llvm.org/PR950 : Fix constant expressions to properly support ICmp and FCmp type expressions.

---
Diffs of the changes:  (+127 -59)

 Constants.cpp |  186 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 127 insertions(+), 59 deletions(-)


Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.175 llvm/lib/VMCore/Constants.cpp:1.176
--- llvm/lib/VMCore/Constants.cpp:1.175	Sun Dec  3 20:43:42 2006
+++ llvm/lib/VMCore/Constants.cpp	Sun Dec  3 23:19:50 2006
@@ -442,6 +442,10 @@
   return Instruction::isCast(getOpcode());
 }
 
+bool ConstantExpr::isCompare() const {
+  return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
+}
+
 /// ConstantExpr::get* - Return some common constants without having to
 /// specify the full Instruction::OPCODE identifier.
 ///
@@ -510,23 +514,6 @@
 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;
@@ -1370,41 +1357,68 @@
 
 //---- ConstantExpr::get() implementations...
 //
-typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
+struct ExprMapKeyType {
+  explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
+      unsigned short pred = 0) : opcode(opc), operands(ops), predicate(pred) { }
+  unsigned opcode;
+  std::vector<Constant*> operands;
+  unsigned short predicate;
+  bool operator==(const ExprMapKeyType& that) const {
+    return this->opcode == that.opcode &&
+           this->predicate == that.predicate &&
+           this->operands == that.operands;
+  }
+  bool operator<(const ExprMapKeyType & that) const {
+    return this->opcode < that.opcode ||
+      (this->opcode == that.opcode && this->predicate < that.predicate) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands < that.operands);
+  }
+
+  bool operator!=(const ExprMapKeyType& that) const {
+    return !(*this == that);
+  }
+};
 
 namespace llvm {
   template<>
   struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
     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 &&
-           V.first < Instruction::BinaryOpsEnd) ||
-          V.first == Instruction::Shl           || 
-          V.first == Instruction::LShr          ||
-          V.first == Instruction::AShr)
-        return new BinaryConstantExpr(V.first, V.second[0], V.second[1]);
-      if (V.first == Instruction::Select)
-        return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
-      if (V.first == Instruction::ExtractElement)
-        return new ExtractElementConstantExpr(V.second[0], V.second[1]);
-      if (V.first == Instruction::InsertElement)
-        return new InsertElementConstantExpr(V.second[0], V.second[1],
-                                             V.second[2]);
-      if (V.first == Instruction::ShuffleVector)
-        return new ShuffleVectorConstantExpr(V.second[0], V.second[1],
-                                             V.second[2]);
-      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);
+      if (Instruction::isCast(V.opcode))
+        return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
+      if ((V.opcode >= Instruction::BinaryOpsBegin &&
+           V.opcode < Instruction::BinaryOpsEnd) ||
+          V.opcode == Instruction::Shl           || 
+          V.opcode == Instruction::LShr          ||
+          V.opcode == Instruction::AShr)
+        return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::Select)
+        return new SelectConstantExpr(V.operands[0], V.operands[1], 
+                                      V.operands[2]);
+      if (V.opcode == Instruction::ExtractElement)
+        return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::InsertElement)
+        return new InsertElementConstantExpr(V.operands[0], V.operands[1],
+                                             V.operands[2]);
+      if (V.opcode == Instruction::ShuffleVector)
+        return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
+                                             V.operands[2]);
+      if (V.opcode == Instruction::GetElementPtr) {
+        std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
+        return new GetElementPtrConstantExpr(V.operands[0], IdxList, Ty);
+      }
+
+      // The compare instructions are weird. We have to encode the predicate
+      // value and it is combined with the instruction opcode by multiplying
+      // the opcode by one hundred. We must decode this to get the predicate.
+      if (V.opcode == Instruction::ICmp)
+        return new CompareConstantExpr(Instruction::ICmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::FCmp) 
+        return new CompareConstantExpr(Instruction::FCmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      assert(0 && "Invalid ConstantExpr!");
     }
   };
 
@@ -1465,7 +1479,8 @@
   Operands.reserve(CE->getNumOperands());
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
-  return ExprMapKeyType(CE->getOpcode(), Operands);
+  return ExprMapKeyType(CE->getOpcode(), Operands, 
+      CE->isCompare() ? CE->getPredicate() : 0);
 }
 
 static ManagedStatic<ValueMap<ExprMapKeyType, Type,
@@ -1482,7 +1497,7 @@
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> argVec(1, C);
-  ExprMapKeyType Key = std::make_pair(opc, argVec);
+  ExprMapKeyType Key(opc, argVec);
   return ExprConstants->getOrCreate(Ty, Key);
 }
 
@@ -1627,10 +1642,15 @@
 }
 
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
-                              Constant *C1, Constant *C2) {
+                              Constant *C1, Constant *C2, unsigned short pred) {
   if (Opcode == Instruction::Shl || Opcode == Instruction::LShr ||
       Opcode == Instruction::AShr)
     return getShiftTy(ReqTy, Opcode, C1, C2);
+  if (Opcode == Instruction::ICmp)
+    return getICmp(pred, C1, C2);
+  if (Opcode == Instruction::FCmp)
+    return getFCmp(pred, C1, C2);
+
   // Check the operands for consistency first
   assert(Opcode >= Instruction::BinaryOpsBegin &&
          Opcode <  Instruction::BinaryOpsEnd   &&
@@ -1644,11 +1664,11 @@
       return FC;          // Fold a few common cases...
 
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+  ExprMapKeyType Key(Opcode, argVec, pred);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
-Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, unsigned short pred) {
 #ifndef NDEBUG
   switch (Opcode) {
   case Instruction::Add: 
@@ -1696,6 +1716,10 @@
   case Instruction::SetGE: case Instruction::SetEQ: case Instruction::SetNE:
     assert(C1->getType() == C2->getType() && "Op types should be identical!");
     break;
+  case Instruction::FCmp:
+  case Instruction::ICmp:
+    assert(C1->getType() == C2->getType() && "Op types should be identical!");
+    break;
   case Instruction::Shl:
   case Instruction::LShr:
   case Instruction::AShr:
@@ -1709,9 +1733,9 @@
 #endif
 
   if (Instruction::isComparison(Opcode))
-    return getTy(Type::BoolTy, Opcode, C1, C2);
+    return getTy(Type::BoolTy, Opcode, C1, C2, pred);
   else
-    return getTy(C1->getType(), Opcode, C1, C2);
+    return getTy(C1->getType(), Opcode, C1, C2, pred);
 }
 
 Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
@@ -1727,7 +1751,7 @@
   std::vector<Constant*> argVec(3, C);
   argVec[1] = V1;
   argVec[2] = V2;
-  ExprMapKeyType Key = std::make_pair(Instruction::Select, argVec);
+  ExprMapKeyType Key(Instruction::Select, argVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1747,7 +1771,7 @@
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+  ExprMapKeyType Key(Opcode, argVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1768,7 +1792,7 @@
   ArgVec.push_back(C);
   for (unsigned i = 0, e = IdxList.size(); i != e; ++i)
     ArgVec.push_back(cast<Constant>(IdxList[i]));
-  const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,ArgVec);
+  const ExprMapKeyType Key(Instruction::GetElementPtr,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1792,6 +1816,41 @@
   return getGetElementPtrTy(PointerType::get(Ty), C, IdxList);
 }
 
+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");
+
+  if (Constant *FC = ConstantFoldCompare(Instruction::ICmp, LHS, RHS, pred))
+    return FC;          // Fold a few common cases...
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Fake up an opcode value that encodes both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
+Constant *
+ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(LHS->getType() == RHS->getType());
+  assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
+
+  if (Constant *FC = ConstantFoldCompare(Instruction::FCmp, LHS, RHS, pred))
+    return FC;          // Fold a few common cases...
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Fake up an opcode value that encodes both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
 Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
                                             Constant *Idx) {
   if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
@@ -1799,7 +1858,7 @@
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Idx);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::ExtractElement,ArgVec);
+  const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1820,7 +1879,7 @@
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Elt);
   ArgVec.push_back(Idx);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec);
+  const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1844,7 +1903,7 @@
   std::vector<Constant*> ArgVec(1, V1);
   ArgVec.push_back(V2);
   ArgVec.push_back(Mask);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::ShuffleVector,ArgVec);
+  const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -2071,6 +2130,15 @@
     if (C2 == From) C2 = To;
     if (C3 == From) C3 = To;
     Replacement = ConstantExpr::getShuffleVector(C1, C2, C3);
+  } else if (isCompare()) {
+    Constant *C1 = getOperand(0);
+    Constant *C2 = getOperand(1);
+    if (C1 == From) C1 = To;
+    if (C2 == From) C2 = To;
+    if (getOpcode() == Instruction::ICmp)
+      Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2);
+    else
+      Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2);
   } else if (getNumOperands() == 2) {
     Constant *C1 = getOperand(0);
     Constant *C2 = getOperand(1);






More information about the llvm-commits mailing list