Fix comment typo.
[oota-llvm.git] / lib / VMCore / Constants.cpp
index e171011159c972a15727196c5f14d83efae4c25e..470e247e4cc464aec9687b63b3d59537082a8527 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.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -103,12 +103,20 @@ bool Constant::ContainsRelocations() const {
 
 // Static constructor to create a '0' constant of arbitrary type...
 Constant *Constant::getNullValue(const Type *Ty) {
+  static uint64_t zero[2] = {0, 0};
   switch (Ty->getTypeID()) {
   case Type::IntegerTyID:
     return ConstantInt::get(Ty, 0);
   case Type::FloatTyID:
+    return ConstantFP::get(Ty, APFloat(APInt(32, 0)));
   case Type::DoubleTyID:
-    return ConstantFP::get(Ty, 0.0);
+    return ConstantFP::get(Ty, APFloat(APInt(64, 0)));
+  case Type::X86_FP80TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
+  case Type::FP128TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero), true));
+  case Type::PPC_FP128TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
   case Type::PointerTyID:
     return ConstantPointerNull::get(cast<PointerType>(Ty));
   case Type::StructTyID:
@@ -196,10 +204,13 @@ namespace {
     static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); }
     static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); }
     static unsigned getHashValue(const KeyTy &Key) {
-      return DenseMapKeyInfo<void*>::getHashValue(Key.type) ^ 
+      return DenseMapInfo<void*>::getHashValue(Key.type) ^ 
         Key.val.getHashValue();
     }
-    static bool isPod() { return true; }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
+    }
+    static bool isPod() { return false; }
   };
 }
 
@@ -214,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.
@@ -235,69 +246,94 @@ ConstantInt *ConstantInt::get(const APInt& V) {
 //                                ConstantFP
 //===----------------------------------------------------------------------===//
 
-
-ConstantFP::ConstantFP(const Type *Ty, double V)
-  : Constant(Ty, ConstantFPVal, 0, 0) {
-  Val = V;
+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);
 }
 
 bool ConstantFP::isNullValue() const {
-  return DoubleToBits(Val) == 0;
+  return Val.isZero() && !Val.isNegative();
 }
 
-bool ConstantFP::isExactlyValue(double V) const {
-  return DoubleToBits(V) == DoubleToBits(Val);
+ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) {
+  APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
+  apf.changeSign();
+  return ConstantFP::get(Ty, apf);
 }
 
+bool ConstantFP::isExactlyValue(const APFloat& V) const {
+  return Val.bitwiseIsEqual(V);
+}
 
 namespace {
-  struct DenseMapInt64KeyInfo {
-    typedef std::pair<uint64_t, const Type*> KeyTy;
-    static inline KeyTy getEmptyKey() { return KeyTy(0, 0); }
-    static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); }
-    static unsigned getHashValue(const KeyTy &Key) {
-      return DenseMapKeyInfo<void*>::getHashValue(Key.second) ^ Key.first;
+  struct DenseMapAPFloatKeyInfo {
+    struct KeyTy {
+      APFloat val;
+      KeyTy(const APFloat& V) : val(V){}
+      KeyTy(const KeyTy& that) : val(that.val) {}
+      bool operator==(const KeyTy& that) const {
+        return this->val.bitwiseIsEqual(that.val);
+      }
+      bool operator!=(const KeyTy& that) const {
+        return !this->operator==(that);
+      }
+    };
+    static inline KeyTy getEmptyKey() { 
+      return KeyTy(APFloat(APFloat::Bogus,1));
+    }
+    static inline KeyTy getTombstoneKey() { 
+      return KeyTy(APFloat(APFloat::Bogus,2)); 
     }
-    static bool isPod() { return true; }
-  };
-  struct DenseMapInt32KeyInfo {
-    typedef std::pair<uint32_t, const Type*> KeyTy;
-    static inline KeyTy getEmptyKey() { return KeyTy(0, 0); }
-    static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); }
     static unsigned getHashValue(const KeyTy &Key) {
-      return DenseMapKeyInfo<void*>::getHashValue(Key.second) ^ Key.first;
+      return Key.val.getHashValue();
+    }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
     }
-    static bool isPod() { return true; }
+    static bool isPod() { return false; }
   };
 }
 
 //---- ConstantFP::get() implementation...
 //
-typedef DenseMap<DenseMapInt32KeyInfo::KeyTy, ConstantFP*, 
-                 DenseMapInt32KeyInfo> FloatMapTy;
-typedef DenseMap<DenseMapInt64KeyInfo::KeyTy, ConstantFP*, 
-                 DenseMapInt64KeyInfo> DoubleMapTy;
-
-static ManagedStatic<FloatMapTy> FloatConstants;
-static ManagedStatic<DoubleMapTy> DoubleConstants;
-
-ConstantFP *ConstantFP::get(const Type *Ty, double V) {
-  if (Ty == Type::FloatTy) {
-    uint32_t IntVal = FloatToBits((float)V);
-    
-    ConstantFP *&Slot = (*FloatConstants)[std::make_pair(IntVal, Ty)];
-    if (Slot) return Slot;
-    return Slot = new ConstantFP(Ty, (float)V);
-  } else {
-    assert(Ty == Type::DoubleTy);
-    uint64_t IntVal = DoubleToBits(V);
-    ConstantFP *&Slot = (*DoubleConstants)[std::make_pair(IntVal, Ty)];
-    if (Slot) return Slot;
-    return Slot = new ConstantFP(Ty, V);
-  }
+typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, 
+                 DenseMapAPFloatKeyInfo> FPMapTy;
+
+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);
+  
+  DenseMapAPFloatKeyInfo::KeyTy Key(V);
+  ConstantFP *&Slot = (*FPConstants)[Key];
+  if (Slot) return Slot;
+  return Slot = new ConstantFP(Ty, V);
 }
 
-
 //===----------------------------------------------------------------------===//
 //                            ConstantXXX Classes
 //===----------------------------------------------------------------------===//
@@ -502,7 +538,7 @@ Constant *ConstantExpr::getNeg(Constant *C) {
              C);
 }
 Constant *ConstantExpr::getNot(Constant *C) {
-  assert(isa<ConstantInt>(C) && "Cannot NOT a nonintegral type!");
+  assert(isa<IntegerType>(C->getType()) && "Cannot NOT a nonintegral value!");
   return get(Instruction::Xor, C,
              ConstantInt::getAllOnesValue(C->getType()));
 }
@@ -544,7 +580,7 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
 }
 unsigned ConstantExpr::getPredicate() const {
   assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
-  return dynamic_cast<const CompareConstantExpr*>(this)->predicate;
+  return ((const CompareConstantExpr*)this)->predicate;
 }
 Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
   return get(Instruction::Shl, C1, C2);
@@ -691,15 +727,35 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
   return (Val >= Min && Val <= Max);
 }
 
-bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
+bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
+  // convert modifies in place, so make a copy.
+  APFloat Val2 = APFloat(Val);
   switch (Ty->getTypeID()) {
   default:
     return false;         // These can't be represented as floating point!
 
-    // TODO: Figure out how to test if a double can be cast to a float!
+  // 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 true;          // This is the largest type...
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) == 
+             APFloat::opOK;
+  case Type::X86_FP80TyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::x87DoubleExtended;
+  case Type::FP128TyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::IEEEquad;
+  case Type::PPC_FP128TyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::PPCDoubleDouble;
   }
 }
 
@@ -1230,6 +1286,17 @@ bool ConstantVector::isAllOnesValue() const {
   return true;
 }
 
+/// getSplatValue - If this is a splat constant, where all of the
+/// elements have the same value, return that value. Otherwise return null.
+Constant *ConstantVector::getSplatValue() {
+  // Check out first element.
+  Constant *Elt = getOperand(0);
+  // Then make sure all remaining elements point to the same value.
+  for (unsigned I = 1, E = getNumOperands(); I < E; ++I)
+    if (getOperand(I) != Elt) return 0;
+  return Elt;
+}
+
 //---- ConstantPointerNull::get() implementation...
 //
 
@@ -1443,7 +1510,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!");
@@ -1576,26 +1643,38 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
-  assert(C->getType()->isInteger() && Ty->isFloatingPoint() &&
-         "This is an illegal i32 to floating point cast!");
+  bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+  bool toVec = Ty->getTypeID() == Type::VectorTyID;
+  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!");
   return getFoldedCast(Instruction::UIToFP, C, Ty);
 }
 
 Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
-  assert(C->getType()->isInteger() && Ty->isFloatingPoint() &&
+  bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+  bool toVec = Ty->getTypeID() == Type::VectorTyID;
+  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!");
   return getFoldedCast(Instruction::SIToFP, C, Ty);
 }
 
 Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
-  assert(C->getType()->isFloatingPoint() && Ty->isInteger() &&
-         "This is an illegal floating point to i32 cast!");
+  bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+  bool toVec = Ty->getTypeID() == Type::VectorTyID;
+  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!");
   return getFoldedCast(Instruction::FPToUI, C, Ty);
 }
 
 Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
-  assert(C->getType()->isFloatingPoint() && Ty->isInteger() &&
-         "This is an illegal floating point to i32 cast!");
+  bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+  bool toVec = Ty->getTypeID() == Type::VectorTyID;
+  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!");
   return getFoldedCast(Instruction::FPToSI, C, Ty);
 }
 
@@ -1628,10 +1707,10 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
 }
 
 Constant *ConstantExpr::getSizeOf(const Type *Ty) {
-  // sizeof is implemented as: (ulong) gep (Ty*)null, 1
+  // 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);
 }
 
@@ -1757,7 +1836,7 @@ 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, NumIdx, true) &&
+  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true) &&
          "GEP indices invalid!");
 
   if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx))
@@ -1779,9 +1858,10 @@ 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, NumIdx, true);
+    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,
@@ -1892,12 +1972,12 @@ Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) {
   if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
     if (PTy->getElementType()->isFloatingPoint()) {
       std::vector<Constant*> zeros(PTy->getNumElements(),
-                                   ConstantFP::get(PTy->getElementType(),-0.0));
+                           ConstantFP::getNegativeZero(PTy->getElementType()));
       return ConstantVector::get(PTy, zeros);
     }
 
-  if (Ty->isFloatingPoint())
-    return ConstantFP::get(Ty, -0.0);
+  if (Ty->isFloatingPoint()) 
+    return ConstantFP::getNegativeZero(Ty);
 
   return Constant::getNullValue(Ty);
 }
@@ -1916,14 +1996,21 @@ const char *ConstantExpr::getOpcodeName() const {
 //===----------------------------------------------------------------------===//
 //                replaceUsesOfWithOnConstant implementations
 
+/// replaceUsesOfWithOnConstant - Update this constant array to change uses of
+/// 'From' to be uses of 'To'.  This must update the uniquing data structures
+/// etc.
+///
+/// Note that we intentionally replace all uses of From with To here.  Consider
+/// a large array that uses 'From' 1000 times.  By handling this case all here,
+/// ConstantArray::replaceUsesOfWithOnConstant is only invoked once, and that
+/// single invocation handles all 1000 uses.  Handling them one at a time would
+/// work, but would be really slow because it would have to unique each updated
+/// array instance.
 void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
                                                 Use *U) {
   assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
   Constant *ToC = cast<Constant>(To);
 
-  unsigned OperandToUpdate = U-OperandList;
-  assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
-
   std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup;
   Lookup.first.first = getType();
   Lookup.second = this;
@@ -1934,18 +2021,28 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
   // Fill values with the modified operands of the constant array.  Also, 
   // compute whether this turns into an all-zeros array.
   bool isAllZeros = false;
+  unsigned NumUpdated = 0;
   if (!ToC->isNullValue()) {
-    for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O)
-      Values.push_back(cast<Constant>(O->get()));
+    for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
+      Constant *Val = cast<Constant>(O->get());
+      if (Val == From) {
+        Val = ToC;
+        ++NumUpdated;
+      }
+      Values.push_back(Val);
+    }
   } else {
     isAllZeros = true;
     for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
       Constant *Val = cast<Constant>(O->get());
+      if (Val == From) {
+        Val = ToC;
+        ++NumUpdated;
+      }
       Values.push_back(Val);
       if (isAllZeros) isAllZeros = Val->isNullValue();
     }
   }
-  Values[OperandToUpdate] = ToC;
   
   Constant *Replacement = 0;
   if (isAllZeros) {
@@ -1965,8 +2062,18 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
       // in place!
       ArrayConstants->MoveConstantToNewSlot(this, I);
       
-      // Update to the new value.
-      setOperand(OperandToUpdate, ToC);
+      // Update to the new value.  Optimize for the case when we have a single
+      // operand that we're changing, but handle bulk updates efficiently.
+      if (NumUpdated == 1) {
+        unsigned OperandToUpdate = U-OperandList;
+        assert(getOperand(OperandToUpdate) == From &&
+               "ReplaceAllUsesWith broken!");
+        setOperand(OperandToUpdate, ToC);
+      } else {
+        for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+          if (getOperand(i) == From)
+            setOperand(i, ToC);
+      }
       return;
     }
   }
@@ -2174,18 +2281,14 @@ std::string Constant::getStringValue(bool Chop, unsigned Offset) {
         }
       }
     }
-  } else if (Constant *C = dyn_cast<Constant>(this)) {
-    if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
-      return GV->getStringValue(Chop, Offset);
-    else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
-      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);
-        }
+  } 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);
       }
     }
   }