brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · 10aba75 Raw
392 lines · cpp
1//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//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 LLVMContext, as a wrapper around the opaque10//  class LLVMContextImpl.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/IR/LLVMContext.h"15#include "LLVMContextImpl.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/StringMap.h"18#include "llvm/ADT/StringRef.h"19#include "llvm/ADT/Twine.h"20#include "llvm/IR/DiagnosticInfo.h"21#include "llvm/IR/DiagnosticPrinter.h"22#include "llvm/IR/LLVMRemarkStreamer.h"23#include "llvm/Remarks/RemarkStreamer.h"24#include "llvm/Support/Casting.h"25#include "llvm/Support/ErrorHandling.h"26#include "llvm/Support/raw_ostream.h"27#include <cassert>28#include <cstdlib>29#include <string>30#include <utility>31 32using namespace llvm;33 34static StringRef knownBundleName(unsigned BundleTagID) {35  switch (BundleTagID) {36  case LLVMContext::OB_deopt:37    return "deopt";38  case LLVMContext::OB_funclet:39    return "funclet";40  case LLVMContext::OB_gc_transition:41    return "gc-transition";42  case LLVMContext::OB_cfguardtarget:43    return "cfguardtarget";44  case LLVMContext::OB_preallocated:45    return "preallocated";46  case LLVMContext::OB_gc_live:47    return "gc-live";48  case LLVMContext::OB_clang_arc_attachedcall:49    return "clang.arc.attachedcall";50  case LLVMContext::OB_ptrauth:51    return "ptrauth";52  case LLVMContext::OB_kcfi:53    return "kcfi";54  case LLVMContext::OB_convergencectrl:55    return "convergencectrl";56  case LLVMContext::OB_align:57    return "align";58  case LLVMContext::OB_deactivation_symbol:59    return "deactivation-symbol";60  default:61    llvm_unreachable("unknown bundle id");62  }63 64  llvm_unreachable("covered switch");65}66 67LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {68  // Create the fixed metadata kinds. This is done in the same order as the69  // MD_* enum values so that they correspond.70  std::pair<unsigned, StringRef> MDKinds[] = {71#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},72#include "llvm/IR/FixedMetadataKinds.def"73#undef LLVM_FIXED_MD_KIND74  };75 76  for (auto &MDKind : MDKinds) {77    unsigned ID = getMDKindID(MDKind.second);78    assert(ID == MDKind.first && "metadata kind id drifted");79    (void)ID;80  }81 82  for (unsigned BundleTagID = LLVMContext::OB_deopt;83       BundleTagID <= LLVMContext::OB_LastBundleID; ++BundleTagID) {84    [[maybe_unused]] const auto *Entry =85        pImpl->getOrInsertBundleTag(knownBundleName(BundleTagID));86    assert(Entry->second == BundleTagID && "operand bundle id drifted!");87  }88 89  SyncScope::ID SingleThreadSSID =90      pImpl->getOrInsertSyncScopeID("singlethread");91  assert(SingleThreadSSID == SyncScope::SingleThread &&92         "singlethread synchronization scope ID drifted!");93  (void)SingleThreadSSID;94 95  SyncScope::ID SystemSSID =96      pImpl->getOrInsertSyncScopeID("");97  assert(SystemSSID == SyncScope::System &&98         "system synchronization scope ID drifted!");99  (void)SystemSSID;100}101 102LLVMContext::~LLVMContext() { delete pImpl; }103 104void LLVMContext::addModule(Module *M) {105  pImpl->OwnedModules.insert(M);106}107 108void LLVMContext::removeModule(Module *M) {109  pImpl->OwnedModules.erase(M);110  pImpl->MachineFunctionNums.erase(M);111}112 113unsigned LLVMContext::generateMachineFunctionNum(Function &F) {114  Module *M = F.getParent();115  assert(pImpl->OwnedModules.contains(M) && "Unexpected module!");116  return pImpl->MachineFunctionNums[M]++;117}118 119//===----------------------------------------------------------------------===//120// Recoverable Backend Errors121//===----------------------------------------------------------------------===//122 123void LLVMContext::setDiagnosticHandlerCallBack(124    DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,125    void *DiagnosticContext, bool RespectFilters) {126  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;127  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;128  pImpl->RespectDiagnosticFilters = RespectFilters;129}130 131void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,132                                      bool RespectFilters) {133  pImpl->DiagHandler = std::move(DH);134  pImpl->RespectDiagnosticFilters = RespectFilters;135}136 137void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {138  pImpl->DiagnosticsHotnessRequested = Requested;139}140bool LLVMContext::getDiagnosticsHotnessRequested() const {141  return pImpl->DiagnosticsHotnessRequested;142}143 144void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) {145  pImpl->DiagnosticsHotnessThreshold = Threshold;146}147void LLVMContext::setMisExpectWarningRequested(bool Requested) {148  pImpl->MisExpectWarningRequested = Requested;149}150bool LLVMContext::getMisExpectWarningRequested() const {151  return pImpl->MisExpectWarningRequested;152}153uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {154  return pImpl->DiagnosticsHotnessThreshold.value_or(UINT64_MAX);155}156void LLVMContext::setDiagnosticsMisExpectTolerance(157    std::optional<uint32_t> Tolerance) {158  pImpl->DiagnosticsMisExpectTolerance = Tolerance;159}160uint32_t LLVMContext::getDiagnosticsMisExpectTolerance() const {161  return pImpl->DiagnosticsMisExpectTolerance.value_or(0);162}163 164bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {165  return !pImpl->DiagnosticsHotnessThreshold.has_value();166}167 168remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {169  return pImpl->MainRemarkStreamer.get();170}171const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {172  return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();173}174void LLVMContext::setMainRemarkStreamer(175    std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {176  pImpl->MainRemarkStreamer = std::move(RemarkStreamer);177}178 179LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {180  return pImpl->LLVMRS.get();181}182const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {183  return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();184}185void LLVMContext::setLLVMRemarkStreamer(186    std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {187  pImpl->LLVMRS = std::move(RemarkStreamer);188}189 190DiagnosticHandler::DiagnosticHandlerTy191LLVMContext::getDiagnosticHandlerCallBack() const {192  return pImpl->DiagHandler->DiagHandlerCallback;193}194 195void *LLVMContext::getDiagnosticContext() const {196  return pImpl->DiagHandler->DiagnosticContext;197}198 199void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)200{201  pImpl->YieldCallback = Callback;202  pImpl->YieldOpaqueHandle = OpaqueHandle;203}204 205void LLVMContext::yield() {206  if (pImpl->YieldCallback)207    pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);208}209 210void LLVMContext::emitError(const Twine &ErrorStr) {211  diagnose(DiagnosticInfoGeneric(ErrorStr));212}213 214void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {215  assert(I && "Invalid instruction");216  diagnose(DiagnosticInfoGeneric(I, ErrorStr));217}218 219static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {220  // Optimization remarks are selective. They need to check whether the regexp221  // pattern, passed via one of the -pass-remarks* flags, matches the name of222  // the pass that is emitting the diagnostic. If there is no match, ignore the223  // diagnostic and return.224  //225  // Also noisy remarks are only enabled if we have hotness information to sort226  // them.227  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))228    return Remark->isEnabled() &&229           (!Remark->isVerbose() || Remark->getHotness());230 231  return true;232}233 234const char *235LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {236  switch (Severity) {237  case DS_Error:238    return "error";239  case DS_Warning:240    return "warning";241  case DS_Remark:242    return "remark";243  case DS_Note:244    return "note";245  }246  llvm_unreachable("Unknown DiagnosticSeverity");247}248 249void LLVMContext::diagnose(const DiagnosticInfo &DI) {250  if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))251    if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())252      RS->emit(*OptDiagBase);253 254  // If there is a report handler, use it.255  if (pImpl->DiagHandler) {256    if (DI.getSeverity() == DS_Error)257      pImpl->DiagHandler->HasErrors = true;258    if ((!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&259        pImpl->DiagHandler->handleDiagnostics(DI))260      return;261  }262 263  if (!isDiagnosticEnabled(DI))264    return;265 266  // Otherwise, print the message with a prefix based on the severity.267  DiagnosticPrinterRawOStream DP(errs());268  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";269  DI.print(DP);270  errs() << "\n";271  if (DI.getSeverity() == DS_Error)272    exit(1);273}274 275//===----------------------------------------------------------------------===//276// Metadata Kind Uniquing277//===----------------------------------------------------------------------===//278 279/// Return a unique non-zero ID for the specified metadata kind.280unsigned LLVMContext::getMDKindID(StringRef Name) const {281  // If this is new, assign it its ID.282  return pImpl->CustomMDKindNames.insert(283                                     std::make_pair(284                                         Name, pImpl->CustomMDKindNames.size()))285      .first->second;286}287 288/// getHandlerNames - Populate client-supplied smallvector using custom289/// metadata name and ID.290void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {291  Names.resize(pImpl->CustomMDKindNames.size());292  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),293       E = pImpl->CustomMDKindNames.end(); I != E; ++I)294    Names[I->second] = I->first();295}296 297void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {298  pImpl->getOperandBundleTags(Tags);299}300 301StringMapEntry<uint32_t> *302LLVMContext::getOrInsertBundleTag(StringRef TagName) const {303  return pImpl->getOrInsertBundleTag(TagName);304}305 306uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {307  return pImpl->getOperandBundleTagID(Tag);308}309 310SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {311  return pImpl->getOrInsertSyncScopeID(SSN);312}313 314void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {315  pImpl->getSyncScopeNames(SSNs);316}317 318std::optional<StringRef> LLVMContext::getSyncScopeName(SyncScope::ID Id) const {319  return pImpl->getSyncScopeName(Id);320}321 322void LLVMContext::setGC(const Function &Fn, std::string GCName) {323  pImpl->GCNames[&Fn] = std::move(GCName);324}325 326const std::string &LLVMContext::getGC(const Function &Fn) {327  return pImpl->GCNames[&Fn];328}329 330void LLVMContext::deleteGC(const Function &Fn) {331  pImpl->GCNames.erase(&Fn);332}333 334bool LLVMContext::shouldDiscardValueNames() const {335  return pImpl->DiscardValueNames;336}337 338bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }339 340void LLVMContext::enableDebugTypeODRUniquing() {341  if (pImpl->DITypeMap)342    return;343 344  pImpl->DITypeMap.emplace();345}346 347void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }348 349void LLVMContext::setDiscardValueNames(bool Discard) {350  pImpl->DiscardValueNames = Discard;351}352 353OptPassGate &LLVMContext::getOptPassGate() const {354  return pImpl->getOptPassGate();355}356 357void LLVMContext::setOptPassGate(OptPassGate& OPG) {358  pImpl->setOptPassGate(OPG);359}360 361const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {362  return pImpl->DiagHandler.get();363}364 365std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {366  return std::move(pImpl->DiagHandler);367}368 369StringRef LLVMContext::getDefaultTargetCPU() {370  return pImpl->DefaultTargetCPU;371}372 373void LLVMContext::setDefaultTargetCPU(StringRef CPU) {374  pImpl->DefaultTargetCPU = CPU;375}376 377StringRef LLVMContext::getDefaultTargetFeatures() {378  return pImpl->DefaultTargetFeatures;379}380 381void LLVMContext::setDefaultTargetFeatures(StringRef Features) {382  pImpl->DefaultTargetFeatures = Features;383}384 385void LLVMContext::updateDILocationAtomGroupWaterline(uint64_t V) {386  pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V);387}388 389uint64_t LLVMContext::incNextDILocationAtomGroup() {390  return pImpl->NextAtomGroup++;391}392