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(ConstantVector *CP) {
33 std::vector<Constant*> Elements;
34 Elements.reserve(CP->getNumOperands());
35 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
36 Elements.push_back(CP->getOperand(i));
41 LLVMContextImpl::LLVMContextImpl(LLVMContext &C) :
42 Context(C), TheTrueVal(0), TheFalseVal(0) { }
44 MDString *LLVMContextImpl::getMDString(const char *StrBegin,
46 sys::SmartScopedWriter<true> Writer(ConstantsLock);
47 StringMapEntry<MDString *> &Entry =
48 MDStringCache.GetOrCreateValue(StringRef(StrBegin, StrLength));
49 MDString *&S = Entry.getValue();
50 if (!S) S = new MDString(Entry.getKeyData(),
51 Entry.getKeyLength());
56 MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) {
58 for (unsigned i = 0; i != NumVals; ++i)
59 ID.AddPointer(Vals[i]);
61 ConstantsLock.reader_acquire();
63 MDNode *N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
64 ConstantsLock.reader_release();
67 sys::SmartScopedWriter<true> Writer(ConstantsLock);
68 N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
70 // InsertPoint will have been set by the FindNodeOrInsertPos call.
71 N = new MDNode(Vals, NumVals);
72 MDNodeSet.InsertNode(N, InsertPoint);
79 ConstantAggregateZero*
80 LLVMContextImpl::getConstantAggregateZero(const Type *Ty) {
81 assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
82 "Cannot create an aggregate zero of non-aggregate type!");
85 return AggZeroConstants.getOrCreate(Ty, 0);
88 Constant *LLVMContextImpl::getConstantArray(const ArrayType *Ty,
89 const std::vector<Constant*> &V) {
90 // If this is an all-zero array, return a ConstantAggregateZero object
93 if (!C->isNullValue()) {
95 return ArrayConstants.getOrCreate(Ty, V);
97 for (unsigned i = 1, e = V.size(); i != e; ++i)
100 return ArrayConstants.getOrCreate(Ty, V);
104 return Context.getConstantAggregateZero(Ty);
107 Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty,
108 const std::vector<Constant*> &V) {
109 assert(!V.empty() && "Vectors can't be empty");
110 // If this is an all-undef or alll-zero vector, return a
111 // ConstantAggregateZero or UndefValue.
113 bool isZero = C->isNullValue();
114 bool isUndef = isa<UndefValue>(C);
116 if (isZero || isUndef) {
117 for (unsigned i = 1, e = V.size(); i != e; ++i)
119 isZero = isUndef = false;
125 return Context.getConstantAggregateZero(Ty);
127 return Context.getUndef(Ty);
129 // Implicitly locked.
130 return VectorConstants.getOrCreate(Ty, V);
133 // *** erase methods ***
135 void LLVMContextImpl::erase(MDString *M) {
136 sys::SmartScopedWriter<true> Writer(ConstantsLock);
137 MDStringCache.erase(MDStringCache.find(M->getString()));
140 void LLVMContextImpl::erase(MDNode *M) {
141 sys::SmartScopedWriter<true> Writer(ConstantsLock);
142 MDNodeSet.RemoveNode(M);
145 void LLVMContextImpl::erase(ConstantAggregateZero *Z) {
146 AggZeroConstants.remove(Z);
149 void LLVMContextImpl::erase(ConstantArray *C) {
150 ArrayConstants.remove(C);
153 void LLVMContextImpl::erase(ConstantVector *V) {
154 VectorConstants.remove(V);
157 // *** RAUW helpers ***
159 Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantArray *CA,
160 Value *From, Value *To, Use *U) {
161 assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
162 Constant *ToC = cast<Constant>(To);
164 std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup;
165 Lookup.first.first = CA->getType();
168 std::vector<Constant*> &Values = Lookup.first.second;
169 Values.reserve(CA->getNumOperands()); // Build replacement array.
171 // Fill values with the modified operands of the constant array. Also,
172 // compute whether this turns into an all-zeros array.
173 bool isAllZeros = false;
174 unsigned NumUpdated = 0;
175 if (!ToC->isNullValue()) {
176 for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
178 Constant *Val = cast<Constant>(O->get());
183 Values.push_back(Val);
187 for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands();
189 Constant *Val = cast<Constant>(O->get());
194 Values.push_back(Val);
195 if (isAllZeros) isAllZeros = Val->isNullValue();
199 Constant *Replacement = 0;
201 Replacement = Context.getConstantAggregateZero(CA->getType());
203 // Check to see if we have this array type already.
204 sys::SmartScopedWriter<true> Writer(ConstantsLock);
206 ArrayConstantsTy::MapTy::iterator I =
207 ArrayConstants.InsertOrGetItem(Lookup, Exists);
210 Replacement = I->second;
212 // Okay, the new shape doesn't exist in the system yet. Instead of
213 // creating a new constant array, inserting it, replaceallusesof'ing the
214 // old with the new, then deleting the old... just update the current one
216 ArrayConstants.MoveConstantToNewSlot(CA, I);
218 // Update to the new value. Optimize for the case when we have a single
219 // operand that we're changing, but handle bulk updates efficiently.
220 if (NumUpdated == 1) {
221 unsigned OperandToUpdate = U - CA->OperandList;
222 assert(CA->getOperand(OperandToUpdate) == From &&
223 "ReplaceAllUsesWith broken!");
224 CA->setOperand(OperandToUpdate, ToC);
226 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
227 if (CA->getOperand(i) == From)
228 CA->setOperand(i, ToC);