1*9880d681SAndroid Build Coastguard Worker //===-- LLVMContextImpl.cpp - Implement LLVMContextImpl -------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the opaque LLVMContextImpl.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "LLVMContextImpl.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Attributes.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/OptBisect.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
21*9880d681SAndroid Build Coastguard Worker #include <algorithm>
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker
LLVMContextImpl(LLVMContext & C)24*9880d681SAndroid Build Coastguard Worker LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
25*9880d681SAndroid Build Coastguard Worker : TheTrueVal(nullptr), TheFalseVal(nullptr),
26*9880d681SAndroid Build Coastguard Worker VoidTy(C, Type::VoidTyID),
27*9880d681SAndroid Build Coastguard Worker LabelTy(C, Type::LabelTyID),
28*9880d681SAndroid Build Coastguard Worker HalfTy(C, Type::HalfTyID),
29*9880d681SAndroid Build Coastguard Worker FloatTy(C, Type::FloatTyID),
30*9880d681SAndroid Build Coastguard Worker DoubleTy(C, Type::DoubleTyID),
31*9880d681SAndroid Build Coastguard Worker MetadataTy(C, Type::MetadataTyID),
32*9880d681SAndroid Build Coastguard Worker TokenTy(C, Type::TokenTyID),
33*9880d681SAndroid Build Coastguard Worker X86_FP80Ty(C, Type::X86_FP80TyID),
34*9880d681SAndroid Build Coastguard Worker FP128Ty(C, Type::FP128TyID),
35*9880d681SAndroid Build Coastguard Worker PPC_FP128Ty(C, Type::PPC_FP128TyID),
36*9880d681SAndroid Build Coastguard Worker X86_MMXTy(C, Type::X86_MMXTyID),
37*9880d681SAndroid Build Coastguard Worker Int1Ty(C, 1),
38*9880d681SAndroid Build Coastguard Worker Int8Ty(C, 8),
39*9880d681SAndroid Build Coastguard Worker Int16Ty(C, 16),
40*9880d681SAndroid Build Coastguard Worker Int32Ty(C, 32),
41*9880d681SAndroid Build Coastguard Worker Int64Ty(C, 64),
42*9880d681SAndroid Build Coastguard Worker Int128Ty(C, 128) {
43*9880d681SAndroid Build Coastguard Worker InlineAsmDiagHandler = nullptr;
44*9880d681SAndroid Build Coastguard Worker InlineAsmDiagContext = nullptr;
45*9880d681SAndroid Build Coastguard Worker DiagnosticHandler = nullptr;
46*9880d681SAndroid Build Coastguard Worker DiagnosticContext = nullptr;
47*9880d681SAndroid Build Coastguard Worker RespectDiagnosticFilters = false;
48*9880d681SAndroid Build Coastguard Worker YieldCallback = nullptr;
49*9880d681SAndroid Build Coastguard Worker YieldOpaqueHandle = nullptr;
50*9880d681SAndroid Build Coastguard Worker NamedStructTypesUniqueID = 0;
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
~LLVMContextImpl()53*9880d681SAndroid Build Coastguard Worker LLVMContextImpl::~LLVMContextImpl() {
54*9880d681SAndroid Build Coastguard Worker // NOTE: We need to delete the contents of OwnedModules, but Module's dtor
55*9880d681SAndroid Build Coastguard Worker // will call LLVMContextImpl::removeModule, thus invalidating iterators into
56*9880d681SAndroid Build Coastguard Worker // the container. Avoid iterators during this operation:
57*9880d681SAndroid Build Coastguard Worker while (!OwnedModules.empty())
58*9880d681SAndroid Build Coastguard Worker delete *OwnedModules.begin();
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker // Drop references for MDNodes. Do this before Values get deleted to avoid
61*9880d681SAndroid Build Coastguard Worker // unnecessary RAUW when nodes are still unresolved.
62*9880d681SAndroid Build Coastguard Worker for (auto *I : DistinctMDNodes)
63*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
64*9880d681SAndroid Build Coastguard Worker #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
65*9880d681SAndroid Build Coastguard Worker for (auto *I : CLASS##s) \
66*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
67*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Metadata.def"
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker // Also drop references that come from the Value bridges.
70*9880d681SAndroid Build Coastguard Worker for (auto &Pair : ValuesAsMetadata)
71*9880d681SAndroid Build Coastguard Worker Pair.second->dropUsers();
72*9880d681SAndroid Build Coastguard Worker for (auto &Pair : MetadataAsValues)
73*9880d681SAndroid Build Coastguard Worker Pair.second->dropUse();
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker // Destroy MDNodes.
76*9880d681SAndroid Build Coastguard Worker for (MDNode *I : DistinctMDNodes)
77*9880d681SAndroid Build Coastguard Worker I->deleteAsSubclass();
78*9880d681SAndroid Build Coastguard Worker #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
79*9880d681SAndroid Build Coastguard Worker for (CLASS * I : CLASS##s) \
80*9880d681SAndroid Build Coastguard Worker delete I;
81*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Metadata.def"
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker // Free the constants.
84*9880d681SAndroid Build Coastguard Worker for (auto *I : ExprConstants)
85*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
86*9880d681SAndroid Build Coastguard Worker for (auto *I : ArrayConstants)
87*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
88*9880d681SAndroid Build Coastguard Worker for (auto *I : StructConstants)
89*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
90*9880d681SAndroid Build Coastguard Worker for (auto *I : VectorConstants)
91*9880d681SAndroid Build Coastguard Worker I->dropAllReferences();
92*9880d681SAndroid Build Coastguard Worker ExprConstants.freeConstants();
93*9880d681SAndroid Build Coastguard Worker ArrayConstants.freeConstants();
94*9880d681SAndroid Build Coastguard Worker StructConstants.freeConstants();
95*9880d681SAndroid Build Coastguard Worker VectorConstants.freeConstants();
96*9880d681SAndroid Build Coastguard Worker DeleteContainerSeconds(CAZConstants);
97*9880d681SAndroid Build Coastguard Worker DeleteContainerSeconds(CPNConstants);
98*9880d681SAndroid Build Coastguard Worker DeleteContainerSeconds(UVConstants);
99*9880d681SAndroid Build Coastguard Worker InlineAsms.freeConstants();
100*9880d681SAndroid Build Coastguard Worker DeleteContainerSeconds(IntConstants);
101*9880d681SAndroid Build Coastguard Worker DeleteContainerSeconds(FPConstants);
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker for (auto &CDSConstant : CDSConstants)
104*9880d681SAndroid Build Coastguard Worker delete CDSConstant.second;
105*9880d681SAndroid Build Coastguard Worker CDSConstants.clear();
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker // Destroy attributes.
108*9880d681SAndroid Build Coastguard Worker for (FoldingSetIterator<AttributeImpl> I = AttrsSet.begin(),
109*9880d681SAndroid Build Coastguard Worker E = AttrsSet.end(); I != E; ) {
110*9880d681SAndroid Build Coastguard Worker FoldingSetIterator<AttributeImpl> Elem = I++;
111*9880d681SAndroid Build Coastguard Worker delete &*Elem;
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker // Destroy attribute lists.
115*9880d681SAndroid Build Coastguard Worker for (FoldingSetIterator<AttributeSetImpl> I = AttrsLists.begin(),
116*9880d681SAndroid Build Coastguard Worker E = AttrsLists.end(); I != E; ) {
117*9880d681SAndroid Build Coastguard Worker FoldingSetIterator<AttributeSetImpl> Elem = I++;
118*9880d681SAndroid Build Coastguard Worker delete &*Elem;
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker // Destroy attribute node lists.
122*9880d681SAndroid Build Coastguard Worker for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),
123*9880d681SAndroid Build Coastguard Worker E = AttrsSetNodes.end(); I != E; ) {
124*9880d681SAndroid Build Coastguard Worker FoldingSetIterator<AttributeSetNode> Elem = I++;
125*9880d681SAndroid Build Coastguard Worker delete &*Elem;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker // Destroy MetadataAsValues.
129*9880d681SAndroid Build Coastguard Worker {
130*9880d681SAndroid Build Coastguard Worker SmallVector<MetadataAsValue *, 8> MDVs;
131*9880d681SAndroid Build Coastguard Worker MDVs.reserve(MetadataAsValues.size());
132*9880d681SAndroid Build Coastguard Worker for (auto &Pair : MetadataAsValues)
133*9880d681SAndroid Build Coastguard Worker MDVs.push_back(Pair.second);
134*9880d681SAndroid Build Coastguard Worker MetadataAsValues.clear();
135*9880d681SAndroid Build Coastguard Worker for (auto *V : MDVs)
136*9880d681SAndroid Build Coastguard Worker delete V;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker // Destroy ValuesAsMetadata.
140*9880d681SAndroid Build Coastguard Worker for (auto &Pair : ValuesAsMetadata)
141*9880d681SAndroid Build Coastguard Worker delete Pair.second;
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker
dropTriviallyDeadConstantArrays()144*9880d681SAndroid Build Coastguard Worker void LLVMContextImpl::dropTriviallyDeadConstantArrays() {
145*9880d681SAndroid Build Coastguard Worker bool Changed;
146*9880d681SAndroid Build Coastguard Worker do {
147*9880d681SAndroid Build Coastguard Worker Changed = false;
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker for (auto I = ArrayConstants.begin(), E = ArrayConstants.end(); I != E;) {
150*9880d681SAndroid Build Coastguard Worker auto *C = *I++;
151*9880d681SAndroid Build Coastguard Worker if (C->use_empty()) {
152*9880d681SAndroid Build Coastguard Worker Changed = true;
153*9880d681SAndroid Build Coastguard Worker C->destroyConstant();
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker } while (Changed);
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker
dropTriviallyDeadConstantArrays()160*9880d681SAndroid Build Coastguard Worker void Module::dropTriviallyDeadConstantArrays() {
161*9880d681SAndroid Build Coastguard Worker Context.pImpl->dropTriviallyDeadConstantArrays();
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker namespace llvm {
165*9880d681SAndroid Build Coastguard Worker /// \brief Make MDOperand transparent for hashing.
166*9880d681SAndroid Build Coastguard Worker ///
167*9880d681SAndroid Build Coastguard Worker /// This overload of an implementation detail of the hashing library makes
168*9880d681SAndroid Build Coastguard Worker /// MDOperand hash to the same value as a \a Metadata pointer.
169*9880d681SAndroid Build Coastguard Worker ///
170*9880d681SAndroid Build Coastguard Worker /// Note that overloading \a hash_value() as follows:
171*9880d681SAndroid Build Coastguard Worker ///
172*9880d681SAndroid Build Coastguard Worker /// \code
173*9880d681SAndroid Build Coastguard Worker /// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
174*9880d681SAndroid Build Coastguard Worker /// \endcode
175*9880d681SAndroid Build Coastguard Worker ///
176*9880d681SAndroid Build Coastguard Worker /// does not cause MDOperand to be transparent. In particular, a bare pointer
177*9880d681SAndroid Build Coastguard Worker /// doesn't get hashed before it's combined, whereas \a MDOperand would.
get_hashable_data(const MDOperand & X)178*9880d681SAndroid Build Coastguard Worker static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker
calculateHash(MDNode * N,unsigned Offset)181*9880d681SAndroid Build Coastguard Worker unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {
182*9880d681SAndroid Build Coastguard Worker unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());
183*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
184*9880d681SAndroid Build Coastguard Worker {
185*9880d681SAndroid Build Coastguard Worker SmallVector<Metadata *, 8> MDs(N->op_begin() + Offset, N->op_end());
186*9880d681SAndroid Build Coastguard Worker unsigned RawHash = calculateHash(MDs);
187*9880d681SAndroid Build Coastguard Worker assert(Hash == RawHash &&
188*9880d681SAndroid Build Coastguard Worker "Expected hash of MDOperand to equal hash of Metadata*");
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker #endif
191*9880d681SAndroid Build Coastguard Worker return Hash;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
calculateHash(ArrayRef<Metadata * > Ops)194*9880d681SAndroid Build Coastguard Worker unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {
195*9880d681SAndroid Build Coastguard Worker return hash_combine_range(Ops.begin(), Ops.end());
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker
getOrInsertBundleTag(StringRef Tag)198*9880d681SAndroid Build Coastguard Worker StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {
199*9880d681SAndroid Build Coastguard Worker uint32_t NewIdx = BundleTagCache.size();
200*9880d681SAndroid Build Coastguard Worker return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
getOperandBundleTags(SmallVectorImpl<StringRef> & Tags) const203*9880d681SAndroid Build Coastguard Worker void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
204*9880d681SAndroid Build Coastguard Worker Tags.resize(BundleTagCache.size());
205*9880d681SAndroid Build Coastguard Worker for (const auto &T : BundleTagCache)
206*9880d681SAndroid Build Coastguard Worker Tags[T.second] = T.first();
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
getOperandBundleTagID(StringRef Tag) const209*9880d681SAndroid Build Coastguard Worker uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {
210*9880d681SAndroid Build Coastguard Worker auto I = BundleTagCache.find(Tag);
211*9880d681SAndroid Build Coastguard Worker assert(I != BundleTagCache.end() && "Unknown tag!");
212*9880d681SAndroid Build Coastguard Worker return I->second;
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker // ConstantsContext anchors
anchor()216*9880d681SAndroid Build Coastguard Worker void UnaryConstantExpr::anchor() { }
217*9880d681SAndroid Build Coastguard Worker
anchor()218*9880d681SAndroid Build Coastguard Worker void BinaryConstantExpr::anchor() { }
219*9880d681SAndroid Build Coastguard Worker
anchor()220*9880d681SAndroid Build Coastguard Worker void SelectConstantExpr::anchor() { }
221*9880d681SAndroid Build Coastguard Worker
anchor()222*9880d681SAndroid Build Coastguard Worker void ExtractElementConstantExpr::anchor() { }
223*9880d681SAndroid Build Coastguard Worker
anchor()224*9880d681SAndroid Build Coastguard Worker void InsertElementConstantExpr::anchor() { }
225*9880d681SAndroid Build Coastguard Worker
anchor()226*9880d681SAndroid Build Coastguard Worker void ShuffleVectorConstantExpr::anchor() { }
227*9880d681SAndroid Build Coastguard Worker
anchor()228*9880d681SAndroid Build Coastguard Worker void ExtractValueConstantExpr::anchor() { }
229*9880d681SAndroid Build Coastguard Worker
anchor()230*9880d681SAndroid Build Coastguard Worker void InsertValueConstantExpr::anchor() { }
231*9880d681SAndroid Build Coastguard Worker
anchor()232*9880d681SAndroid Build Coastguard Worker void GetElementPtrConstantExpr::anchor() { }
233*9880d681SAndroid Build Coastguard Worker
anchor()234*9880d681SAndroid Build Coastguard Worker void CompareConstantExpr::anchor() { }
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker /// Singleton instance of the OptBisect class.
237*9880d681SAndroid Build Coastguard Worker ///
238*9880d681SAndroid Build Coastguard Worker /// This singleton is accessed via the LLVMContext::getOptBisect() function. It
239*9880d681SAndroid Build Coastguard Worker /// provides a mechanism to disable passes and individual optimizations at
240*9880d681SAndroid Build Coastguard Worker /// compile time based on a command line option (-opt-bisect-limit) in order to
241*9880d681SAndroid Build Coastguard Worker /// perform a bisecting search for optimization-related problems.
242*9880d681SAndroid Build Coastguard Worker ///
243*9880d681SAndroid Build Coastguard Worker /// Even if multiple LLVMContext objects are created, they will all return the
244*9880d681SAndroid Build Coastguard Worker /// same instance of OptBisect in order to provide a single bisect count. Any
245*9880d681SAndroid Build Coastguard Worker /// code that uses the OptBisect object should be serialized when bisection is
246*9880d681SAndroid Build Coastguard Worker /// enabled in order to enable a consistent bisect count.
247*9880d681SAndroid Build Coastguard Worker static ManagedStatic<OptBisect> OptBisector;
248*9880d681SAndroid Build Coastguard Worker
getOptBisect()249*9880d681SAndroid Build Coastguard Worker OptBisect &LLVMContextImpl::getOptBisect() {
250*9880d681SAndroid Build Coastguard Worker return *OptBisector;
251*9880d681SAndroid Build Coastguard Worker }
252