Fix a typo in a comment.
[oota-llvm.git] / lib / VMCore / Constants.cpp
index b327a6a855ad6e72ce7be2a9bb55ba8884adc99c..55b87009cba348c2f1a2518c1188cfb6fcbd23bc 100644 (file)
@@ -155,6 +155,36 @@ ConstantVector *ConstantVector::getAllOnesValue(const VectorType *Ty) {
 }
 
 
+/// getVectorElements - This method, which is only valid on constant of vector
+/// type, returns the elements of the vector in the specified smallvector.
+/// This handles breaking down a vector undef into undef elements, etc.  For
+/// constant exprs and other cases we can't handle, we return an empty vector.
+void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
+  assert(isa<VectorType>(getType()) && "Not a vector constant!");
+  
+  if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) {
+    for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i)
+      Elts.push_back(CV->getOperand(i));
+    return;
+  }
+  
+  const VectorType *VT = cast<VectorType>(getType());
+  if (isa<ConstantAggregateZero>(this)) {
+    Elts.assign(VT->getNumElements(), 
+                Constant::getNullValue(VT->getElementType()));
+    return;
+  }
+  
+  if (isa<UndefValue>(this)) {
+    Elts.assign(VT->getNumElements(), UndefValue::get(VT->getElementType()));
+    return;
+  }
+  
+  // Unknown type, must be constant expr etc.
+}
+
+
+
 //===----------------------------------------------------------------------===//
 //                                ConstantInt
 //===----------------------------------------------------------------------===//
@@ -343,7 +373,8 @@ ConstantFP *ConstantFP::get(const APFloat &V) {
 /// 2.0/1.0 etc, that are known-valid both as double and as the target format.
 ConstantFP *ConstantFP::get(const Type *Ty, double V) {
   APFloat FV(V);
-  FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven);
+  bool ignored;
+  FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven, &ignored);
   return get(FV);
 }
 
@@ -367,7 +398,7 @@ ConstantArray::ConstantArray(const ArrayType *T,
             (T->isAbstract() &&
              C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
            "Initializer for array element doesn't match array element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -389,7 +420,7 @@ ConstantStruct::ConstantStruct(const StructType *T,
              T->getElementType(I-V.begin())->getTypeID() == 
                    C->getType()->getTypeID())) &&
            "Initializer for struct element doesn't match struct element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -407,7 +438,7 @@ ConstantVector::ConstantVector(const VectorType *T,
             (T->isAbstract() &&
              C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
            "Initializer for vector element doesn't match vector element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -445,8 +476,8 @@ public:
   }
   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -463,9 +494,9 @@ public:
   }
   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -484,8 +515,8 @@ public:
   ExtractElementConstantExpr(Constant *C1, Constant *C2)
     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 
                    Instruction::ExtractElement, &Op<0>(), 2) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -504,9 +535,9 @@ public:
   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C1->getType(), Instruction::InsertElement, 
                    &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -525,23 +556,77 @@ public:
   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
   : ConstantExpr(C1->getType(), Instruction::ShuffleVector, 
                  &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
+  }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+};
+
+/// ExtractValueConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// extractvalue constant exprs.
+class VISIBILITY_HIDDEN ExtractValueConstantExpr : public ConstantExpr {
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
   }
+  ExtractValueConstantExpr(Constant *Agg,
+                           const SmallVector<unsigned, 4> &IdxList,
+                           const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
+      Indices(IdxList) {
+    Op<0>() = Agg;
+  }
+
+  /// Indices - These identify which value to extract.
+  const SmallVector<unsigned, 4> Indices;
+
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
+/// InsertValueConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// insertvalue constant exprs.
+class VISIBILITY_HIDDEN InsertValueConstantExpr : public ConstantExpr {
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+  InsertValueConstantExpr(Constant *Agg, Constant *Val,
+                          const SmallVector<unsigned, 4> &IdxList,
+                          const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
+      Indices(IdxList) {
+    Op<0>() = Agg;
+    Op<1>() = Val;
+  }
+
+  /// Indices - These identify the position for the insertion.
+  const SmallVector<unsigned, 4> Indices;
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+};
+
+
 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
 /// used behind the scenes to implement getelementpr constant exprs.
 class VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
   GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
                             const Type *DestTy);
 public:
-  static GetElementPtrConstantExpr *Create(Constant *C, const std::vector<Constant*> &IdxList,
+  static GetElementPtrConstantExpr *Create(Constant *C,
+                                           const std::vector<Constant*>&IdxList,
                                            const Type *DestTy) {
-    return new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
+    return new(IdxList.size() + 1)
+      GetElementPtrConstantExpr(C, IdxList, DestTy);
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -560,8 +645,8 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
   CompareConstantExpr(const Type *ty, Instruction::OtherOps opc,
                       unsigned short pred,  Constant* LHS, Constant* RHS)
     : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
-    Op<0>().init(LHS, this);
-    Op<1>().init(RHS, this);
+    Op<0>() = LHS;
+    Op<1>() = RHS;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -599,6 +684,15 @@ struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> {
 };
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
 
+template <>
+struct OperandTraits<ExtractValueConstantExpr> : FixedNumOperandTraits<1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
+
+template <>
+struct OperandTraits<InsertValueConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
 
 template <>
 struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> {
@@ -612,9 +706,9 @@ GetElementPtrConstantExpr::GetElementPtrConstantExpr
                    OperandTraits<GetElementPtrConstantExpr>::op_end(this)
                    - (IdxList.size()+1),
                    IdxList.size()+1) {
-  OperandList[0].init(C, this);
+  OperandList[0] = C;
   for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
-    OperandList[i+1].init(IdxList[i], this);
+    OperandList[i+1] = IdxList[i];
 }
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
@@ -637,7 +731,21 @@ bool ConstantExpr::isCast() const {
 }
 
 bool ConstantExpr::isCompare() const {
-  return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
+  return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp ||
+         getOpcode() == Instruction::VICmp || getOpcode() == Instruction::VFCmp;
+}
+
+bool ConstantExpr::hasIndices() const {
+  return getOpcode() == Instruction::ExtractValue ||
+         getOpcode() == Instruction::InsertValue;
+}
+
+const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const {
+  if (const ExtractValueConstantExpr *EVCE =
+        dyn_cast<ExtractValueConstantExpr>(this))
+    return EVCE->Indices;
+
+  return cast<InsertValueConstantExpr>(this)->Indices;
 }
 
 /// ConstantExpr::get* - Return some common constants without having to
@@ -649,9 +757,11 @@ Constant *ConstantExpr::getNeg(Constant *C) {
              C);
 }
 Constant *ConstantExpr::getNot(Constant *C) {
-  assert(isa<IntegerType>(C->getType()) && "Cannot NOT a nonintegral value!");
+  assert((isa<IntegerType>(C->getType()) ||
+            cast<VectorType>(C->getType())->getElementType()->isInteger()) &&
+          "Cannot NOT a nonintegral value!");
   return get(Instruction::Xor, C,
-             ConstantInt::getAllOnesValue(C->getType()));
+             Constant::getAllOnesValue(C->getType()));
 }
 Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) {
   return get(Instruction::Add, C1, C2);
@@ -752,9 +862,9 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
     return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
   case Instruction::GetElementPtr: {
     SmallVector<Constant*, 8> Ops;
-    Ops.resize(getNumOperands());
+    Ops.resize(getNumOperands()-1);
     for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
-      Ops[i] = getOperand(i);
+      Ops[i-1] = getOperand(i);
     if (OpNo == 0)
       return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
     Ops[OpNo-1] = Op;
@@ -772,10 +882,10 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
 /// operands replaced with the specified values.  The specified operands must
 /// match count and type with the existing ones.
 Constant *ConstantExpr::
-getWithOperands(const std::vector<Constant*> &Ops) const {
-  assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
+getWithOperands(Constant* const *Ops, unsigned NumOps) const {
+  assert(NumOps == getNumOperands() && "Operand count mismatch!");
   bool AnyChange = false;
-  for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+  for (unsigned i = 0; i != NumOps; ++i) {
     assert(Ops[i]->getType() == getOperand(i)->getType() &&
            "Operand type mismatch!");
     AnyChange |= Ops[i] != getOperand(i);
@@ -806,9 +916,11 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
   case Instruction::ShuffleVector:
     return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
   case Instruction::GetElementPtr:
-    return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1);
+    return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
   case Instruction::ICmp:
   case Instruction::FCmp:
+  case Instruction::VICmp:
+  case Instruction::VFCmp:
     return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
   default:
     assert(getNumOperands() == 2 && "Must be binary operator?");
@@ -844,20 +956,25 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
 bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
   // convert modifies in place, so make a copy.
   APFloat Val2 = APFloat(Val);
+  bool losesInfo;
   switch (Ty->getTypeID()) {
   default:
     return false;         // These can't be represented as floating point!
 
   // FIXME rounding mode needs to be more flexible
-  case Type::FloatTyID:
-    return &Val2.getSemantics() == &APFloat::IEEEsingle ||
-           Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven) == 
-              APFloat::opOK;
-  case Type::DoubleTyID:
-    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
-           &Val2.getSemantics() == &APFloat::IEEEdouble ||
-           Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) == 
-             APFloat::opOK;
+  case Type::FloatTyID: {
+    if (&Val2.getSemantics() == &APFloat::IEEEsingle)
+      return true;
+    Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
+    return !losesInfo;
+  }
+  case Type::DoubleTyID: {
+    if (&Val2.getSemantics() == &APFloat::IEEEsingle ||
+        &Val2.getSemantics() == &APFloat::IEEEdouble)
+      return true;
+    Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
+    return !losesInfo;
+  }
   case Type::X86_FP80TyID:
     return &Val2.getSemantics() == &APFloat::IEEEsingle || 
            &Val2.getSemantics() == &APFloat::IEEEdouble ||
@@ -961,7 +1078,8 @@ private:
       }
       
       typename MapTy::iterator I =
-        Map.find(MapKey((TypeClass*)CP->getRawType(), getValType(CP)));
+        Map.find(MapKey(static_cast<const TypeClass*>(CP->getRawType()),
+                        getValType(CP)));
       if (I == Map.end() || I->second != CP) {
         // FIXME: This should not use a linear scan.  If this gets to be a
         // performance problem, someone should look at this.
@@ -976,17 +1094,16 @@ public:
     /// necessary.
     ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
       MapKey Lookup(Ty, V);
-      typename MapTy::iterator I = Map.lower_bound(Lookup);
+      typename MapTy::iterator I = Map.find(Lookup);
       // Is it in the map?      
-      if (I != Map.end() && I->first == Lookup)
+      if (I != Map.end())
         return static_cast<ConstantClass *>(I->second);  
 
       // If no preexisting value, create one now...
       ConstantClass *Result =
         ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
 
-      /// FIXME: why does this assert fail when loading 176.gcc?
-      //assert(Result->getType() == Ty && "Type specified is not correct!");
+      assert(Result->getType() == Ty && "Type specified is not correct!");
       I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));
 
       if (HasLargeKey)  // Remember the reverse mapping if needed.
@@ -995,10 +1112,9 @@ public:
       // If the type of the constant is abstract, make sure that an entry exists
       // for it in the AbstractTypeMap.
       if (Ty->isAbstract()) {
-        typename AbstractTypeMapTy::iterator TI =
-          AbstractTypeMap.lower_bound(Ty);
+        typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(Ty);
 
-        if (TI == AbstractTypeMap.end() || TI->first != Ty) {
+        if (TI == AbstractTypeMap.end()) {
           // Add ourselves to the ATU list of the type.
           cast<DerivedType>(Ty)->addAbstractTypeUser(this);
 
@@ -1279,8 +1395,9 @@ bool ConstantArray::isCString() const {
 std::string ConstantArray::getAsString() const {
   assert(isString() && "Not a string!");
   std::string Result;
+  Result.reserve(getNumOperands());
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
-    Result += (char)cast<ConstantInt>(getOperand(i))->getZExtValue();
+    Result.push_back((char)cast<ConstantInt>(getOperand(i))->getZExtValue());
   return Result;
 }
 
@@ -1373,16 +1490,26 @@ static ManagedStatic<ValueMap<std::vector<Constant*>, VectorType,
 
 Constant *ConstantVector::get(const VectorType *Ty,
                               const std::vector<Constant*> &V) {
-  // If this is an all-zero vector, return a ConstantAggregateZero object
-  if (!V.empty()) {
-    Constant *C = V[0];
-    if (!C->isNullValue())
-      return VectorConstants->getOrCreate(Ty, V);
+  assert(!V.empty() && "Vectors can't be empty");
+  // If this is an all-undef or alll-zero vector, return a
+  // ConstantAggregateZero or UndefValue.
+  Constant *C = V[0];
+  bool isZero = C->isNullValue();
+  bool isUndef = isa<UndefValue>(C);
+
+  if (isZero || isUndef) {
     for (unsigned i = 1, e = V.size(); i != e; ++i)
-      if (V[i] != C)
-        return VectorConstants->getOrCreate(Ty, V);
+      if (V[i] != C) {
+        isZero = isUndef = false;
+        break;
+      }
   }
-  return ConstantAggregateZero::get(Ty);
+  
+  if (isZero)
+    return ConstantAggregateZero::get(Ty);
+  if (isUndef)
+    return UndefValue::get(Ty);
+  return VectorConstants->getOrCreate(Ty, V);
 }
 
 Constant *ConstantVector::get(const std::vector<Constant*> &V) {
@@ -1517,21 +1644,30 @@ void UndefValue::destroyConstant() {
 namespace {
 
 struct ExprMapKeyType {
-  explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
-      unsigned short pred = 0) : opcode(opc), predicate(pred), operands(ops) { }
+  typedef SmallVector<unsigned, 4> IndexList;
+
+  ExprMapKeyType(unsigned opc,
+      const std::vector<Constant*> &ops,
+      unsigned short pred = 0,
+      const IndexList &inds = IndexList())
+        : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
   uint16_t opcode;
   uint16_t predicate;
   std::vector<Constant*> operands;
+  IndexList indices;
   bool operator==(const ExprMapKeyType& that) const {
     return this->opcode == that.opcode &&
            this->predicate == that.predicate &&
-           this->operands == that.operands;
+           this->operands == that.operands &&
+           this->indices == that.indices;
   }
   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);
+       this->operands < that.operands) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands == that.operands && this->indices < that.indices);
   }
 
   bool operator!=(const ExprMapKeyType& that) const {
@@ -1562,6 +1698,11 @@ namespace llvm {
       if (V.opcode == Instruction::ShuffleVector)
         return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
                                              V.operands[2]);
+      if (V.opcode == Instruction::InsertValue)
+        return new InsertValueConstantExpr(V.operands[0], V.operands[1],
+                                           V.indices, Ty);
+      if (V.opcode == Instruction::ExtractValue)
+        return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
       if (V.opcode == Instruction::GetElementPtr) {
         std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
         return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
@@ -1640,7 +1781,9 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
   return ExprMapKeyType(CE->getOpcode(), Operands, 
-      CE->isCompare() ? CE->getPredicate() : 0);
+      CE->isCompare() ? CE->getPredicate() : 0,
+      CE->hasIndices() ?
+        CE->getIndices() : SmallVector<unsigned, 4>());
 }
 
 static ManagedStatic<ValueMap<ExprMapKeyType, Type,
@@ -1780,8 +1923,10 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
+#ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
          "This is an illegal uint to floating point cast!");
@@ -1789,8 +1934,10 @@ Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
+#ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
          "This is an illegal sint to floating point cast!");
@@ -1798,8 +1945,10 @@ Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
+#ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
          "This is an illegal floating point to uint cast!");
@@ -1807,8 +1956,10 @@ Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
+#ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
          "This is an illegal floating point to sint cast!");
@@ -1830,6 +1981,7 @@ Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
 Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
   // BitCast implies a no-op cast of type only. No bits change.  However, you 
   // can't cast pointers to anything but pointers.
+#ifndef NDEBUG
   const Type *SrcTy = C->getType();
   assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) &&
          "BitCast cannot cast pointer to non-pointer and vice versa");
@@ -1839,6 +1991,7 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
   // destination bit widths are identical.
   unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
   unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+#endif
   assert(SrcBitSize == DstBitSize && "BitCast requies types of same width");
   return getFoldedCast(Instruction::BitCast, C, DstTy);
 }
@@ -1871,20 +2024,23 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
 
 Constant *ConstantExpr::getCompareTy(unsigned short predicate,
                                      Constant *C1, Constant *C2) {
+  bool isVectorType = C1->getType()->getTypeID() == Type::VectorTyID;
   switch (predicate) {
     default: assert(0 && "Invalid CmpInst predicate");
-    case FCmpInst::FCMP_FALSE: case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_OGT:
-    case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OLE:
-    case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_ORD: case FCmpInst::FCMP_UNO:
-    case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UGT: case FCmpInst::FCMP_UGE:
-    case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_ULE: case FCmpInst::FCMP_UNE:
-    case FCmpInst::FCMP_TRUE:
-      return getFCmp(predicate, C1, C2);
-    case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT:
-    case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE:
-    case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: case ICmpInst::ICMP_SLT:
-    case ICmpInst::ICMP_SLE:
-      return getICmp(predicate, C1, C2);
+    case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT:
+    case CmpInst::FCMP_OGE:   case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE:
+    case CmpInst::FCMP_ONE:   case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO:
+    case CmpInst::FCMP_UEQ:   case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE:
+    case CmpInst::FCMP_ULT:   case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE:
+    case CmpInst::FCMP_TRUE:
+      return isVectorType ? getVFCmp(predicate, C1, C2) 
+                          : getFCmp(predicate, C1, C2);
+    case CmpInst::ICMP_EQ:  case CmpInst::ICMP_NE:  case CmpInst::ICMP_UGT:
+    case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE:
+    case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT:
+    case CmpInst::ICMP_SLE:
+      return isVectorType ? getVICmp(predicate, C1, C2)
+                          : getICmp(predicate, C1, C2);
   }
 }
 
@@ -1973,7 +2129,9 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
                                            Value* const *Idxs,
                                            unsigned NumIdx) {
-  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true) &&
+  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
+                                           Idxs+NumIdx) ==
+         cast<PointerType>(ReqTy)->getElementType() &&
          "GEP indices invalid!");
 
   if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx))
@@ -1995,7 +2153,7 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                          unsigned NumIdx) {
   // Get the result type of the getelementptr!
   const Type *Ty = 
-    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
+    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
   assert(Ty && "GEP indices invalid!");
   unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
   return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
@@ -2044,9 +2202,8 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
 
 Constant *
 ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
-  assert(isa<VectorType>(LHS->getType()) &&
+  assert(isa<VectorType>(LHS->getType()) && LHS->getType() == RHS->getType() &&
          "Tried to create vicmp operation on non-vector type!");
-  assert(LHS->getType() == RHS->getType());
   assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && 
          pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate");
 
@@ -2054,20 +2211,30 @@ ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
   const Type *EltTy = VTy->getElementType();
   unsigned NumElts = VTy->getNumElements();
 
-  SmallVector<Constant *, 8> Elts;
-  for (unsigned i = 0; i != NumElts; ++i) {
-    Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
-                                                        RHS->getOperand(i));
-    if (FC) {
-      uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
-      if (Val != 0ULL)
-        Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
-      else
-        Elts.push_back(ConstantInt::get(EltTy, 0ULL));
+  // See if we can fold the element-wise comparison of the LHS and RHS.
+  SmallVector<Constant *, 16> LHSElts, RHSElts;
+  LHS->getVectorElements(LHSElts);
+  RHS->getVectorElements(RHSElts);
+                    
+  if (!LHSElts.empty() && !RHSElts.empty()) {
+    SmallVector<Constant *, 16> Elts;
+    for (unsigned i = 0; i != NumElts; ++i) {
+      Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i],
+                                                    RHSElts[i]);
+      if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) {
+        if (FCI->getZExtValue())
+          Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
+        else
+          Elts.push_back(ConstantInt::get(EltTy, 0ULL));
+      } else if (FC && isa<UndefValue>(FC)) {
+        Elts.push_back(UndefValue::get(EltTy));
+      } else {
+        break;
+      }
     }
+    if (Elts.size() == NumElts)
+      return ConstantVector::get(&Elts[0], Elts.size());
   }
-  if (Elts.size() == NumElts)
-    return ConstantVector::get(&Elts[0], Elts.size());
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec;
@@ -2091,20 +2258,30 @@ ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
   const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits());
   const Type *ResultTy = VectorType::get(REltTy, NumElts);
 
-  SmallVector<Constant *, 8> Elts;
-  for (unsigned i = 0; i != NumElts; ++i) {
-    Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
-                                                        RHS->getOperand(i));
-    if (FC) {
-      uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
-      if (Val != 0ULL)
-        Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
-      else
-        Elts.push_back(ConstantInt::get(REltTy, 0ULL));
+  // See if we can fold the element-wise comparison of the LHS and RHS.
+  SmallVector<Constant *, 16> LHSElts, RHSElts;
+  LHS->getVectorElements(LHSElts);
+  RHS->getVectorElements(RHSElts);
+  
+  if (!LHSElts.empty() && !RHSElts.empty()) {
+    SmallVector<Constant *, 16> Elts;
+    for (unsigned i = 0; i != NumElts; ++i) {
+      Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i],
+                                                    RHSElts[i]);
+      if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) {
+        if (FCI->getZExtValue())
+          Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
+        else
+          Elts.push_back(ConstantInt::get(REltTy, 0ULL));
+      } else if (FC && isa<UndefValue>(FC)) {
+        Elts.push_back(UndefValue::get(REltTy));
+      } else {
+        break;
+      }
     }
+    if (Elts.size() == NumElts)
+      return ConstantVector::get(&Elts[0], Elts.size());
   }
-  if (Elts.size() == NumElts)
-    return ConstantVector::get(&Elts[0], Elts.size());
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec;
@@ -2155,8 +2332,7 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
          && "Insertelement types must match!");
   assert(Idx->getType() == Type::Int32Ty &&
          "Insertelement index must be i32 type!");
-  return getInsertElementTy(cast<VectorType>(Val->getType())->getElementType(),
-                            Val, Elt, Idx);
+  return getInsertElementTy(Val->getType(), Val, Elt, Idx);
 }
 
 Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
@@ -2178,6 +2354,58 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
   return getShuffleVectorTy(V1->getType(), V1, V2, Mask);
 }
 
+Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg,
+                                         Constant *Val,
+                                        const unsigned *Idxs, unsigned NumIdx) {
+  assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
+                                          Idxs+NumIdx) == Val->getType() &&
+         "insertvalue indices invalid!");
+  assert(Agg->getType() == ReqTy &&
+         "insertvalue type invalid!");
+  assert(Agg->getType()->isFirstClassType() &&
+         "Non-first-class type for constant InsertValue expression");
+  Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
+  assert(FC && "InsertValue constant expr couldn't be folded!");
+  return FC;
+}
+
+Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
+                                     const unsigned *IdxList, unsigned NumIdx) {
+  assert(Agg->getType()->isFirstClassType() &&
+         "Tried to create insertelement operation on non-first-class type!");
+
+  const Type *ReqTy = Agg->getType();
+#ifndef NDEBUG
+  const Type *ValTy =
+    ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx);
+#endif
+  assert(ValTy == Val->getType() && "insertvalue indices invalid!");
+  return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx);
+}
+
+Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg,
+                                        const unsigned *Idxs, unsigned NumIdx) {
+  assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
+                                          Idxs+NumIdx) == ReqTy &&
+         "extractvalue indices invalid!");
+  assert(Agg->getType()->isFirstClassType() &&
+         "Non-first-class type for constant extractvalue expression");
+  Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
+  assert(FC && "ExtractValue constant expr couldn't be folded!");
+  return FC;
+}
+
+Constant *ConstantExpr::getExtractValue(Constant *Agg,
+                                     const unsigned *IdxList, unsigned NumIdx) {
+  assert(Agg->getType()->isFirstClassType() &&
+         "Tried to create extractelement operation on non-first-class type!");
+
+  const Type *ReqTy =
+    ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx);
+  assert(ReqTy && "extractvalue indices invalid!");
+  return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx);
+}
+
 Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) {
   if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
     if (PTy->getElementType()->isFloatingPoint()) {
@@ -2403,6 +2631,22 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
     }
     Replacement = ConstantExpr::getGetElementPtr(Pointer,
                                                  &Indices[0], Indices.size());
+  } else if (getOpcode() == Instruction::ExtractValue) {
+    Constant *Agg = getOperand(0);
+    if (Agg == From) Agg = To;
+    
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    Replacement = ConstantExpr::getExtractValue(Agg,
+                                                &Indices[0], Indices.size());
+  } else if (getOpcode() == Instruction::InsertValue) {
+    Constant *Agg = getOperand(0);
+    Constant *Val = getOperand(1);
+    if (Agg == From) Agg = To;
+    if (Val == From) Val = To;
+    
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    Replacement = ConstantExpr::getInsertValue(Agg, Val,
+                                               &Indices[0], Indices.size());
   } else if (isCast()) {
     assert(getOperand(0) == From && "Cast only has one use!");
     Replacement = ConstantExpr::getCast(getOpcode(), To, getType());
@@ -2443,8 +2687,14 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
     if (C2 == From) C2 = To;
     if (getOpcode() == Instruction::ICmp)
       Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2);
-    else
+    else if (getOpcode() == Instruction::FCmp)
       Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2);
+    else if (getOpcode() == Instruction::VICmp)
+      Replacement = ConstantExpr::getVICmp(getPredicate(), C1, C2);
+    else {
+      assert(getOpcode() == Instruction::VFCmp);
+      Replacement = ConstantExpr::getVFCmp(getPredicate(), C1, C2);
+    }
   } else if (getNumOperands() == 2) {
     Constant *C1 = getOperand(0);
     Constant *C2 = getOperand(1);
@@ -2464,43 +2714,3 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
   // Delete the old constant!
   destroyConstant();
 }
-
-
-/// getStringValue - Turn an LLVM constant pointer that eventually points to a
-/// global into a string value.  Return an empty string if we can't do it.
-/// Parameter Chop determines if the result is chopped at the first null
-/// terminator.
-///
-std::string Constant::getStringValue(bool Chop, unsigned Offset) {
-  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) {
-    if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
-      ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
-      if (Init->isString()) {
-        std::string Result = Init->getAsString();
-        if (Offset < Result.size()) {
-          // If we are pointing INTO The string, erase the beginning...
-          Result.erase(Result.begin(), Result.begin()+Offset);
-
-          // Take off the null terminator, and any string fragments after it.
-          if (Chop) {
-            std::string::size_type NullPos = Result.find_first_of((char)0);
-            if (NullPos != std::string::npos)
-              Result.erase(Result.begin()+NullPos, Result.end());
-          }
-          return Result;
-        }
-      }
-    }
-  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
-    if (CE->getOpcode() == Instruction::GetElementPtr) {
-      // Turn a gep into the specified offset.
-      if (CE->getNumOperands() == 3 &&
-          cast<Constant>(CE->getOperand(1))->isNullValue() &&
-          isa<ConstantInt>(CE->getOperand(2))) {
-        Offset += cast<ConstantInt>(CE->getOperand(2))->getZExtValue();
-        return CE->getOperand(0)->getStringValue(Chop, Offset);
-      }
-    }
-  }
-  return "";
-}