Path: blob/main/contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.cpp
35234 views
//===- LLVMContextImpl.cpp - Implement LLVMContextImpl --------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the opaque LLVMContextImpl.9//10//===----------------------------------------------------------------------===//1112#include "LLVMContextImpl.h"13#include "AttributeImpl.h"14#include "llvm/ADT/SetVector.h"15#include "llvm/ADT/StringMapEntry.h"16#include "llvm/ADT/iterator.h"17#include "llvm/ADT/iterator_range.h"18#include "llvm/IR/DiagnosticHandler.h"19#include "llvm/IR/LLVMRemarkStreamer.h"20#include "llvm/IR/Module.h"21#include "llvm/IR/OptBisect.h"22#include "llvm/IR/Type.h"23#include "llvm/IR/Use.h"24#include "llvm/IR/User.h"25#include "llvm/Remarks/RemarkStreamer.h"26#include "llvm/Support/CommandLine.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Support/ErrorHandling.h"29#include "llvm/Support/TypeSize.h"30#include <cassert>31#include <utility>3233using namespace llvm;3435LLVMContextImpl::LLVMContextImpl(LLVMContext &C)36: DiagHandler(std::make_unique<DiagnosticHandler>()),37VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID),38HalfTy(C, Type::HalfTyID), BFloatTy(C, Type::BFloatTyID),39FloatTy(C, Type::FloatTyID), DoubleTy(C, Type::DoubleTyID),40MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID),41X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),42PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),43X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),44Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {}4546LLVMContextImpl::~LLVMContextImpl() {47#ifndef NDEBUG48// Check that any variable location records that fell off the end of a block49// when it's terminator was removed were eventually replaced. This assertion50// firing indicates that DbgVariableRecords went missing during the lifetime51// of the LLVMContext.52assert(TrailingDbgRecords.empty() && "DbgRecords in blocks not cleaned");53#endif5455// NOTE: We need to delete the contents of OwnedModules, but Module's dtor56// will call LLVMContextImpl::removeModule, thus invalidating iterators into57// the container. Avoid iterators during this operation:58while (!OwnedModules.empty())59delete *OwnedModules.begin();6061#ifndef NDEBUG62// Check for metadata references from leaked Values.63for (auto &Pair : ValueMetadata)64Pair.first->dump();65assert(ValueMetadata.empty() && "Values with metadata have been leaked");66#endif6768// Drop references for MDNodes. Do this before Values get deleted to avoid69// unnecessary RAUW when nodes are still unresolved.70for (auto *I : DistinctMDNodes)71I->dropAllReferences();72#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \73for (auto *I : CLASS##s) \74I->dropAllReferences();75#include "llvm/IR/Metadata.def"7677// Also drop references that come from the Value bridges.78for (auto &Pair : ValuesAsMetadata)79Pair.second->dropUsers();80for (auto &Pair : MetadataAsValues)81Pair.second->dropUse();82// Do not untrack ValueAsMetadata references for DIArgLists, as they have83// already been more efficiently untracked above.84for (DIArgList *AL : DIArgLists) {85AL->dropAllReferences(/* Untrack */ false);86delete AL;87}88DIArgLists.clear();8990// Destroy MDNodes.91for (MDNode *I : DistinctMDNodes)92I->deleteAsSubclass();9394for (auto *ConstantRangeListAttribute : ConstantRangeListAttributes)95ConstantRangeListAttribute->~ConstantRangeListAttributeImpl();96#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \97for (CLASS * I : CLASS##s) \98delete I;99#include "llvm/IR/Metadata.def"100101// Free the constants.102for (auto *I : ExprConstants)103I->dropAllReferences();104for (auto *I : ArrayConstants)105I->dropAllReferences();106for (auto *I : StructConstants)107I->dropAllReferences();108for (auto *I : VectorConstants)109I->dropAllReferences();110ExprConstants.freeConstants();111ArrayConstants.freeConstants();112StructConstants.freeConstants();113VectorConstants.freeConstants();114InlineAsms.freeConstants();115116CAZConstants.clear();117CPNConstants.clear();118CTNConstants.clear();119UVConstants.clear();120PVConstants.clear();121IntZeroConstants.clear();122IntOneConstants.clear();123IntConstants.clear();124IntSplatConstants.clear();125FPConstants.clear();126FPSplatConstants.clear();127CDSConstants.clear();128129// Destroy attribute node lists.130for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),131E = AttrsSetNodes.end(); I != E; ) {132FoldingSetIterator<AttributeSetNode> Elem = I++;133delete &*Elem;134}135136// Destroy MetadataAsValues.137{138SmallVector<MetadataAsValue *, 8> MDVs;139MDVs.reserve(MetadataAsValues.size());140for (auto &Pair : MetadataAsValues)141MDVs.push_back(Pair.second);142MetadataAsValues.clear();143for (auto *V : MDVs)144delete V;145}146147// Destroy ValuesAsMetadata.148for (auto &Pair : ValuesAsMetadata)149delete Pair.second;150}151152void LLVMContextImpl::dropTriviallyDeadConstantArrays() {153SmallSetVector<ConstantArray *, 4> WorkList;154155// When ArrayConstants are of substantial size and only a few in them are156// dead, starting WorkList with all elements of ArrayConstants can be157// wasteful. Instead, starting WorkList with only elements that have empty158// uses.159for (ConstantArray *C : ArrayConstants)160if (C->use_empty())161WorkList.insert(C);162163while (!WorkList.empty()) {164ConstantArray *C = WorkList.pop_back_val();165if (C->use_empty()) {166for (const Use &Op : C->operands()) {167if (auto *COp = dyn_cast<ConstantArray>(Op))168WorkList.insert(COp);169}170C->destroyConstant();171}172}173}174175void Module::dropTriviallyDeadConstantArrays() {176Context.pImpl->dropTriviallyDeadConstantArrays();177}178179namespace llvm {180181/// Make MDOperand transparent for hashing.182///183/// This overload of an implementation detail of the hashing library makes184/// MDOperand hash to the same value as a \a Metadata pointer.185///186/// Note that overloading \a hash_value() as follows:187///188/// \code189/// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }190/// \endcode191///192/// does not cause MDOperand to be transparent. In particular, a bare pointer193/// doesn't get hashed before it's combined, whereas \a MDOperand would.194static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }195196} // end namespace llvm197198unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {199unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());200#ifndef NDEBUG201{202SmallVector<Metadata *, 8> MDs(drop_begin(N->operands(), Offset));203unsigned RawHash = calculateHash(MDs);204assert(Hash == RawHash &&205"Expected hash of MDOperand to equal hash of Metadata*");206}207#endif208return Hash;209}210211unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {212return hash_combine_range(Ops.begin(), Ops.end());213}214215StringMapEntry<uint32_t> *LLVMContextImpl::getOrInsertBundleTag(StringRef Tag) {216uint32_t NewIdx = BundleTagCache.size();217return &*(BundleTagCache.insert(std::make_pair(Tag, NewIdx)).first);218}219220void LLVMContextImpl::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {221Tags.resize(BundleTagCache.size());222for (const auto &T : BundleTagCache)223Tags[T.second] = T.first();224}225226uint32_t LLVMContextImpl::getOperandBundleTagID(StringRef Tag) const {227auto I = BundleTagCache.find(Tag);228assert(I != BundleTagCache.end() && "Unknown tag!");229return I->second;230}231232SyncScope::ID LLVMContextImpl::getOrInsertSyncScopeID(StringRef SSN) {233auto NewSSID = SSC.size();234assert(NewSSID < std::numeric_limits<SyncScope::ID>::max() &&235"Hit the maximum number of synchronization scopes allowed!");236return SSC.insert(std::make_pair(SSN, SyncScope::ID(NewSSID))).first->second;237}238239void LLVMContextImpl::getSyncScopeNames(240SmallVectorImpl<StringRef> &SSNs) const {241SSNs.resize(SSC.size());242for (const auto &SSE : SSC)243SSNs[SSE.second] = SSE.first();244}245246/// Gets the OptPassGate for this LLVMContextImpl, which defaults to the247/// singleton OptBisect if not explicitly set.248OptPassGate &LLVMContextImpl::getOptPassGate() const {249if (!OPG)250OPG = &getGlobalPassGate();251return *OPG;252}253254void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) {255this->OPG = &OPG;256}257258259