xref: /aosp_15_r20/external/llvm/lib/IR/LLVMContextImpl.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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