72e415cd66b66fbd1f40097312845df70fd493f9
[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(ConstantVector *CP) {
25   std::vector<Constant*> Elements;
26   Elements.reserve(CP->getNumOperands());
27   for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
28     Elements.push_back(CP->getOperand(i));
29   return Elements;
30 }
31
32
33 LLVMContextImpl::LLVMContextImpl(LLVMContext &C) :
34     Context(C), TheTrueVal(0), TheFalseVal(0) { }
35
36 MDString *LLVMContextImpl::getMDString(const char *StrBegin,
37                                        unsigned StrLength) {
38   sys::SmartScopedWriter<true> Writer(ConstantsLock);
39   StringMapEntry<MDString *> &Entry = 
40     MDStringCache.GetOrCreateValue(StringRef(StrBegin, StrLength));
41   MDString *&S = Entry.getValue();
42   if (!S) S = new MDString(Entry.getKeyData(),
43                            Entry.getKeyLength());
44
45   return S;
46 }
47
48 MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) {
49   FoldingSetNodeID ID;
50   for (unsigned i = 0; i != NumVals; ++i)
51     ID.AddPointer(Vals[i]);
52
53   ConstantsLock.reader_acquire();
54   void *InsertPoint;
55   MDNode *N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
56   ConstantsLock.reader_release();
57   
58   if (!N) {
59     sys::SmartScopedWriter<true> Writer(ConstantsLock);
60     N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
61     if (!N) {
62       // InsertPoint will have been set by the FindNodeOrInsertPos call.
63       N = new MDNode(Vals, NumVals);
64       MDNodeSet.InsertNode(N, InsertPoint);
65     }
66   }
67
68   return N;
69 }
70
71 ConstantAggregateZero*
72 LLVMContextImpl::getConstantAggregateZero(const Type *Ty) {
73   assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
74          "Cannot create an aggregate zero of non-aggregate type!");
75
76   // Implicitly locked.
77   return AggZeroConstants.getOrCreate(Ty, 0);
78 }
79
80 Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty,
81                               const std::vector<Constant*> &V) {
82   assert(!V.empty() && "Vectors can't be empty");
83   // If this is an all-undef or alll-zero vector, return a
84   // ConstantAggregateZero or UndefValue.
85   Constant *C = V[0];
86   bool isZero = C->isNullValue();
87   bool isUndef = isa<UndefValue>(C);
88
89   if (isZero || isUndef) {
90     for (unsigned i = 1, e = V.size(); i != e; ++i)
91       if (V[i] != C) {
92         isZero = isUndef = false;
93         break;
94       }
95   }
96   
97   if (isZero)
98     return Context.getConstantAggregateZero(Ty);
99   if (isUndef)
100     return Context.getUndef(Ty);
101     
102   // Implicitly locked.
103   return VectorConstants.getOrCreate(Ty, V);
104 }
105
106 // *** erase methods ***
107
108 void LLVMContextImpl::erase(MDString *M) {
109   sys::SmartScopedWriter<true> Writer(ConstantsLock);
110   MDStringCache.erase(MDStringCache.find(M->getString()));
111 }
112
113 void LLVMContextImpl::erase(MDNode *M) {
114   sys::SmartScopedWriter<true> Writer(ConstantsLock);
115   MDNodeSet.RemoveNode(M);
116 }
117
118 void LLVMContextImpl::erase(ConstantAggregateZero *Z) {
119   AggZeroConstants.remove(Z);
120 }
121
122 void LLVMContextImpl::erase(ConstantVector *V) {
123   VectorConstants.remove(V);
124 }