Revert the ConstantInt constructors back to their 2.5 forms where possible, thanks...
[oota-llvm.git] / lib / VMCore / LLVMContextImpl.cpp
1 //===--------------- LLVMContextImpl.cpp - Implementation ------*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements LLVMContextImpl, the opaque implementation 
11 //  of LLVMContext.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "LLVMContextImpl.h"
16 #include "llvm/Constants.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/LLVMContext.h"
19 #include "llvm/MDNode.h"
20 using namespace llvm;
21
22 static char getValType(ConstantAggregateZero *CPZ) { return 0; }
23
24 static std::vector<Constant*> getValType(ConstantArray *CA) {
25   std::vector<Constant*> Elements;
26   Elements.reserve(CA->getNumOperands());
27   for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
28     Elements.push_back(cast<Constant>(CA->getOperand(i)));
29   return Elements;
30 }
31
32 static std::vector<Constant*> getValType(ConstantStruct *CS) {
33   std::vector<Constant*> Elements;
34   Elements.reserve(CS->getNumOperands());
35   for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i)
36     Elements.push_back(cast<Constant>(CS->getOperand(i)));
37   return Elements;
38 }
39
40 static std::vector<Constant*> getValType(ConstantVector *CP) {
41   std::vector<Constant*> Elements;
42   Elements.reserve(CP->getNumOperands());
43   for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
44     Elements.push_back(CP->getOperand(i));
45   return Elements;
46 }
47
48
49 LLVMContextImpl::LLVMContextImpl(LLVMContext &C) :
50     Context(C), TheTrueVal(0), TheFalseVal(0) { }
51
52
53 ConstantFP *LLVMContextImpl::getConstantFP(const APFloat &V) {
54   DenseMapAPFloatKeyInfo::KeyTy Key(V);
55   
56   ConstantsLock.reader_acquire();
57   ConstantFP *&Slot = FPConstants[Key];
58   ConstantsLock.reader_release();
59     
60   if (!Slot) {
61     sys::SmartScopedWriter<true> Writer(ConstantsLock);
62     ConstantFP *&NewSlot = FPConstants[Key];
63     if (!NewSlot) {
64       const Type *Ty;
65       if (&V.getSemantics() == &APFloat::IEEEsingle)
66         Ty = Type::FloatTy;
67       else if (&V.getSemantics() == &APFloat::IEEEdouble)
68         Ty = Type::DoubleTy;
69       else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
70         Ty = Type::X86_FP80Ty;
71       else if (&V.getSemantics() == &APFloat::IEEEquad)
72         Ty = Type::FP128Ty;
73       else {
74         assert(&V.getSemantics() == &APFloat::PPCDoubleDouble && 
75                "Unknown FP format");
76         Ty = Type::PPC_FP128Ty;
77       }
78       NewSlot = new ConstantFP(Ty, V);
79     }
80     
81     return NewSlot;
82   }
83   
84   return Slot;
85 }
86
87 MDString *LLVMContextImpl::getMDString(const char *StrBegin,
88                                        unsigned StrLength) {
89   sys::SmartScopedWriter<true> Writer(ConstantsLock);
90   StringMapEntry<MDString *> &Entry = 
91     MDStringCache.GetOrCreateValue(StringRef(StrBegin, StrLength));
92   MDString *&S = Entry.getValue();
93   if (!S) S = new MDString(Entry.getKeyData(),
94                            Entry.getKeyLength());
95
96   return S;
97 }
98
99 MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) {
100   FoldingSetNodeID ID;
101   for (unsigned i = 0; i != NumVals; ++i)
102     ID.AddPointer(Vals[i]);
103
104   ConstantsLock.reader_acquire();
105   void *InsertPoint;
106   MDNode *N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
107   ConstantsLock.reader_release();
108   
109   if (!N) {
110     sys::SmartScopedWriter<true> Writer(ConstantsLock);
111     N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
112     if (!N) {
113       // InsertPoint will have been set by the FindNodeOrInsertPos call.
114       N = new MDNode(Vals, NumVals);
115       MDNodeSet.InsertNode(N, InsertPoint);
116     }
117   }
118
119   return N;
120 }
121
122 ConstantAggregateZero*
123 LLVMContextImpl::getConstantAggregateZero(const Type *Ty) {
124   assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
125          "Cannot create an aggregate zero of non-aggregate type!");
126
127   // Implicitly locked.
128   return AggZeroConstants.getOrCreate(Ty, 0);
129 }
130
131 Constant *LLVMContextImpl::getConstantArray(const ArrayType *Ty,
132                              const std::vector<Constant*> &V) {
133   // If this is an all-zero array, return a ConstantAggregateZero object
134   if (!V.empty()) {
135     Constant *C = V[0];
136     if (!C->isNullValue()) {
137       // Implicitly locked.
138       return ArrayConstants.getOrCreate(Ty, V);
139     }
140     for (unsigned i = 1, e = V.size(); i != e; ++i)
141       if (V[i] != C) {
142         // Implicitly locked.
143         return ArrayConstants.getOrCreate(Ty, V);
144       }
145   }
146   
147   return Context.getConstantAggregateZero(Ty);
148 }
149
150 Constant *LLVMContextImpl::getConstantStruct(const StructType *Ty,
151                               const std::vector<Constant*> &V) {
152   // Create a ConstantAggregateZero value if all elements are zeros...
153   for (unsigned i = 0, e = V.size(); i != e; ++i)
154     if (!V[i]->isNullValue())
155       // Implicitly locked.
156       return StructConstants.getOrCreate(Ty, V);
157
158   return Context.getConstantAggregateZero(Ty);
159 }
160
161 Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty,
162                               const std::vector<Constant*> &V) {
163   assert(!V.empty() && "Vectors can't be empty");
164   // If this is an all-undef or alll-zero vector, return a
165   // ConstantAggregateZero or UndefValue.
166   Constant *C = V[0];
167   bool isZero = C->isNullValue();
168   bool isUndef = isa<UndefValue>(C);
169
170   if (isZero || isUndef) {
171     for (unsigned i = 1, e = V.size(); i != e; ++i)
172       if (V[i] != C) {
173         isZero = isUndef = false;
174         break;
175       }
176   }
177   
178   if (isZero)
179     return Context.getConstantAggregateZero(Ty);
180   if (isUndef)
181     return Context.getUndef(Ty);
182     
183   // Implicitly locked.
184   return VectorConstants.getOrCreate(Ty, V);
185 }
186
187 // *** erase methods ***
188
189 void LLVMContextImpl::erase(MDString *M) {
190   sys::SmartScopedWriter<true> Writer(ConstantsLock);
191   MDStringCache.erase(MDStringCache.find(StringRef(M->StrBegin, 
192                                                    M->length())));
193 }
194
195 void LLVMContextImpl::erase(MDNode *M) {
196   sys::SmartScopedWriter<true> Writer(ConstantsLock);
197   MDNodeSet.RemoveNode(M);
198 }
199
200 void LLVMContextImpl::erase(ConstantAggregateZero *Z) {
201   AggZeroConstants.remove(Z);
202 }
203
204 void LLVMContextImpl::erase(ConstantArray *C) {
205   ArrayConstants.remove(C);
206 }
207
208 void LLVMContextImpl::erase(ConstantStruct *S) {
209   StructConstants.remove(S);
210 }
211
212 void LLVMContextImpl::erase(ConstantVector *V) {
213   VectorConstants.remove(V);
214 }
215
216 // *** RAUW helpers ***
217
218 Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantArray *CA,
219                                                Value *From, Value *To, Use *U) {
220   assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
221   Constant *ToC = cast<Constant>(To);
222
223   std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup;
224   Lookup.first.first = CA->getType();
225   Lookup.second = CA;
226
227   std::vector<Constant*> &Values = Lookup.first.second;
228   Values.reserve(CA->getNumOperands());  // Build replacement array.
229
230   // Fill values with the modified operands of the constant array.  Also, 
231   // compute whether this turns into an all-zeros array.
232   bool isAllZeros = false;
233   unsigned NumUpdated = 0;
234   if (!ToC->isNullValue()) {
235     for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
236          O != E; ++O) {
237       Constant *Val = cast<Constant>(O->get());
238       if (Val == From) {
239         Val = ToC;
240         ++NumUpdated;
241       }
242       Values.push_back(Val);
243     }
244   } else {
245     isAllZeros = true;
246     for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
247          O != E; ++O) {
248       Constant *Val = cast<Constant>(O->get());
249       if (Val == From) {
250         Val = ToC;
251         ++NumUpdated;
252       }
253       Values.push_back(Val);
254       if (isAllZeros) isAllZeros = Val->isNullValue();
255     }
256   }
257   
258   Constant *Replacement = 0;
259   if (isAllZeros) {
260     Replacement = Context.getConstantAggregateZero(CA->getType());
261   } else {
262     // Check to see if we have this array type already.
263     sys::SmartScopedWriter<true> Writer(ConstantsLock);
264     bool Exists;
265     ArrayConstantsTy::MapTy::iterator I =
266       ArrayConstants.InsertOrGetItem(Lookup, Exists);
267     
268     if (Exists) {
269       Replacement = I->second;
270     } else {
271       // Okay, the new shape doesn't exist in the system yet.  Instead of
272       // creating a new constant array, inserting it, replaceallusesof'ing the
273       // old with the new, then deleting the old... just update the current one
274       // in place!
275       ArrayConstants.MoveConstantToNewSlot(CA, I);
276       
277       // Update to the new value.  Optimize for the case when we have a single
278       // operand that we're changing, but handle bulk updates efficiently.
279       if (NumUpdated == 1) {
280         unsigned OperandToUpdate = U - CA->OperandList;
281         assert(CA->getOperand(OperandToUpdate) == From &&
282                "ReplaceAllUsesWith broken!");
283         CA->setOperand(OperandToUpdate, ToC);
284       } else {
285         for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
286           if (CA->getOperand(i) == From)
287             CA->setOperand(i, ToC);
288       }
289       return 0;
290     }
291   }
292   
293   return Replacement;
294 }
295
296 Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantStruct *CS,
297                                                Value *From, Value *To, Use *U) {
298   assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
299   Constant *ToC = cast<Constant>(To);
300
301   unsigned OperandToUpdate = U - CS->OperandList;
302   assert(CS->getOperand(OperandToUpdate) == From &&
303          "ReplaceAllUsesWith broken!");
304
305   std::pair<StructConstantsTy::MapKey, Constant*> Lookup;
306   Lookup.first.first = CS->getType();
307   Lookup.second = CS;
308   std::vector<Constant*> &Values = Lookup.first.second;
309   Values.reserve(CS->getNumOperands());  // Build replacement struct.
310   
311   
312   // Fill values with the modified operands of the constant struct.  Also, 
313   // compute whether this turns into an all-zeros struct.
314   bool isAllZeros = false;
315   if (!ToC->isNullValue()) {
316     for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands(); 
317          O != E; ++O)
318       Values.push_back(cast<Constant>(O->get()));
319   } else {
320     isAllZeros = true;
321     for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands(); 
322          O != E; ++O) {
323       Constant *Val = cast<Constant>(O->get());
324       Values.push_back(Val);
325       if (isAllZeros) isAllZeros = Val->isNullValue();
326     }
327   }
328   Values[OperandToUpdate] = ToC;
329   
330   Constant *Replacement = 0;
331   if (isAllZeros) {
332     Replacement = Context.getConstantAggregateZero(CS->getType());
333   } else {
334     // Check to see if we have this array type already.
335     sys::SmartScopedWriter<true> Writer(ConstantsLock);
336     bool Exists;
337     StructConstantsTy::MapTy::iterator I =
338       StructConstants.InsertOrGetItem(Lookup, Exists);
339     
340     if (Exists) {
341       Replacement = I->second;
342     } else {
343       // Okay, the new shape doesn't exist in the system yet.  Instead of
344       // creating a new constant struct, inserting it, replaceallusesof'ing the
345       // old with the new, then deleting the old... just update the current one
346       // in place!
347       StructConstants.MoveConstantToNewSlot(CS, I);
348       
349       // Update to the new value.
350       CS->setOperand(OperandToUpdate, ToC);
351       return 0;
352     }
353   }
354   
355   assert(Replacement != CS && "I didn't contain From!");
356   
357   return Replacement;
358 }