237 lines · cpp
1//===- LLVMContextImpl.cpp - Implement LLVMContextImpl --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the opaque LLVMContextImpl.10//11//===----------------------------------------------------------------------===//12 13#include "LLVMContextImpl.h"14#include "AttributeImpl.h"15#include "llvm/ADT/StringMapEntry.h"16#include "llvm/ADT/iterator.h"17#include "llvm/IR/DiagnosticHandler.h"18#include "llvm/IR/LLVMRemarkStreamer.h"19#include "llvm/IR/Module.h"20#include "llvm/IR/OptBisect.h"21#include "llvm/IR/Type.h"22#include "llvm/IR/Use.h"23#include "llvm/IR/User.h"24#include "llvm/Remarks/RemarkStreamer.h"25#include "llvm/Support/Compiler.h"26#include "llvm/Support/ErrorHandling.h"27#include <cassert>28 29using namespace llvm;30 31LLVMContextImpl::LLVMContextImpl(LLVMContext &C)32 : DiagHandler(std::make_unique<DiagnosticHandler>()),33 VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID),34 HalfTy(C, Type::HalfTyID), BFloatTy(C, Type::BFloatTyID),35 FloatTy(C, Type::FloatTyID), DoubleTy(C, Type::DoubleTyID),36 MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID),37 X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),38 PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_AMXTy(C, Type::X86_AMXTyID),39 Int1Ty(C, 1), Int8Ty(C, 8), Int16Ty(C, 16), Int32Ty(C, 32),40 Int64Ty(C, 64), Int128Ty(C, 128) {}41 42LLVMContextImpl::~LLVMContextImpl() {43#ifndef NDEBUG44 // Check that any variable location records that fell off the end of a block45 // when it's terminator was removed were eventually replaced. This assertion46 // firing indicates that DbgVariableRecords went missing during the lifetime47 // of the LLVMContext.48 assert(TrailingDbgRecords.empty() && "DbgRecords in blocks not cleaned");49#endif50 51 // NOTE: We need to delete the contents of OwnedModules, but Module's dtor52 // will call LLVMContextImpl::removeModule, thus invalidating iterators into53 // the container. Avoid iterators during this operation:54 while (!OwnedModules.empty())55 delete *OwnedModules.begin();56 57#ifndef NDEBUG58 // Check for metadata references from leaked Values.59 for (auto &Pair : ValueMetadata)60 Pair.first->dump();61 assert(ValueMetadata.empty() && "Values with metadata have been leaked");62#endif63 64 // Drop references for MDNodes. Do this before Values get deleted to avoid65 // unnecessary RAUW when nodes are still unresolved.66 for (auto *I : DistinctMDNodes)67 I->dropAllReferences();68#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \69 for (auto *I : CLASS##s) \70 I->dropAllReferences();71#include "llvm/IR/Metadata.def"72 73 // Also drop references that come from the Value bridges.74 for (auto &Pair : ValuesAsMetadata)75 Pair.second->dropUsers();76 for (auto &Pair : MetadataAsValues)77 Pair.second->dropUse();78 // Do not untrack ValueAsMetadata references for DIArgLists, as they have79 // already been more efficiently untracked above.80 for (DIArgList *AL : DIArgLists) {81 AL->dropAllReferences(/* Untrack */ false);82 delete AL;83 }84 DIArgLists.clear();85 86 // Destroy MDNodes.87 for (MDNode *I : DistinctMDNodes)88 I->deleteAsSubclass();89 90 for (auto *ConstantRangeListAttribute : ConstantRangeListAttributes)91 ConstantRangeListAttribute->~ConstantRangeListAttributeImpl();92#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \93 for (CLASS * I : CLASS##s) \94 delete I;95#include "llvm/IR/Metadata.def"96 97 // Free the constants.98 for (auto *I : ExprConstants)99 I->dropAllReferences();100 for (auto *I : ArrayConstants)101 I->dropAllReferences();102 for (auto *I : StructConstants)103 I->dropAllReferences();104 for (auto *I : VectorConstants)105 I->dropAllReferences();106 ExprConstants.freeConstants();107 ArrayConstants.freeConstants();108 StructConstants.freeConstants();109 VectorConstants.freeConstants();110 ConstantPtrAuths.freeConstants();111 InlineAsms.freeConstants();112 113 CAZConstants.clear();114 CPNConstants.clear();115 CTNConstants.clear();116 UVConstants.clear();117 PVConstants.clear();118 IntZeroConstants.clear();119 IntOneConstants.clear();120 IntConstants.clear();121 IntSplatConstants.clear();122 FPConstants.clear();123 FPSplatConstants.clear();124 CDSConstants.clear();125 126 // Destroy attribute node lists.127 for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),128 E = AttrsSetNodes.end(); I != E; ) {129 FoldingSetIterator<AttributeSetNode> Elem = I++;130 delete &*Elem;131 }132 133 // Destroy MetadataAsValues.134 {135 SmallVector<MetadataAsValue *, 8> MDVs;136 MDVs.reserve(MetadataAsValues.size());137 for (auto &Pair : MetadataAsValues)138 MDVs.push_back(Pair.second);139 MetadataAsValues.clear();140 for (auto *V : MDVs)141 delete V;142 }143 144 // Destroy ValuesAsMetadata.145 for (auto &Pair : ValuesAsMetadata)146 delete Pair.second;147}148 149namespace llvm {150 151/// Make MDOperand transparent for hashing.152///153/// This overload of an implementation detail of the hashing library makes154/// MDOperand hash to the same value as a \a Metadata pointer.155///156/// Note that overloading \a hash_value() as follows:157///158/// \code159/// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }160/// \endcode161///162/// does not cause MDOperand to be transparent. In particular, a bare pointer163/// doesn't get hashed before it's combined, whereas \a MDOperand would.164static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }165 166} // end namespace llvm167 168unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {169 unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());170#ifndef NDEBUG171 {172 SmallVector<Metadata *, 8> MDs(drop_begin(N->operands(), Offset));173 unsigned RawHash = calculateHash(MDs);174 assert(Hash == RawHash &&175 "Expected hash of MDOperand to equal hash of Metadata*");176 }177#endif178 return Hash;179}180 181unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {182 return hash_combine_range(Ops);183}184 185StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {186 uint32_t NewIdx = BundleTagCache.size();187 return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);188}189 190void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {191 Tags.resize(BundleTagCache.size());192 for (const auto &T : BundleTagCache)193 Tags[T.second] = T.first();194}195 196uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {197 auto I = BundleTagCache.find(Tag);198 assert(I != BundleTagCache.end() && "Unknown tag!");199 return I->second;200}201 202SyncScope::ID LLVMContextImpl::getOrInsertSyncScopeID(StringRef SSN) {203 auto NewSSID = SSC.size();204 assert(NewSSID < std::numeric_limits<SyncScope::ID>::max() &&205 "Hit the maximum number of synchronization scopes allowed!");206 return SSC.insert(std::make_pair(SSN, SyncScope::ID(NewSSID))).first->second;207}208 209void LLVMContextImpl::getSyncScopeNames(210 SmallVectorImpl<StringRef> &SSNs) const {211 SSNs.resize(SSC.size());212 for (const auto &SSE : SSC)213 SSNs[SSE.second] = SSE.first();214}215 216std::optional<StringRef>217LLVMContextImpl::getSyncScopeName(SyncScope::ID Id) const {218 for (const auto &SSE : SSC) {219 if (SSE.second != Id)220 continue;221 return SSE.first();222 }223 return std::nullopt;224}225 226/// Gets the OptPassGate for this LLVMContextImpl, which defaults to the227/// singleton OptBisect if not explicitly set.228OptPassGate &LLVMContextImpl::getOptPassGate() const {229 if (!OPG)230 OPG = &getGlobalPassGate();231 return *OPG;232}233 234void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) {235 this->OPG = &OPG;236}237