merge of use-diet branch to trunk
[oota-llvm.git] / lib / VMCore / Constants.cpp
index 49c27b82ccd665254cda5b85a56c680d21a83883..d0c837335dcee118e4accb91a1451a9e34b9797c 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -108,15 +108,15 @@ Constant *Constant::getNullValue(const Type *Ty) {
   case Type::IntegerTyID:
     return ConstantInt::get(Ty, 0);
   case Type::FloatTyID:
-    return ConstantFP::get(Ty, APFloat(APInt(32, 0)));
+    return ConstantFP::get(APFloat(APInt(32, 0)));
   case Type::DoubleTyID:
-    return ConstantFP::get(Ty, APFloat(APInt(64, 0)));
+    return ConstantFP::get(APFloat(APInt(64, 0)));
   case Type::X86_FP80TyID:
-    return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
+    return ConstantFP::get(APFloat(APInt(80, 2, zero)));
   case Type::FP128TyID:
-    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero), true));
+    return ConstantFP::get(APFloat(APInt(128, 2, zero), true));
   case Type::PPC_FP128TyID:
-    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
+    return ConstantFP::get(APFloat(APInt(128, 2, zero)));
   case Type::PointerTyID:
     return ConstantPointerNull::get(cast<PointerType>(Ty));
   case Type::StructTyID:
@@ -225,7 +225,7 @@ ConstantInt *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
 }
 
 // Get a ConstantInt from an APInt. Note that the value stored in the DenseMap 
-// as the key, is a DensMapAPIntKeyInfo::KeyTy which has provided the
+// as the key, is a DenseMapAPIntKeyInfo::KeyTy which has provided the
 // operator== and operator!= to ensure that the DenseMap doesn't attempt to
 // compare APInt's of different widths, which would violate an APInt class
 // invariant which generates an assertion.
@@ -246,21 +246,24 @@ ConstantInt *ConstantInt::get(const APInt& V) {
 //                                ConstantFP
 //===----------------------------------------------------------------------===//
 
+static const fltSemantics *TypeToFloatSemantics(const Type *Ty) {
+  if (Ty == Type::FloatTy)
+    return &APFloat::IEEEsingle;
+  if (Ty == Type::DoubleTy)
+    return &APFloat::IEEEdouble;
+  if (Ty == Type::X86_FP80Ty)
+    return &APFloat::x87DoubleExtended;
+  else if (Ty == Type::FP128Ty)
+    return &APFloat::IEEEquad;
+  
+  assert(Ty == Type::PPC_FP128Ty && "Unknown FP format");
+  return &APFloat::PPCDoubleDouble;
+}
+
 ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
   : Constant(Ty, ConstantFPVal, 0, 0), Val(V) {
-  // temporary
-  if (Ty==Type::FloatTy)
-    assert(&V.getSemantics()==&APFloat::IEEEsingle);
-  else if (Ty==Type::DoubleTy)
-    assert(&V.getSemantics()==&APFloat::IEEEdouble);
-  else if (Ty==Type::X86_FP80Ty)
-    assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
-  else if (Ty==Type::FP128Ty)
-    assert(&V.getSemantics()==&APFloat::IEEEquad);
-  else if (Ty==Type::PPC_FP128Ty)
-    assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);
-  else
-    assert(0);
+  assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
+         "FP type Mismatch");
 }
 
 bool ConstantFP::isNullValue() const {
@@ -270,7 +273,7 @@ bool ConstantFP::isNullValue() const {
 ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) {
   APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
   apf.changeSign();
-  return ConstantFP::get(Ty, apf);
+  return ConstantFP::get(apf);
 }
 
 bool ConstantFP::isExactlyValue(const APFloat& V) const {
@@ -313,27 +316,37 @@ typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
 
 static ManagedStatic<FPMapTy> FPConstants;
 
-ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
-  // temporary
-  if (Ty==Type::FloatTy)
-    assert(&V.getSemantics()==&APFloat::IEEEsingle);
-  else if (Ty==Type::DoubleTy)
-    assert(&V.getSemantics()==&APFloat::IEEEdouble);
-  else if (Ty==Type::X86_FP80Ty)
-    assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
-  else if (Ty==Type::FP128Ty)
-    assert(&V.getSemantics()==&APFloat::IEEEquad);
-  else if (Ty==Type::PPC_FP128Ty)
-    assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);
-  else
-    assert(0);
-  
+ConstantFP *ConstantFP::get(const APFloat &V) {
   DenseMapAPFloatKeyInfo::KeyTy Key(V);
   ConstantFP *&Slot = (*FPConstants)[Key];
   if (Slot) return Slot;
+  
+  const Type *Ty;
+  if (&V.getSemantics() == &APFloat::IEEEsingle)
+    Ty = Type::FloatTy;
+  else if (&V.getSemantics() == &APFloat::IEEEdouble)
+    Ty = Type::DoubleTy;
+  else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
+    Ty = Type::X86_FP80Ty;
+  else if (&V.getSemantics() == &APFloat::IEEEquad)
+    Ty = Type::FP128Ty;
+  else {
+    assert(&V.getSemantics() == &APFloat::PPCDoubleDouble&&"Unknown FP format");
+    Ty = Type::PPC_FP128Ty;
+  }
+  
   return Slot = new ConstantFP(Ty, V);
 }
 
+/// get() - This returns a constant fp for the specified value in the
+/// specified type.  This should only be used for simple constant values like
+/// 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);
+  return get(FV);
+}
+
 //===----------------------------------------------------------------------===//
 //                            ConstantXXX Classes
 //===----------------------------------------------------------------------===//
@@ -341,7 +354,9 @@ ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
 
 ConstantArray::ConstantArray(const ArrayType *T,
                              const std::vector<Constant*> &V)
-  : Constant(T, ConstantArrayVal, new Use[V.size()], V.size()) {
+  : Constant(T, ConstantArrayVal,
+             OperandTraits<ConstantArray>::op_end(this) - V.size(),
+             V.size()) {
   assert(V.size() == T->getNumElements() &&
          "Invalid initializer vector for constant array");
   Use *OL = OperandList;
@@ -356,13 +371,12 @@ ConstantArray::ConstantArray(const ArrayType *T,
   }
 }
 
-ConstantArray::~ConstantArray() {
-  delete [] OperandList;
-}
 
 ConstantStruct::ConstantStruct(const StructType *T,
                                const std::vector<Constant*> &V)
-  : Constant(T, ConstantStructVal, new Use[V.size()], V.size()) {
+  : Constant(T, ConstantStructVal,
+             OperandTraits<ConstantStruct>::op_end(this) - V.size(),
+             V.size()) {
   assert(V.size() == T->getNumElements() &&
          "Invalid initializer vector for constant structure");
   Use *OL = OperandList;
@@ -379,14 +393,12 @@ ConstantStruct::ConstantStruct(const StructType *T,
   }
 }
 
-ConstantStruct::~ConstantStruct() {
-  delete [] OperandList;
-}
-
 
 ConstantVector::ConstantVector(const VectorType *T,
                                const std::vector<Constant*> &V)
-  : Constant(T, ConstantVectorVal, new Use[V.size()], V.size()) {
+  : Constant(T, ConstantVectorVal,
+             OperandTraits<ConstantVector>::op_end(this) - V.size(),
+             V.size()) {
   Use *OL = OperandList;
     for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
          I != E; ++I, ++OL) {
@@ -399,10 +411,8 @@ ConstantVector::ConstantVector(const VectorType *T,
   }
 }
 
-ConstantVector::~ConstantVector() {
-  delete [] OperandList;
-}
 
+namespace llvm {
 // We declare several classes private to this file, so use an anonymous
 // namespace
 namespace {
@@ -410,113 +420,214 @@ namespace {
 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement unary constant exprs.
 class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr {
-  Use Op;
+  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);
+  }
   UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
-    : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {}
+    : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
+    Op<0>() = C;
+  }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement binary constant exprs.
 class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr {
-  Use Ops[2];
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
 public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
-    : ConstantExpr(C1->getType(), Opcode, Ops, 2) {
-    Ops[0].init(C1, this);
-    Ops[1].init(C2, this);
+    : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
+    Op<0>().init(C1, this);
+    Op<1>().init(C2, this);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement select constant exprs.
 class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr {
-  Use Ops[3];
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
 public:
+  // allocate space for exactly three operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 3);
+  }
   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
-    : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) {
-    Ops[0].init(C1, this);
-    Ops[1].init(C2, this);
-    Ops[2].init(C3, this);
+    : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
+    Op<0>().init(C1, this);
+    Op<1>().init(C2, this);
+    Op<2>().init(C3, this);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 /// ExtractElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// extractelement constant exprs.
 class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr {
-  Use Ops[2];
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
 public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
   ExtractElementConstantExpr(Constant *C1, Constant *C2)
     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 
-                   Instruction::ExtractElement, Ops, 2) {
-    Ops[0].init(C1, this);
-    Ops[1].init(C2, this);
+                   Instruction::ExtractElement, &Op<0>(), 2) {
+    Op<0>().init(C1, this);
+    Op<1>().init(C2, this);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 /// InsertElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// insertelement constant exprs.
 class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr {
-  Use Ops[3];
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
 public:
+  // allocate space for exactly three operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 3);
+  }
   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C1->getType(), Instruction::InsertElement, 
-                   Ops, 3) {
-    Ops[0].init(C1, this);
-    Ops[1].init(C2, this);
-    Ops[2].init(C3, this);
+                   &Op<0>(), 3) {
+    Op<0>().init(C1, this);
+    Op<1>().init(C2, this);
+    Op<2>().init(C3, this);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 /// ShuffleVectorConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// shufflevector constant exprs.
 class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr {
-  Use Ops[3];
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
 public:
+  // allocate space for exactly three operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 3);
+  }
   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
   : ConstantExpr(C1->getType(), Instruction::ShuffleVector, 
-                 Ops, 3) {
-    Ops[0].init(C1, this);
-    Ops[1].init(C2, this);
-    Ops[2].init(C3, this);
+                 &Op<0>(), 3) {
+    Op<0>().init(C1, this);
+    Op<1>().init(C2, this);
+    Op<2>().init(C3, this);
   }
+  /// 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.
-struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
+class VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
   GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
-                            const Type *DestTy)
-    : ConstantExpr(DestTy, Instruction::GetElementPtr,
-                   new Use[IdxList.size()+1], IdxList.size()+1) {
-    OperandList[0].init(C, this);
-    for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
-      OperandList[i+1].init(IdxList[i], this);
-  }
-  ~GetElementPtrConstantExpr() {
-    delete [] OperandList;
+                            const Type *DestTy);
+public:
+  static GetElementPtrConstantExpr *Create(Constant *C, const std::vector<Constant*> &IdxList,
+                                           const Type *DestTy) {
+    return new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 // 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 {
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
   unsigned short predicate;
-  Use Ops[2];
   CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, 
                       Constant* LHS, Constant* RHS)
-    : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) {
-    OperandList[0].init(LHS, this);
-    OperandList[1].init(RHS, this);
+    : ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) {
+    Op<0>().init(LHS, this);
+    Op<1>().init(RHS, this);
   }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
 } // end anonymous namespace
 
+template <>
+struct OperandTraits<UnaryConstantExpr> : FixedNumOperandTraits<1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
+
+template <>
+struct OperandTraits<BinaryConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
+
+template <>
+struct OperandTraits<SelectConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
+
+template <>
+struct OperandTraits<ExtractElementConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
+
+template <>
+struct OperandTraits<InsertElementConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
+
+template <>
+struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
+
+
+template <>
+struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> {
+};
+
+GetElementPtrConstantExpr::GetElementPtrConstantExpr
+  (Constant *C,
+   const std::vector<Constant*> &IdxList,
+   const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::GetElementPtr,
+                   OperandTraits<GetElementPtrConstantExpr>::op_end(this)
+                   - (IdxList.size()+1),
+                   IdxList.size()+1) {
+  OperandList[0].init(C, this);
+  for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+    OperandList[i+1].init(IdxList[i], this);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
+
+
+template <>
+struct OperandTraits<CompareConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
+
+
+} // End llvm namespace
+
 
 // Utility function for determining if a ConstantExpr is a CastOp or not. This
 // can't be inline because we don't want to #include Instruction.h into
@@ -762,16 +873,29 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
 //===----------------------------------------------------------------------===//
 //                      Factory Function Implementation
 
+
+// The number of operands for each ConstantCreator::create method is
+// determined by the ConstantTraits template.
 // ConstantCreator - A class that is used to create constants by
 // ValueMap*.  This class should be partially specialized if there is
 // something strange that needs to be done to interface to the ctor for the
 // constant.
 //
 namespace llvm {
+  template<class ValType>
+  struct ConstantTraits;
+
+  template<typename T, typename Alloc>
+  struct VISIBILITY_HIDDEN ConstantTraits< std::vector<T, Alloc> > {
+    static unsigned uses(const std::vector<T, Alloc>& v) {
+      return v.size();
+    }
+  };
+
   template<class ConstantClass, class TypeClass, class ValType>
   struct VISIBILITY_HIDDEN ConstantCreator {
     static ConstantClass *create(const TypeClass *Ty, const ValType &V) {
-      return new ConstantClass(Ty, V);
+      return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
     }
   };
 
@@ -1433,7 +1557,7 @@ namespace llvm {
                                              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);
+        return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
       }
 
       // The compare instructions are weird. We have to encode the predicate
@@ -1510,7 +1634,7 @@ static ManagedStatic<ValueMap<ExprMapKeyType, Type,
                               ConstantExpr> > ExprConstants;
 
 /// This is a utility function to handle folding of casts and lookup of the
-/// cast in the ExprConstants map. It is usedby the various get* methods below.
+/// cast in the ExprConstants map. It is used by the various get* methods below.
 static inline Constant *getFoldedCast(
   Instruction::CastOps opc, Constant *C, const Type *Ty) {
   assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
@@ -1710,7 +1834,7 @@ Constant *ConstantExpr::getSizeOf(const Type *Ty) {
   // sizeof is implemented as: (i64) gep (Ty*)null, 1
   Constant *GEPIdx = ConstantInt::get(Type::Int32Ty, 1);
   Constant *GEP =
-    getGetElementPtr(getNullValue(PointerType::get(Ty)), &GEPIdx, 1);
+    getGetElementPtr(getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1);
   return getCast(Instruction::PtrToInt, GEP, Type::Int64Ty);
 }
 
@@ -1860,7 +1984,8 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
   const Type *Ty = 
     GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
   assert(Ty && "GEP indices invalid!");
-  return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
+  unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
+  return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
 }
 
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,