diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp b/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp new file mode 100644 index 000000000000..cb13b27aa50f --- /dev/null +++ b/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp @@ -0,0 +1,331 @@ +//===-- 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; + + auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget"); + assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget && + "cfguardtarget operand bundle id drifted!"); + (void)CFGuardTargetEntry; + + 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); +} |