brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · 8f79398 Raw
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