1de6cce22SEugene Zelenko //===- LLVMContextImpl.cpp - Implement LLVMContextImpl --------------------===//
2ef860a24SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef860a24SChandler Carruth //
7ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
8ef860a24SChandler Carruth //
9ef860a24SChandler Carruth //  This file implements the opaque LLVMContextImpl.
10ef860a24SChandler Carruth //
11ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
12ef860a24SChandler Carruth 
13ef860a24SChandler Carruth #include "LLVMContextImpl.h"
14e188aae4Sserge-sans-paille #include "AttributeImpl.h"
1581f385b0SBenjamin Kramer #include "llvm/ADT/SetVector.h"
16e188aae4Sserge-sans-paille #include "llvm/ADT/StringMapEntry.h"
17e188aae4Sserge-sans-paille #include "llvm/ADT/iterator.h"
18e188aae4Sserge-sans-paille #include "llvm/ADT/iterator_range.h"
19e188aae4Sserge-sans-paille #include "llvm/IR/DiagnosticHandler.h"
20e188aae4Sserge-sans-paille #include "llvm/IR/LLVMRemarkStreamer.h"
219fb823bbSChandler Carruth #include "llvm/IR/Module.h"
22aa641a51SAndrew Kaylor #include "llvm/IR/OptBisect.h"
23de6cce22SEugene Zelenko #include "llvm/IR/Type.h"
24e188aae4Sserge-sans-paille #include "llvm/IR/Use.h"
25e188aae4Sserge-sans-paille #include "llvm/IR/User.h"
26e188aae4Sserge-sans-paille #include "llvm/Remarks/RemarkStreamer.h"
274c8174f5SArthur Eubanks #include "llvm/Support/CommandLine.h"
28e188aae4Sserge-sans-paille #include "llvm/Support/Compiler.h"
29e188aae4Sserge-sans-paille #include "llvm/Support/ErrorHandling.h"
30e188aae4Sserge-sans-paille #include "llvm/Support/TypeSize.h"
31de6cce22SEugene Zelenko #include <cassert>
32de6cce22SEugene Zelenko #include <utility>
33de6cce22SEugene Zelenko 
34ef860a24SChandler Carruth using namespace llvm;
35ef860a24SChandler Carruth 
364c8174f5SArthur Eubanks static cl::opt<bool>
3790ec6dffSNikita Popov     OpaquePointersCL("opaque-pointers", cl::desc("Use opaque pointers"),
3841d5033eSNikita Popov                      cl::init(true));
394c8174f5SArthur Eubanks 
LLVMContextImpl(LLVMContext & C)40ef860a24SChandler Carruth LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
410eaee545SJonas Devlieghere     : DiagHandler(std::make_unique<DiagnosticHandler>()),
424c8174f5SArthur Eubanks       VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID),
434c8174f5SArthur Eubanks       HalfTy(C, Type::HalfTyID), BFloatTy(C, Type::BFloatTyID),
444c8174f5SArthur Eubanks       FloatTy(C, Type::FloatTyID), DoubleTy(C, Type::DoubleTyID),
454c8174f5SArthur Eubanks       MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID),
464c8174f5SArthur Eubanks       X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),
474c8174f5SArthur Eubanks       PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
484c8174f5SArthur Eubanks       X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),
492362c4ecSArthur Eubanks       Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {
502362c4ecSArthur Eubanks   if (OpaquePointersCL.getNumOccurrences()) {
512362c4ecSArthur Eubanks     OpaquePointers = OpaquePointersCL;
522362c4ecSArthur Eubanks   }
532362c4ecSArthur Eubanks }
54ef860a24SChandler Carruth 
~LLVMContextImpl()55ef860a24SChandler Carruth LLVMContextImpl::~LLVMContextImpl() {
564c82a809SDavid Blaikie   // NOTE: We need to delete the contents of OwnedModules, but Module's dtor
574c82a809SDavid Blaikie   // will call LLVMContextImpl::removeModule, thus invalidating iterators into
584c82a809SDavid Blaikie   // the container. Avoid iterators during this operation:
594c82a809SDavid Blaikie   while (!OwnedModules.empty())
604c82a809SDavid Blaikie     delete *OwnedModules.begin();
61ef860a24SChandler Carruth 
6269ee62ceSVedant Kumar #ifndef NDEBUG
637975b8c3SSerge Pavlov   // Check for metadata references from leaked Values.
647975b8c3SSerge Pavlov   for (auto &Pair : ValueMetadata)
6569ee62ceSVedant Kumar     Pair.first->dump();
667975b8c3SSerge Pavlov   assert(ValueMetadata.empty() && "Values with metadata have been leaked");
6769ee62ceSVedant Kumar #endif
6869ee62ceSVedant Kumar 
69e16d5875SDuncan P. N. Exon Smith   // Drop references for MDNodes.  Do this before Values get deleted to avoid
70e16d5875SDuncan P. N. Exon Smith   // unnecessary RAUW when nodes are still unresolved.
71badcd585STeresa Johnson   for (auto *I : DistinctMDNodes) {
72badcd585STeresa Johnson     // We may have DIArgList that were uniqued, and as it has a custom
73badcd585STeresa Johnson     // implementation of dropAllReferences, it needs to be explicitly invoked.
74badcd585STeresa Johnson     if (auto *AL = dyn_cast<DIArgList>(I)) {
75badcd585STeresa Johnson       AL->dropAllReferences();
76badcd585STeresa Johnson       continue;
77badcd585STeresa Johnson     }
78e16d5875SDuncan P. N. Exon Smith     I->dropAllReferences();
79badcd585STeresa Johnson   }
8055ca964eSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)                                    \
81408f5a25SDuncan P. N. Exon Smith   for (auto *I : CLASS##s)                                                     \
82e16d5875SDuncan P. N. Exon Smith     I->dropAllReferences();
83408f5a25SDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
84e16d5875SDuncan P. N. Exon Smith 
85e16d5875SDuncan P. N. Exon Smith   // Also drop references that come from the Value bridges.
86e16d5875SDuncan P. N. Exon Smith   for (auto &Pair : ValuesAsMetadata)
87e16d5875SDuncan P. N. Exon Smith     Pair.second->dropUsers();
88e16d5875SDuncan P. N. Exon Smith   for (auto &Pair : MetadataAsValues)
89e16d5875SDuncan P. N. Exon Smith     Pair.second->dropUse();
90e16d5875SDuncan P. N. Exon Smith 
91e16d5875SDuncan P. N. Exon Smith   // Destroy MDNodes.
922bc00f4aSDuncan P. N. Exon Smith   for (MDNode *I : DistinctMDNodes)
93e16d5875SDuncan P. N. Exon Smith     I->deleteAsSubclass();
9455ca964eSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)                                    \
95408f5a25SDuncan P. N. Exon Smith   for (CLASS * I : CLASS##s)                                                   \
96e16d5875SDuncan P. N. Exon Smith     delete I;
97408f5a25SDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
98e16d5875SDuncan P. N. Exon Smith 
99cb36becbSBenjamin Kramer   // Free the constants.
100ef06d445SDuncan P. N. Exon Smith   for (auto *I : ExprConstants)
101ef06d445SDuncan P. N. Exon Smith     I->dropAllReferences();
102ef06d445SDuncan P. N. Exon Smith   for (auto *I : ArrayConstants)
103ef06d445SDuncan P. N. Exon Smith     I->dropAllReferences();
104ef06d445SDuncan P. N. Exon Smith   for (auto *I : StructConstants)
105ef06d445SDuncan P. N. Exon Smith     I->dropAllReferences();
106ef06d445SDuncan P. N. Exon Smith   for (auto *I : VectorConstants)
107ef06d445SDuncan P. N. Exon Smith     I->dropAllReferences();
108ef860a24SChandler Carruth   ExprConstants.freeConstants();
109ef860a24SChandler Carruth   ArrayConstants.freeConstants();
110ef860a24SChandler Carruth   StructConstants.freeConstants();
111ef860a24SChandler Carruth   VectorConstants.freeConstants();
112ef860a24SChandler Carruth   InlineAsms.freeConstants();
113611c5c22SJustin Lebar 
114611c5c22SJustin Lebar   CAZConstants.clear();
115611c5c22SJustin Lebar   CPNConstants.clear();
116611c5c22SJustin Lebar   UVConstants.clear();
117345fcccbSZhengyang Liu   PVConstants.clear();
118611c5c22SJustin Lebar   IntConstants.clear();
119611c5c22SJustin Lebar   FPConstants.clear();
120ef860a24SChandler Carruth   CDSConstants.clear();
121ef860a24SChandler Carruth 
122164a4fbbSBill Wendling   // Destroy attribute node lists.
123164a4fbbSBill Wendling   for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),
124164a4fbbSBill Wendling          E = AttrsSetNodes.end(); I != E; ) {
125164a4fbbSBill Wendling     FoldingSetIterator<AttributeSetNode> Elem = I++;
126164a4fbbSBill Wendling     delete &*Elem;
127164a4fbbSBill Wendling   }
128164a4fbbSBill Wendling 
1295bf8fef5SDuncan P. N. Exon Smith   // Destroy MetadataAsValues.
1305bf8fef5SDuncan P. N. Exon Smith   {
1315bf8fef5SDuncan P. N. Exon Smith     SmallVector<MetadataAsValue *, 8> MDVs;
1325bf8fef5SDuncan P. N. Exon Smith     MDVs.reserve(MetadataAsValues.size());
1335bf8fef5SDuncan P. N. Exon Smith     for (auto &Pair : MetadataAsValues)
1345bf8fef5SDuncan P. N. Exon Smith       MDVs.push_back(Pair.second);
1355bf8fef5SDuncan P. N. Exon Smith     MetadataAsValues.clear();
1365bf8fef5SDuncan P. N. Exon Smith     for (auto *V : MDVs)
1375bf8fef5SDuncan P. N. Exon Smith       delete V;
1385bf8fef5SDuncan P. N. Exon Smith   }
1395bf8fef5SDuncan P. N. Exon Smith 
1405bf8fef5SDuncan P. N. Exon Smith   // Destroy ValuesAsMetadata.
1415bf8fef5SDuncan P. N. Exon Smith   for (auto &Pair : ValuesAsMetadata)
1425bf8fef5SDuncan P. N. Exon Smith     delete Pair.second;
143ef860a24SChandler Carruth }
144ef860a24SChandler Carruth 
dropTriviallyDeadConstantArrays()145dab999d5SManman Ren void LLVMContextImpl::dropTriviallyDeadConstantArrays() {
146aedaa077SJianzhou Zhao   SmallSetVector<ConstantArray *, 4> WorkList;
147aedaa077SJianzhou Zhao 
148aedaa077SJianzhou Zhao   // When ArrayConstants are of substantial size and only a few in them are
149aedaa077SJianzhou Zhao   // dead, starting WorkList with all elements of ArrayConstants can be
150aedaa077SJianzhou Zhao   // wasteful. Instead, starting WorkList with only elements that have empty
151aedaa077SJianzhou Zhao   // uses.
152aedaa077SJianzhou Zhao   for (ConstantArray *C : ArrayConstants)
153aedaa077SJianzhou Zhao     if (C->use_empty())
154aedaa077SJianzhou Zhao       WorkList.insert(C);
155dab999d5SManman Ren 
15681f385b0SBenjamin Kramer   while (!WorkList.empty()) {
15781f385b0SBenjamin Kramer     ConstantArray *C = WorkList.pop_back_val();
158dab999d5SManman Ren     if (C->use_empty()) {
15981f385b0SBenjamin Kramer       for (const Use &Op : C->operands()) {
16081f385b0SBenjamin Kramer         if (auto *COp = dyn_cast<ConstantArray>(Op))
16181f385b0SBenjamin Kramer           WorkList.insert(COp);
16281f385b0SBenjamin Kramer       }
163dab999d5SManman Ren       C->destroyConstant();
164dab999d5SManman Ren     }
165dab999d5SManman Ren   }
166dab999d5SManman Ren }
167dab999d5SManman Ren 
dropTriviallyDeadConstantArrays()168dab999d5SManman Ren void Module::dropTriviallyDeadConstantArrays() {
169dab999d5SManman Ren   Context.pImpl->dropTriviallyDeadConstantArrays();
170dab999d5SManman Ren }
171dab999d5SManman Ren 
17293e983e7SDuncan P. N. Exon Smith namespace llvm {
173de6cce22SEugene Zelenko 
1745f8f34e4SAdrian Prantl /// Make MDOperand transparent for hashing.
17593e983e7SDuncan P. N. Exon Smith ///
17693e983e7SDuncan P. N. Exon Smith /// This overload of an implementation detail of the hashing library makes
17793e983e7SDuncan P. N. Exon Smith /// MDOperand hash to the same value as a \a Metadata pointer.
17893e983e7SDuncan P. N. Exon Smith ///
17993e983e7SDuncan P. N. Exon Smith /// Note that overloading \a hash_value() as follows:
18093e983e7SDuncan P. N. Exon Smith ///
18193e983e7SDuncan P. N. Exon Smith /// \code
18293e983e7SDuncan P. N. Exon Smith ///     size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
18393e983e7SDuncan P. N. Exon Smith /// \endcode
18493e983e7SDuncan P. N. Exon Smith ///
18593e983e7SDuncan P. N. Exon Smith /// does not cause MDOperand to be transparent.  In particular, a bare pointer
18693e983e7SDuncan P. N. Exon Smith /// doesn't get hashed before it's combined, whereas \a MDOperand would.
get_hashable_data(const MDOperand & X)18793e983e7SDuncan P. N. Exon Smith static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
188de6cce22SEugene Zelenko 
189de6cce22SEugene Zelenko } // end namespace llvm
19093e983e7SDuncan P. N. Exon Smith 
calculateHash(MDNode * N,unsigned Offset)191fed199a7SDuncan P. N. Exon Smith unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {
192fed199a7SDuncan P. N. Exon Smith   unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());
19393e983e7SDuncan P. N. Exon Smith #ifndef NDEBUG
19493e983e7SDuncan P. N. Exon Smith   {
19519aacdb7SKazu Hirata     SmallVector<Metadata *, 8> MDs(drop_begin(N->operands(), Offset));
19693e983e7SDuncan P. N. Exon Smith     unsigned RawHash = calculateHash(MDs);
19793e983e7SDuncan P. N. Exon Smith     assert(Hash == RawHash &&
19893e983e7SDuncan P. N. Exon Smith            "Expected hash of MDOperand to equal hash of Metadata*");
19993e983e7SDuncan P. N. Exon Smith   }
20093e983e7SDuncan P. N. Exon Smith #endif
20193e983e7SDuncan P. N. Exon Smith   return Hash;
20293e983e7SDuncan P. N. Exon Smith }
20393e983e7SDuncan P. N. Exon Smith 
calculateHash(ArrayRef<Metadata * > Ops)20493e983e7SDuncan P. N. Exon Smith unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {
20593e983e7SDuncan P. N. Exon Smith   return hash_combine_range(Ops.begin(), Ops.end());
20693e983e7SDuncan P. N. Exon Smith }
20793e983e7SDuncan P. N. Exon Smith 
getOrInsertBundleTag(StringRef Tag)2089303c246SSanjoy Das StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {
2099303c246SSanjoy Das   uint32_t NewIdx = BundleTagCache.size();
2109303c246SSanjoy Das   return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);
2119303c246SSanjoy Das }
2129303c246SSanjoy Das 
getOperandBundleTags(SmallVectorImpl<StringRef> & Tags) const2139303c246SSanjoy Das void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
2149303c246SSanjoy Das   Tags.resize(BundleTagCache.size());
2159303c246SSanjoy Das   for (const auto &T : BundleTagCache)
2169303c246SSanjoy Das     Tags[T.second] = T.first();
2179303c246SSanjoy Das }
2189303c246SSanjoy Das 
getOperandBundleTagID(StringRef Tag) const2199303c246SSanjoy Das uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {
2209303c246SSanjoy Das   auto I = BundleTagCache.find(Tag);
2219303c246SSanjoy Das   assert(I != BundleTagCache.end() && "Unknown tag!");
2229303c246SSanjoy Das   return I->second;
2239303c246SSanjoy Das }
2249303c246SSanjoy Das 
getOrInsertSyncScopeID(StringRef SSN)225bb80d3e1SKonstantin Zhuravlyov SyncScope::ID LLVMContextImpl::getOrInsertSyncScopeID(StringRef SSN) {
226bb80d3e1SKonstantin Zhuravlyov   auto NewSSID = SSC.size();
227bb80d3e1SKonstantin Zhuravlyov   assert(NewSSID < std::numeric_limits<SyncScope::ID>::max() &&
228bb80d3e1SKonstantin Zhuravlyov          "Hit the maximum number of synchronization scopes allowed!");
229bb80d3e1SKonstantin Zhuravlyov   return SSC.insert(std::make_pair(SSN, SyncScope::ID(NewSSID))).first->second;
230bb80d3e1SKonstantin Zhuravlyov }
231bb80d3e1SKonstantin Zhuravlyov 
getSyncScopeNames(SmallVectorImpl<StringRef> & SSNs) const232bb80d3e1SKonstantin Zhuravlyov void LLVMContextImpl::getSyncScopeNames(
233bb80d3e1SKonstantin Zhuravlyov     SmallVectorImpl<StringRef> &SSNs) const {
234bb80d3e1SKonstantin Zhuravlyov   SSNs.resize(SSC.size());
235bb80d3e1SKonstantin Zhuravlyov   for (const auto &SSE : SSC)
236bb80d3e1SKonstantin Zhuravlyov     SSNs[SSE.second] = SSE.first();
237bb80d3e1SKonstantin Zhuravlyov }
238bb80d3e1SKonstantin Zhuravlyov 
23947dbee67SSamuel Eubanks /// Gets the OptPassGate for this LLVMContextImpl, which defaults to the
24047dbee67SSamuel Eubanks /// singleton OptBisect if not explicitly set.
getOptPassGate() const241d29884c7SFedor Sergeev OptPassGate &LLVMContextImpl::getOptPassGate() const {
242d29884c7SFedor Sergeev   if (!OPG)
243ede60037SNicolai Hähnle     OPG = &getOptBisector();
244d29884c7SFedor Sergeev   return *OPG;
245d29884c7SFedor Sergeev }
246d29884c7SFedor Sergeev 
setOptPassGate(OptPassGate & OPG)247d29884c7SFedor Sergeev void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) {
248d29884c7SFedor Sergeev   this->OPG = &OPG;
249aa641a51SAndrew Kaylor }
2501caabbefSVitaly Buka 
hasOpaquePointersValue()2512362c4ecSArthur Eubanks bool LLVMContextImpl::hasOpaquePointersValue() {
252a81b64a1SKazu Hirata   return OpaquePointers.has_value();
2532362c4ecSArthur Eubanks }
2542362c4ecSArthur Eubanks 
getOpaquePointers()2551caabbefSVitaly Buka bool LLVMContextImpl::getOpaquePointers() {
256a7938c74SKazu Hirata   if (LLVM_UNLIKELY(!OpaquePointers))
257cde6003aSNikita Popov     OpaquePointers = OpaquePointersCL;
2581caabbefSVitaly Buka   return *OpaquePointers;
2591caabbefSVitaly Buka }
2601caabbefSVitaly Buka 
setOpaquePointers(bool OP)26146cfbe56SNikita Popov void LLVMContextImpl::setOpaquePointers(bool OP) {
262*611ffcf4SKazu Hirata   assert((!OpaquePointers || OpaquePointers.value() == OP) &&
26346cfbe56SNikita Popov          "Cannot change opaque pointers mode once set");
26446cfbe56SNikita Popov   OpaquePointers = OP;
26546cfbe56SNikita Popov }
266