1 //===--------------- LLVMContextImpl.cpp - Implementation ------*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements LLVMContextImpl, the opaque implementation
13 //===----------------------------------------------------------------------===//
15 #include "LLVMContextImpl.h"
16 #include "llvm/Constants.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/LLVMContext.h"
19 #include "llvm/MDNode.h"
22 static char getValType(ConstantAggregateZero *CPZ) { return 0; }
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)));
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)));
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));
49 LLVMContextImpl::LLVMContextImpl(LLVMContext &C) :
50 Context(C), TheTrueVal(0), TheFalseVal(0) { }
52 MDString *LLVMContextImpl::getMDString(const char *StrBegin,
54 sys::SmartScopedWriter<true> Writer(ConstantsLock);
55 StringMapEntry<MDString *> &Entry =
56 MDStringCache.GetOrCreateValue(StringRef(StrBegin, StrLength));
57 MDString *&S = Entry.getValue();
58 if (!S) S = new MDString(Entry.getKeyData(),
59 Entry.getKeyLength());
64 MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) {
66 for (unsigned i = 0; i != NumVals; ++i)
67 ID.AddPointer(Vals[i]);
69 ConstantsLock.reader_acquire();
71 MDNode *N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
72 ConstantsLock.reader_release();
75 sys::SmartScopedWriter<true> Writer(ConstantsLock);
76 N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
78 // InsertPoint will have been set by the FindNodeOrInsertPos call.
79 N = new MDNode(Vals, NumVals);
80 MDNodeSet.InsertNode(N, InsertPoint);
87 ConstantAggregateZero*
88 LLVMContextImpl::getConstantAggregateZero(const Type *Ty) {
89 assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
90 "Cannot create an aggregate zero of non-aggregate type!");
93 return AggZeroConstants.getOrCreate(Ty, 0);
96 Constant *LLVMContextImpl::getConstantArray(const ArrayType *Ty,
97 const std::vector<Constant*> &V) {
98 // If this is an all-zero array, return a ConstantAggregateZero object
101 if (!C->isNullValue()) {
102 // Implicitly locked.
103 return ArrayConstants.getOrCreate(Ty, V);
105 for (unsigned i = 1, e = V.size(); i != e; ++i)
107 // Implicitly locked.
108 return ArrayConstants.getOrCreate(Ty, V);
112 return Context.getConstantAggregateZero(Ty);
115 Constant *LLVMContextImpl::getConstantStruct(const StructType *Ty,
116 const std::vector<Constant*> &V) {
117 // Create a ConstantAggregateZero value if all elements are zeros...
118 for (unsigned i = 0, e = V.size(); i != e; ++i)
119 if (!V[i]->isNullValue())
120 // Implicitly locked.
121 return StructConstants.getOrCreate(Ty, V);
123 return Context.getConstantAggregateZero(Ty);
126 Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty,
127 const std::vector<Constant*> &V) {
128 assert(!V.empty() && "Vectors can't be empty");
129 // If this is an all-undef or alll-zero vector, return a
130 // ConstantAggregateZero or UndefValue.
132 bool isZero = C->isNullValue();
133 bool isUndef = isa<UndefValue>(C);
135 if (isZero || isUndef) {
136 for (unsigned i = 1, e = V.size(); i != e; ++i)
138 isZero = isUndef = false;
144 return Context.getConstantAggregateZero(Ty);
146 return Context.getUndef(Ty);
148 // Implicitly locked.
149 return VectorConstants.getOrCreate(Ty, V);
152 // *** erase methods ***
154 void LLVMContextImpl::erase(MDString *M) {
155 sys::SmartScopedWriter<true> Writer(ConstantsLock);
156 MDStringCache.erase(MDStringCache.find(M->getString()));
159 void LLVMContextImpl::erase(MDNode *M) {
160 sys::SmartScopedWriter<true> Writer(ConstantsLock);
161 MDNodeSet.RemoveNode(M);
164 void LLVMContextImpl::erase(ConstantAggregateZero *Z) {
165 AggZeroConstants.remove(Z);
168 void LLVMContextImpl::erase(ConstantArray *C) {
169 ArrayConstants.remove(C);
172 void LLVMContextImpl::erase(ConstantStruct *S) {
173 StructConstants.remove(S);
176 void LLVMContextImpl::erase(ConstantVector *V) {
177 VectorConstants.remove(V);
180 // *** RAUW helpers ***
182 Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantArray *CA,
183 Value *From, Value *To, Use *U) {
184 assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
185 Constant *ToC = cast<Constant>(To);
187 std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup;
188 Lookup.first.first = CA->getType();
191 std::vector<Constant*> &Values = Lookup.first.second;
192 Values.reserve(CA->getNumOperands()); // Build replacement array.
194 // Fill values with the modified operands of the constant array. Also,
195 // compute whether this turns into an all-zeros array.
196 bool isAllZeros = false;
197 unsigned NumUpdated = 0;
198 if (!ToC->isNullValue()) {
199 for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
201 Constant *Val = cast<Constant>(O->get());
206 Values.push_back(Val);
210 for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
212 Constant *Val = cast<Constant>(O->get());
217 Values.push_back(Val);
218 if (isAllZeros) isAllZeros = Val->isNullValue();
222 Constant *Replacement = 0;
224 Replacement = Context.getConstantAggregateZero(CA->getType());
226 // Check to see if we have this array type already.
227 sys::SmartScopedWriter<true> Writer(ConstantsLock);
229 ArrayConstantsTy::MapTy::iterator I =
230 ArrayConstants.InsertOrGetItem(Lookup, Exists);
233 Replacement = I->second;
235 // Okay, the new shape doesn't exist in the system yet. Instead of
236 // creating a new constant array, inserting it, replaceallusesof'ing the
237 // old with the new, then deleting the old... just update the current one
239 ArrayConstants.MoveConstantToNewSlot(CA, I);
241 // Update to the new value. Optimize for the case when we have a single
242 // operand that we're changing, but handle bulk updates efficiently.
243 if (NumUpdated == 1) {
244 unsigned OperandToUpdate = U - CA->OperandList;
245 assert(CA->getOperand(OperandToUpdate) == From &&
246 "ReplaceAllUsesWith broken!");
247 CA->setOperand(OperandToUpdate, ToC);
249 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
250 if (CA->getOperand(i) == From)
251 CA->setOperand(i, ToC);
260 Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantStruct *CS,
261 Value *From, Value *To, Use *U) {
262 assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
263 Constant *ToC = cast<Constant>(To);
265 unsigned OperandToUpdate = U - CS->OperandList;
266 assert(CS->getOperand(OperandToUpdate) == From &&
267 "ReplaceAllUsesWith broken!");
269 std::pair<StructConstantsTy::MapKey, Constant*> Lookup;
270 Lookup.first.first = CS->getType();
272 std::vector<Constant*> &Values = Lookup.first.second;
273 Values.reserve(CS->getNumOperands()); // Build replacement struct.
276 // Fill values with the modified operands of the constant struct. Also,
277 // compute whether this turns into an all-zeros struct.
278 bool isAllZeros = false;
279 if (!ToC->isNullValue()) {
280 for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands();
282 Values.push_back(cast<Constant>(O->get()));
285 for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands();
287 Constant *Val = cast<Constant>(O->get());
288 Values.push_back(Val);
289 if (isAllZeros) isAllZeros = Val->isNullValue();
292 Values[OperandToUpdate] = ToC;
294 Constant *Replacement = 0;
296 Replacement = Context.getConstantAggregateZero(CS->getType());
298 // Check to see if we have this array type already.
299 sys::SmartScopedWriter<true> Writer(ConstantsLock);
301 StructConstantsTy::MapTy::iterator I =
302 StructConstants.InsertOrGetItem(Lookup, Exists);
305 Replacement = I->second;
307 // Okay, the new shape doesn't exist in the system yet. Instead of
308 // creating a new constant struct, inserting it, replaceallusesof'ing the
309 // old with the new, then deleting the old... just update the current one
311 StructConstants.MoveConstantToNewSlot(CS, I);
313 // Update to the new value.
314 CS->setOperand(OperandToUpdate, ToC);
319 assert(Replacement != CS && "I didn't contain From!");