Transform BU pass to not use the horrible DSCallSiteIterator class.
[oota-llvm.git] / lib / VMCore / Constants.cpp
index 77c34296aa81e0d6ebd78c1fd374977363eefccc..ee60f804b3cbd765d9962d3bb0d3726478db340b 100644 (file)
@@ -31,13 +31,6 @@ ConstantBool *ConstantBool::False = new ConstantBool(false);
 //                              Constant Class
 //===----------------------------------------------------------------------===//
 
-// Specialize setName to take care of symbol table majik
-void Constant::setName(const std::string &Name, SymbolTable *ST) {
-  assert(ST && "Type::setName - Must provide symbol table argument!");
-
-  if (Name.size()) ST->insert(Name, this);
-}
-
 void Constant::destroyConstantImpl() {
   // When a Constant is destroyed, there may be lingering
   // references to the constant by other constants in the constant pool.  These
@@ -216,7 +209,7 @@ bool ConstantUInt::isAllOnesValue() const {
 //                             Normal Constructors
 
 ConstantIntegral::ConstantIntegral(const Type *Ty, uint64_t V)
-  : Constant(Ty) {
+  : Constant(Ty, SimpleConstantVal, 0, 0) {
     Val.Unsigned = V;
 }
 
@@ -228,7 +221,7 @@ ConstantInt::ConstantInt(const Type *Ty, uint64_t V) : ConstantIntegral(Ty, V) {
 
 ConstantSInt::ConstantSInt(const Type *Ty, int64_t V) : ConstantInt(Ty, V) {
   assert(Ty->isInteger() && Ty->isSigned() &&
-         "Illegal type for unsigned integer constant!");
+         "Illegal type for signed integer constant!");
   assert(isValueValidForType(Ty, V) && "Value too large for type!");
 }
 
@@ -238,63 +231,77 @@ ConstantUInt::ConstantUInt(const Type *Ty, uint64_t V) : ConstantInt(Ty, V) {
   assert(isValueValidForType(Ty, V) && "Value too large for type!");
 }
 
-ConstantFP::ConstantFP(const Type *Ty, double V) : Constant(Ty) {
+ConstantFP::ConstantFP(const Type *Ty, double V)
+  : Constant(Ty, SimpleConstantVal, 0, 0) {
   assert(isValueValidForType(Ty, V) && "Value too large for type!");
   Val = V;
 }
 
 ConstantArray::ConstantArray(const ArrayType *T,
-                             const std::vector<Constant*> &V) : Constant(T) {
-  Operands.reserve(V.size());
+                             const std::vector<Constant*> &V)
+  : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) {
+  assert(V.size() == T->getNumElements() &&
+         "Invalid initializer vector for constant array");
+  Use *OL = OperandList;
   for (unsigned i = 0, e = V.size(); i != e; ++i) {
-    assert(V[i]->getType() == T->getElementType() ||
-           (T->isAbstract() &&
-            V[i]->getType()->getTypeID() == T->getElementType()->getTypeID()));
-    Operands.push_back(Use(V[i], this));
+    assert((V[i]->getType() == T->getElementType() ||
+            (T->isAbstract() &&
+             V[i]->getType()->getTypeID()==T->getElementType()->getTypeID())) &&
+           "Initializer for array element doesn't match array element type!");
+    OL[i].init(V[i], this);
   }
 }
 
+ConstantArray::~ConstantArray() {
+  delete [] OperandList;
+}
+
 ConstantStruct::ConstantStruct(const StructType *T,
-                               const std::vector<Constant*> &V) : Constant(T) {
+                               const std::vector<Constant*> &V)
+  : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) {
   assert(V.size() == T->getNumElements() &&
          "Invalid initializer vector for constant structure");
-  Operands.reserve(V.size());
+  Use *OL = OperandList;
   for (unsigned i = 0, e = V.size(); i != e; ++i) {
     assert((V[i]->getType() == T->getElementType(i) ||
             ((T->getElementType(i)->isAbstract() ||
               V[i]->getType()->isAbstract()) &&
-             T->getElementType(i)->getTypeID() == V[i]->getType()->getTypeID())) &&
+             T->getElementType(i)->getTypeID()==V[i]->getType()->getTypeID()))&&
            "Initializer for struct element doesn't match struct element type!");
-    Operands.push_back(Use(V[i], this));
+    OL[i].init(V[i], this);
   }
 }
 
+ConstantStruct::~ConstantStruct() {
+  delete [] OperandList;
+}
+
+
 ConstantPacked::ConstantPacked(const PackedType *T,
-                               const std::vector<Constant*> &V) : Constant(T) {
-  Operands.reserve(V.size());
+                               const std::vector<Constant*> &V)
+  : Constant(T, SimpleConstantVal, new Use[V.size()], V.size()) {
+  Use *OL = OperandList;
   for (unsigned i = 0, e = V.size(); i != e; ++i) {
-    assert(V[i]->getType() == T->getElementType() ||
-           (T->isAbstract() &&
-            V[i]->getType()->getTypeID() == T->getElementType()->getTypeID()));
-    Operands.push_back(Use(V[i], this));
+    assert((V[i]->getType() == T->getElementType() ||
+            (T->isAbstract() &&
+             V[i]->getType()->getTypeID()==T->getElementType()->getTypeID())) &&
+           "Initializer for packed element doesn't match packed element type!");
+    OL[i].init(V[i], this);
   }
 }
 
-ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
-  : Constant(Ty, ConstantExprVal), iType(Opcode) {
-  Operands.reserve(1);
-  Operands.push_back(Use(C, this));
-}
-
-// Select instruction creation ctor
-ConstantExpr::ConstantExpr(Constant *C, Constant *V1, Constant *V2)
-  : Constant(V1->getType(), ConstantExprVal), iType(Instruction::Select) {
-  Operands.reserve(3);
-  Operands.push_back(Use(C, this));
-  Operands.push_back(Use(V1, this));
-  Operands.push_back(Use(V2, this));
+ConstantPacked::~ConstantPacked() {
+  delete [] OperandList;
 }
 
+/// UnaryConstantExpr - This class is private to Constants.cpp, and is used
+/// behind the scenes to implement unary constant exprs.
+class UnaryConstantExpr : public ConstantExpr {
+  Use Op;
+public:
+  UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
+    : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {}
+};
 
 static bool isSetCC(unsigned Opcode) {
   return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
@@ -302,22 +309,47 @@ static bool isSetCC(unsigned Opcode) {
          Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
 }
 
-ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
-  : Constant(isSetCC(Opcode) ? Type::BoolTy : C1->getType(), ConstantExprVal),
-    iType(Opcode) {
-  Operands.reserve(2);
-  Operands.push_back(Use(C1, this));
-  Operands.push_back(Use(C2, this));
-}
+/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
+/// behind the scenes to implement binary constant exprs.
+class BinaryConstantExpr : public ConstantExpr {
+  Use Ops[2];
+public:
+  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
+    : ConstantExpr(isSetCC(Opcode) ? Type::BoolTy : C1->getType(),
+                   Opcode, Ops, 2) {
+    Ops[0].init(C1, this);
+    Ops[1].init(C2, this);
+  }
+};
 
-ConstantExpr::ConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
-                           const Type *DestTy)
-  : Constant(DestTy, ConstantExprVal), iType(Instruction::GetElementPtr) {
-  Operands.reserve(1+IdxList.size());
-  Operands.push_back(Use(C, this));
-  for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
-    Operands.push_back(Use(IdxList[i], this));
-}
+/// SelectConstantExpr - This class is private to Constants.cpp, and is used
+/// behind the scenes to implement select constant exprs.
+class SelectConstantExpr : public ConstantExpr {
+  Use Ops[3];
+public:
+  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);
+  }
+};
+
+/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
+/// used behind the scenes to implement getelementpr constant exprs.
+struct 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;    
+  }
+};
 
 /// ConstantExpr::get* - Return some common constants without having to
 /// specify the full Instruction::OPCODE identifier.
@@ -608,6 +640,16 @@ namespace {
 
     typedef std::map<const TypeClass*, MapIterator> AbstractTypeMapTy;
     AbstractTypeMapTy AbstractTypeMap;
+
+    friend void Constant::clearAllValueMaps();
+  private:
+    void clear(std::vector<Constant *> &Constants) {
+      for(MapIterator I = Map.begin(); I != Map.end(); ++I)
+        Constants.push_back(I->second);
+      Map.clear();
+      AbstractTypeMap.clear();
+    }
+
   public:
     // getOrCreate - Return the specified constant from the map, creating it if
     // necessary.
@@ -1094,6 +1136,51 @@ void ConstantPointerNull::destroyConstant() {
 }
 
 
+//---- UndefValue::get() implementation...
+//
+
+namespace llvm {
+  // UndefValue does not take extra "value" argument...
+  template<class ValType>
+  struct ConstantCreator<UndefValue, Type, ValType> {
+    static UndefValue *create(const Type *Ty, const ValType &V) {
+      return new UndefValue(Ty);
+    }
+  };
+
+  template<>
+  struct ConvertConstantType<UndefValue, Type> {
+    static void convert(UndefValue *OldC, const Type *NewTy) {
+      // Make everyone now use a constant of the new type.
+      Constant *New = UndefValue::get(NewTy);
+      assert(New != OldC && "Didn't replace constant??");
+      OldC->uncheckedReplaceAllUsesWith(New);
+      OldC->destroyConstant();     // This constant is now dead, destroy it.
+    }
+  };
+}
+
+static ValueMap<char, Type, UndefValue> UndefValueConstants;
+
+static char getValType(UndefValue *) {
+  return 0;
+}
+
+
+UndefValue *UndefValue::get(const Type *Ty) {
+  return UndefValueConstants.getOrCreate(Ty, 0);
+}
+
+// destroyConstant - Remove the constant from the constant table.
+//
+void UndefValue::destroyConstant() {
+  UndefValueConstants.remove(this);
+  destroyConstantImpl();
+}
+
+
+
+
 //---- ConstantExpr::get() implementations...
 //
 typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
@@ -1103,18 +1190,18 @@ namespace llvm {
   struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
     static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V) {
       if (V.first == Instruction::Cast)
-        return new ConstantExpr(Instruction::Cast, V.second[0], Ty);
+        return new UnaryConstantExpr(Instruction::Cast, V.second[0], Ty);
       if ((V.first >= Instruction::BinaryOpsBegin &&
            V.first < Instruction::BinaryOpsEnd) ||
           V.first == Instruction::Shl || V.first == Instruction::Shr)
-        return new ConstantExpr(V.first, V.second[0], V.second[1]);
+        return new BinaryConstantExpr(V.first, V.second[0], V.second[1]);
       if (V.first == Instruction::Select)
-        return new ConstantExpr(V.second[0], V.second[1], V.second[2]);
+        return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
       
       assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
       
       std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
-      return new ConstantExpr(V.second[0], IdxList, Ty);
+      return new GetElementPtrConstantExpr(V.second[0], IdxList, Ty);
     }
   };
 
@@ -1144,10 +1231,8 @@ namespace llvm {
         break;
       case Instruction::GetElementPtr:
         // Make everyone now use a constant of the new type... 
-        std::vector<Constant*> C;
-        for (unsigned i = 1, e = OldC->getNumOperands(); i != e; ++i)
-          C.push_back(cast<Constant>(OldC->getOperand(i)));
-        New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), C);
+        std::vector<Value*> Idx(OldC->op_begin()+1, OldC->op_end());
+        New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), Idx);
         break;
       }
       
@@ -1182,21 +1267,44 @@ Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) {
 }
 
 Constant *ConstantExpr::getSignExtend(Constant *C, const Type *Ty) {
-  assert(C->getType()->isInteger() && Ty->isInteger() &&
+  assert(C->getType()->isIntegral() && Ty->isIntegral() &&
          C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() &&
          "This is an illegal sign extension!");
-  C = ConstantExpr::getCast(C, C->getType()->getSignedVersion());
-  return ConstantExpr::getCast(C, Ty);
+  if (C->getType() != Type::BoolTy) {
+    C = ConstantExpr::getCast(C, C->getType()->getSignedVersion());
+    return ConstantExpr::getCast(C, Ty);
+  } else {
+    if (C == ConstantBool::True)
+      return ConstantIntegral::getAllOnesValue(Ty);
+    else
+      return ConstantIntegral::getNullValue(Ty);
+  }
 }
 
 Constant *ConstantExpr::getZeroExtend(Constant *C, const Type *Ty) {
-  assert(C->getType()->isInteger() && Ty->isInteger() &&
+  assert(C->getType()->isIntegral() && Ty->isIntegral() &&
          C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() &&
          "This is an illegal zero extension!");
-  C = ConstantExpr::getCast(C, C->getType()->getUnsignedVersion());
+  if (C->getType() != Type::BoolTy)
+    C = ConstantExpr::getCast(C, C->getType()->getUnsignedVersion());
   return ConstantExpr::getCast(C, Ty);
 }
 
+Constant *ConstantExpr::getSizeOf(const Type *Ty) {
+  // sizeof is implemented as: (ulong) gep (Ty*)null, 1
+  return getCast(
+    getGetElementPtr(getNullValue(PointerType::get(Ty)),
+                 std::vector<Constant*>(1, ConstantInt::get(Type::UIntTy, 1))),
+    Type::ULongTy);
+}
+
+Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
+  // pointer from array is implemented as: getelementptr arr ptr, 0, 0
+  static std::vector<Constant*> Indices(2, ConstantUInt::get(Type::UIntTy, 0));
+
+  return ConstantExpr::getGetElementPtr(C, Indices);
+}
+
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
                               Constant *C1, Constant *C2) {
   if (Opcode == Instruction::Shl || Opcode == Instruction::Shr)
@@ -1233,7 +1341,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
   case Instruction::Xor:
     assert(C1->getType() == C2->getType() && "Op types should be identical!");
     assert(C1->getType()->isIntegral() &&
-           "Tried to create an logical operation on a non-integral type!");
+           "Tried to create a logical operation on a non-integral type!");
     break;
   case Instruction::SetLT: case Instruction::SetGT: case Instruction::SetLE:
   case Instruction::SetGE: case Instruction::SetEQ: case Instruction::SetNE:
@@ -1294,9 +1402,8 @@ Constant *ConstantExpr::getShiftTy(const Type *ReqTy, unsigned Opcode,
 
 
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
-                                        const std::vector<Constant*> &IdxList) {
-  assert(GetElementPtrInst::getIndexedType(C->getType(),
-                   std::vector<Value*>(IdxList.begin(), IdxList.end()), true) &&
+                                           const std::vector<Value*> &IdxList) {
+  assert(GetElementPtrInst::getIndexedType(C->getType(), IdxList, true) &&
          "GEP indices invalid!");
 
   if (Constant *FC = ConstantFoldGetElementPtr(C, IdxList))
@@ -1305,9 +1412,12 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
   assert(isa<PointerType>(C->getType()) &&
          "Non-pointer type for constant GetElementPtr expression");
   // Look up the constant in the table first to ensure uniqueness
-  std::vector<Constant*> argVec(1, C);
-  argVec.insert(argVec.end(), IdxList.begin(), IdxList.end());
-  const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,argVec);
+  std::vector<Constant*> ArgVec;
+  ArgVec.reserve(IdxList.size()+1);
+  ArgVec.push_back(C);
+  for (unsigned i = 0, e = IdxList.size(); i != e; ++i)
+    ArgVec.push_back(cast<Constant>(IdxList[i]));
+  const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,ArgVec);
   return ExprConstants.getOrCreate(ReqTy, Key);
 }
 
@@ -1319,6 +1429,15 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C,
   const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), VIdxList,
                                                      true);
   assert(Ty && "GEP indices invalid!");
+  return getGetElementPtrTy(PointerType::get(Ty), C, VIdxList);
+}
+
+Constant *ConstantExpr::getGetElementPtr(Constant *C,
+                                         const std::vector<Value*> &IdxList) {
+  // Get the result type of the getelementptr!
+  const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), IdxList,
+                                                     true);
+  assert(Ty && "GEP indices invalid!");
   return getGetElementPtrTy(PointerType::get(Ty), C, IdxList);
 }
 
@@ -1334,3 +1453,29 @@ const char *ConstantExpr::getOpcodeName() const {
   return Instruction::getOpcodeName(getOpcode());
 }
 
+/// clearAllValueMaps - This method frees all internal memory used by the
+/// constant subsystem, which can be used in environments where this memory
+/// is otherwise reported as a leak.
+void Constant::clearAllValueMaps() {
+  std::vector<Constant *> Constants;
+
+  DoubleConstants.clear(Constants);
+  FloatConstants.clear(Constants);
+  SIntConstants.clear(Constants);
+  UIntConstants.clear(Constants);
+  AggZeroConstants.clear(Constants);
+  ArrayConstants.clear(Constants);
+  StructConstants.clear(Constants);
+  PackedConstants.clear(Constants);
+  NullPtrConstants.clear(Constants);
+  UndefValueConstants.clear(Constants);
+  ExprConstants.clear(Constants);
+
+  for (std::vector<Constant *>::iterator I = Constants.begin(), 
+       E = Constants.end(); I != E; ++I)
+    (*I)->dropAllReferences();
+  for (std::vector<Constant *>::iterator I = Constants.begin(),
+       E = Constants.end(); I != E; ++I)
+    (*I)->destroyConstantImpl();
+  Constants.clear();
+}