diff options
Diffstat (limited to 'llvm/lib/IR/LLVMContext.cpp')
| -rw-r--r-- | llvm/lib/IR/LLVMContext.cpp | 326 | 
1 files changed, 326 insertions, 0 deletions
| diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp new file mode 100644 index 0000000000000..5e8772186a2a4 --- /dev/null +++ b/llvm/lib/IR/LLVMContext.cpp @@ -0,0 +1,326 @@ +//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +//  This file implements LLVMContext, as a wrapper around the opaque +//  class LLVMContextImpl. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/LLVMContext.h" +#include "LLVMContextImpl.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstdlib> +#include <string> +#include <utility> + +using namespace llvm; + +LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { +  // Create the fixed metadata kinds. This is done in the same order as the +  // MD_* enum values so that they correspond. +  std::pair<unsigned, StringRef> MDKinds[] = { +#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name}, +#include "llvm/IR/FixedMetadataKinds.def" +#undef LLVM_FIXED_MD_KIND +  }; + +  for (auto &MDKind : MDKinds) { +    unsigned ID = getMDKindID(MDKind.second); +    assert(ID == MDKind.first && "metadata kind id drifted"); +    (void)ID; +  } + +  auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); +  assert(DeoptEntry->second == LLVMContext::OB_deopt && +         "deopt operand bundle id drifted!"); +  (void)DeoptEntry; + +  auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); +  assert(FuncletEntry->second == LLVMContext::OB_funclet && +         "funclet operand bundle id drifted!"); +  (void)FuncletEntry; + +  auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); +  assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && +         "gc-transition operand bundle id drifted!"); +  (void)GCTransitionEntry; + +  SyncScope::ID SingleThreadSSID = +      pImpl->getOrInsertSyncScopeID("singlethread"); +  assert(SingleThreadSSID == SyncScope::SingleThread && +         "singlethread synchronization scope ID drifted!"); +  (void)SingleThreadSSID; + +  SyncScope::ID SystemSSID = +      pImpl->getOrInsertSyncScopeID(""); +  assert(SystemSSID == SyncScope::System && +         "system synchronization scope ID drifted!"); +  (void)SystemSSID; +} + +LLVMContext::~LLVMContext() { delete pImpl; } + +void LLVMContext::addModule(Module *M) { +  pImpl->OwnedModules.insert(M); +} + +void LLVMContext::removeModule(Module *M) { +  pImpl->OwnedModules.erase(M); +} + +//===----------------------------------------------------------------------===// +// Recoverable Backend Errors +//===----------------------------------------------------------------------===// + +void LLVMContext:: +setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, +                              void *DiagContext) { +  pImpl->InlineAsmDiagHandler = DiagHandler; +  pImpl->InlineAsmDiagContext = DiagContext; +} + +/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by +/// setInlineAsmDiagnosticHandler. +LLVMContext::InlineAsmDiagHandlerTy +LLVMContext::getInlineAsmDiagnosticHandler() const { +  return pImpl->InlineAsmDiagHandler; +} + +/// getInlineAsmDiagnosticContext - Return the diagnostic context set by +/// setInlineAsmDiagnosticHandler. +void *LLVMContext::getInlineAsmDiagnosticContext() const { +  return pImpl->InlineAsmDiagContext; +} + +void LLVMContext::setDiagnosticHandlerCallBack( +    DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, +    void *DiagnosticContext, bool RespectFilters) { +  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler; +  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext; +  pImpl->RespectDiagnosticFilters = RespectFilters; +} + +void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, +                                      bool RespectFilters) { +  pImpl->DiagHandler = std::move(DH); +  pImpl->RespectDiagnosticFilters = RespectFilters; +} + +void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) { +  pImpl->DiagnosticsHotnessRequested = Requested; +} +bool LLVMContext::getDiagnosticsHotnessRequested() const { +  return pImpl->DiagnosticsHotnessRequested; +} + +void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) { +  pImpl->DiagnosticsHotnessThreshold = Threshold; +} +uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { +  return pImpl->DiagnosticsHotnessThreshold; +} + +RemarkStreamer *LLVMContext::getRemarkStreamer() { +  return pImpl->RemarkDiagStreamer.get(); +} +const RemarkStreamer *LLVMContext::getRemarkStreamer() const { +  return const_cast<LLVMContext *>(this)->getRemarkStreamer(); +} +void LLVMContext::setRemarkStreamer( +    std::unique_ptr<RemarkStreamer> RemarkStreamer) { +  pImpl->RemarkDiagStreamer = std::move(RemarkStreamer); +} + +DiagnosticHandler::DiagnosticHandlerTy +LLVMContext::getDiagnosticHandlerCallBack() const { +  return pImpl->DiagHandler->DiagHandlerCallback; +} + +void *LLVMContext::getDiagnosticContext() const { +  return pImpl->DiagHandler->DiagnosticContext; +} + +void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) +{ +  pImpl->YieldCallback = Callback; +  pImpl->YieldOpaqueHandle = OpaqueHandle; +} + +void LLVMContext::yield() { +  if (pImpl->YieldCallback) +    pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); +} + +void LLVMContext::emitError(const Twine &ErrorStr) { +  diagnose(DiagnosticInfoInlineAsm(ErrorStr)); +} + +void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { +  assert (I && "Invalid instruction"); +  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); +} + +static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { +  // Optimization remarks are selective. They need to check whether the regexp +  // pattern, passed via one of the -pass-remarks* flags, matches the name of +  // the pass that is emitting the diagnostic. If there is no match, ignore the +  // diagnostic and return. +  // +  // Also noisy remarks are only enabled if we have hotness information to sort +  // them. +  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) +    return Remark->isEnabled() && +           (!Remark->isVerbose() || Remark->getHotness()); + +  return true; +} + +const char * +LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { +  switch (Severity) { +  case DS_Error: +    return "error"; +  case DS_Warning: +    return "warning"; +  case DS_Remark: +    return "remark"; +  case DS_Note: +    return "note"; +  } +  llvm_unreachable("Unknown DiagnosticSeverity"); +} + +void LLVMContext::diagnose(const DiagnosticInfo &DI) { +  if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) +    if (RemarkStreamer *RS = getRemarkStreamer()) +      RS->emit(*OptDiagBase); + +  // If there is a report handler, use it. +  if (pImpl->DiagHandler && +      (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && +      pImpl->DiagHandler->handleDiagnostics(DI)) +    return; + +  if (!isDiagnosticEnabled(DI)) +    return; + +  // Otherwise, print the message with a prefix based on the severity. +  DiagnosticPrinterRawOStream DP(errs()); +  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; +  DI.print(DP); +  errs() << "\n"; +  if (DI.getSeverity() == DS_Error) +    exit(1); +} + +void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { +  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); +} + +//===----------------------------------------------------------------------===// +// Metadata Kind Uniquing +//===----------------------------------------------------------------------===// + +/// Return a unique non-zero ID for the specified metadata kind. +unsigned LLVMContext::getMDKindID(StringRef Name) const { +  // If this is new, assign it its ID. +  return pImpl->CustomMDKindNames.insert( +                                     std::make_pair( +                                         Name, pImpl->CustomMDKindNames.size())) +      .first->second; +} + +/// getHandlerNames - Populate client-supplied smallvector using custom +/// metadata name and ID. +void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { +  Names.resize(pImpl->CustomMDKindNames.size()); +  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), +       E = pImpl->CustomMDKindNames.end(); I != E; ++I) +    Names[I->second] = I->first(); +} + +void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { +  pImpl->getOperandBundleTags(Tags); +} + +uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { +  return pImpl->getOperandBundleTagID(Tag); +} + +SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) { +  return pImpl->getOrInsertSyncScopeID(SSN); +} + +void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const { +  pImpl->getSyncScopeNames(SSNs); +} + +void LLVMContext::setGC(const Function &Fn, std::string GCName) { +  auto It = pImpl->GCNames.find(&Fn); + +  if (It == pImpl->GCNames.end()) { +    pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); +    return; +  } +  It->second = std::move(GCName); +} + +const std::string &LLVMContext::getGC(const Function &Fn) { +  return pImpl->GCNames[&Fn]; +} + +void LLVMContext::deleteGC(const Function &Fn) { +  pImpl->GCNames.erase(&Fn); +} + +bool LLVMContext::shouldDiscardValueNames() const { +  return pImpl->DiscardValueNames; +} + +bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } + +void LLVMContext::enableDebugTypeODRUniquing() { +  if (pImpl->DITypeMap) +    return; + +  pImpl->DITypeMap.emplace(); +} + +void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } + +void LLVMContext::setDiscardValueNames(bool Discard) { +  pImpl->DiscardValueNames = Discard; +} + +OptPassGate &LLVMContext::getOptPassGate() const { +  return pImpl->getOptPassGate(); +} + +void LLVMContext::setOptPassGate(OptPassGate& OPG) { +  pImpl->setOptPassGate(OPG); +} + +const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { +  return pImpl->DiagHandler.get(); +} + +std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() { +  return std::move(pImpl->DiagHandler); +} | 
