Adding C and Ocaml bindings for ConstantExpr.
[oota-llvm.git] / lib / VMCore / Constants.cpp
index 0d595314a53890adeeef750b6c641fb4f2aa044f..7de823b1ba5f37f3f0bc36acc68e76c9cee9a587 100644 (file)
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Constants.h"
-#include "ConstantFolding.h"
+#include "ConstantFold.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/GlobalValue.h"
 #include "llvm/Instructions.h"
@@ -22,6 +22,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include <algorithm>
 #include <map>
@@ -89,14 +90,32 @@ bool Constant::canTrap() const {
   }
 }
 
+/// ContaintsRelocations - Return true if the constant value contains
+/// relocations which cannot be resolved at compile time.
+bool Constant::ContainsRelocations() const {
+  if (isa<GlobalValue>(this))
+    return true;
+  for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+    if (getOperand(i)->ContainsRelocations())
+      return true;
+  return false;
+}
+
 // 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:
+  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:
@@ -110,46 +129,211 @@ Constant *Constant::getNullValue(const Type *Ty) {
   }
 }
 
+Constant *Constant::getAllOnesValue(const Type *Ty) {
+  if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
+    return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));
+  return ConstantVector::getAllOnesValue(cast<VectorType>(Ty));
+}
 
 // Static constructor to create an integral constant with all bits set
 ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) {
   if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
-    if (ITy->getBitWidth() == 1)
-      return ConstantInt::getTrue();
-    else
-      return ConstantInt::get(Ty, int64_t(-1));
+    return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));
   return 0;
 }
 
-/// @returns the value for an packed integer constant of the given type that
+/// @returns the value for a vector integer constant of the given type that
 /// has all its bits set to true.
 /// @brief Get the all ones value
 ConstantVector *ConstantVector::getAllOnesValue(const VectorType *Ty) {
   std::vector<Constant*> Elts;
   Elts.resize(Ty->getNumElements(),
               ConstantInt::getAllOnesValue(Ty->getElementType()));
-  assert(Elts[0] && "Not a packed integer type!");
+  assert(Elts[0] && "Not a vector integer type!");
   return cast<ConstantVector>(ConstantVector::get(Elts));
 }
 
 
 //===----------------------------------------------------------------------===//
-//                            ConstantXXX Classes
+//                                ConstantInt
 //===----------------------------------------------------------------------===//
 
+ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V)
+  : Constant(Ty, ConstantIntVal, 0, 0), Val(V) {
+  assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
+}
+
+ConstantInt *ConstantInt::TheTrueVal = 0;
+ConstantInt *ConstantInt::TheFalseVal = 0;
+
+namespace llvm {
+  void CleanupTrueFalse(void *) {
+    ConstantInt::ResetTrueFalse();
+  }
+}
+
+static ManagedCleanup<llvm::CleanupTrueFalse> TrueFalseCleanup;
+
+ConstantInt *ConstantInt::CreateTrueFalseVals(bool WhichOne) {
+  assert(TheTrueVal == 0 && TheFalseVal == 0);
+  TheTrueVal  = get(Type::Int1Ty, 1);
+  TheFalseVal = get(Type::Int1Ty, 0);
+  
+  // Ensure that llvm_shutdown nulls out TheTrueVal/TheFalseVal.
+  TrueFalseCleanup.Register();
+  
+  return WhichOne ? TheTrueVal : TheFalseVal;
+}
+
+
+namespace {
+  struct DenseMapAPIntKeyInfo {
+    struct KeyTy {
+      APInt val;
+      const Type* type;
+      KeyTy(const APInt& V, const Type* Ty) : val(V), type(Ty) {}
+      KeyTy(const KeyTy& that) : val(that.val), type(that.type) {}
+      bool operator==(const KeyTy& that) const {
+        return type == that.type && this->val == that.val;
+      }
+      bool operator!=(const KeyTy& that) const {
+        return !this->operator==(that);
+      }
+    };
+    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 DenseMapInfo<void*>::getHashValue(Key.type) ^ 
+        Key.val.getHashValue();
+    }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
+    }
+    static bool isPod() { return false; }
+  };
+}
+
+
+typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, 
+                 DenseMapAPIntKeyInfo> IntMapTy;
+static ManagedStatic<IntMapTy> IntConstants;
+
+ConstantInt *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
+  const IntegerType *ITy = cast<IntegerType>(Ty);
+  return get(APInt(ITy->getBitWidth(), V, 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
+// 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.
+ConstantInt *ConstantInt::get(const APInt& V) {
+  // Get the corresponding integer type for the bit width of the value.
+  const IntegerType *ITy = IntegerType::get(V.getBitWidth());
+  // get an existing value or the insertion position
+  DenseMapAPIntKeyInfo::KeyTy Key(V, ITy);
+  ConstantInt *&Slot = (*IntConstants)[Key]; 
+  // if it exists, return it.
+  if (Slot)
+    return Slot;
+  // otherwise create a new one, insert it, and return it.
+  return Slot = new ConstantInt(ITy, V);
+}
+
+//===----------------------------------------------------------------------===//
+//                                ConstantFP
 //===----------------------------------------------------------------------===//
-//                             Normal Constructors
 
-ConstantInt::ConstantInt(const IntegerType *Ty, uint64_t V)
-  : Constant(Ty, ConstantIntVal, 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
+    assert(0);
+}
+
+bool ConstantFP::isNullValue() const {
+  return Val.isZero() && !Val.isNegative();
+}
+
+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 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 unsigned getHashValue(const KeyTy &Key) {
+      return Key.val.getHashValue();
+    }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
+    }
+    static bool isPod() { return false; }
+  };
 }
 
-ConstantFP::ConstantFP(const Type *Ty, double V)
-  : Constant(Ty, ConstantFPVal, 0, 0) {
-  assert(isValueValidForType(Ty, V) && "Value too large for type!");
-  Val = V;
+//---- ConstantFP::get() implementation...
+//
+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
+    assert(0);
+  
+  DenseMapAPFloatKeyInfo::KeyTy Key(V);
+  ConstantFP *&Slot = (*FPConstants)[Key];
+  if (Slot) return Slot;
+  return Slot = new ConstantFP(Ty, V);
 }
 
+//===----------------------------------------------------------------------===//
+//                            ConstantXXX Classes
+//===----------------------------------------------------------------------===//
+
+
 ConstantArray::ConstantArray(const ArrayType *T,
                              const std::vector<Constant*> &V)
   : Constant(T, ConstantArrayVal, new Use[V.size()], V.size()) {
@@ -205,7 +389,7 @@ ConstantVector::ConstantVector(const VectorType *T,
       assert((C->getType() == T->getElementType() ||
             (T->isAbstract() &&
              C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
-           "Initializer for packed element doesn't match packed element type!");
+           "Initializer for vector element doesn't match vector element type!");
     OL->init(C, this);
   }
 }
@@ -349,7 +533,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()));
 }
@@ -538,15 +722,31 @@ 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;
   }
 }
 
@@ -598,15 +798,6 @@ namespace llvm {
     ///
     AbstractTypeMapTy AbstractTypeMap;
 
-  private:
-    void clear(std::vector<Constant *> &Constants) {
-      for(typename MapTy::iterator I = Map.begin(); I != Map.end(); ++I)
-        Constants.push_back(I->second);
-      Map.clear();
-      AbstractTypeMap.clear();
-      InverseMap.clear();
-    }
-
   public:
     typename MapTy::iterator map_end() { return Map.end(); }
     
@@ -796,65 +987,6 @@ public:
 }
 
 
-//---- ConstantInt::get() implementations...
-//
-static ManagedStatic<ValueMap<uint64_t, IntegerType, ConstantInt> >IntConstants;
-
-// Get a ConstantInt from an int64_t. Note here that we canoncialize the value
-// to a uint64_t value that has been zero extended down to the size of the
-// integer type of the ConstantInt. This allows the getZExtValue method to 
-// just return the stored value while getSExtValue has to convert back to sign
-// extended. getZExtValue is more common in LLVM than getSExtValue().
-ConstantInt *ConstantInt::get(const Type *Ty, int64_t V) {
-  const IntegerType *ITy = cast<IntegerType>(Ty);
-  if (Ty == Type::Int1Ty)
-    if (V & 1)
-      return getTrue();
-    else
-      return getFalse();
-  return IntConstants->getOrCreate(ITy, V & ITy->getBitMask());
-}
-
-//---- ConstantFP::get() implementation...
-//
-namespace llvm {
-  template<>
-  struct ConstantCreator<ConstantFP, Type, uint64_t> {
-    static ConstantFP *create(const Type *Ty, uint64_t V) {
-      assert(Ty == Type::DoubleTy);
-      return new ConstantFP(Ty, BitsToDouble(V));
-    }
-  };
-  template<>
-  struct ConstantCreator<ConstantFP, Type, uint32_t> {
-    static ConstantFP *create(const Type *Ty, uint32_t V) {
-      assert(Ty == Type::FloatTy);
-      return new ConstantFP(Ty, BitsToFloat(V));
-    }
-  };
-}
-
-static ManagedStatic<ValueMap<uint64_t, Type, ConstantFP> > DoubleConstants;
-static ManagedStatic<ValueMap<uint32_t, Type, ConstantFP> > FloatConstants;
-
-bool ConstantFP::isNullValue() const {
-  return DoubleToBits(Val) == 0;
-}
-
-bool ConstantFP::isExactlyValue(double V) const {
-  return DoubleToBits(V) == DoubleToBits(Val);
-}
-
-
-ConstantFP *ConstantFP::get(const Type *Ty, double V) {
-  if (Ty == Type::FloatTy) {
-    // Force the value through memory to normalize it.
-    return FloatConstants->getOrCreate(Ty, FloatToBits(V));
-  } else {
-    assert(Ty == Type::DoubleTy);
-    return DoubleConstants->getOrCreate(Ty, DoubleToBits(V));
-  }
-}
 
 //---- ConstantAggregateZero::get() implementation...
 //
@@ -1105,7 +1237,7 @@ static ManagedStatic<ValueMap<std::vector<Constant*>, VectorType,
 
 Constant *ConstantVector::get(const VectorType *Ty,
                               const std::vector<Constant*> &V) {
-  // If this is an all-zero packed, return a ConstantAggregateZero object
+  // If this is an all-zero vector, return a ConstantAggregateZero object
   if (!V.empty()) {
     Constant *C = V[0];
     if (!C->isNullValue())
@@ -1129,7 +1261,7 @@ void ConstantVector::destroyConstant() {
   destroyConstantImpl();
 }
 
-/// This function will return true iff every element in this packed constant
+/// This function will return true iff every element in this vector constant
 /// is set to all ones.
 /// @returns true iff this constant's emements are all set to all ones.
 /// @brief Determine if the value is all ones.
@@ -1543,7 +1675,7 @@ 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);
@@ -1672,7 +1804,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))
@@ -1694,7 +1826,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, NumIdx, true);
+    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
   assert(Ty && "GEP indices invalid!");
   return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
 }
@@ -1807,12 +1939,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);
 }
@@ -1831,14 +1963,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;
@@ -1849,18 +1988,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) {
@@ -1880,8 +2029,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;
     }
   }