1ef860a24SChandler Carruth //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===// 2ef860a24SChandler Carruth // 3ef860a24SChandler Carruth // The LLVM Compiler Infrastructure 4ef860a24SChandler Carruth // 5ef860a24SChandler Carruth // This file is distributed under the University of Illinois Open Source 6ef860a24SChandler Carruth // License. See LICENSE.TXT for details. 7ef860a24SChandler Carruth // 8ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 9ef860a24SChandler Carruth // 10ef860a24SChandler Carruth // This file implements LLVMContext, as a wrapper around the opaque 11ef860a24SChandler Carruth // class LLVMContextImpl. 12ef860a24SChandler Carruth // 13ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 14ef860a24SChandler Carruth 159fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 165354a8aaSEugene Zelenko #include "llvm/ADT/SmallVector.h" 175354a8aaSEugene Zelenko #include "llvm/ADT/StringMap.h" 185354a8aaSEugene Zelenko #include "llvm/ADT/StringRef.h" 195354a8aaSEugene Zelenko #include "llvm/ADT/Twine.h" 20ef860a24SChandler Carruth #include "LLVMContextImpl.h" 21b4c44d23SQuentin Colombet #include "llvm/IR/DiagnosticInfo.h" 22b4c44d23SQuentin Colombet #include "llvm/IR/DiagnosticPrinter.h" 239fb823bbSChandler Carruth #include "llvm/IR/Metadata.h" 245354a8aaSEugene Zelenko #include "llvm/IR/Module.h" 255354a8aaSEugene Zelenko #include "llvm/Support/Casting.h" 265354a8aaSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 275354a8aaSEugene Zelenko #include "llvm/Support/raw_ostream.h" 285354a8aaSEugene Zelenko #include <cassert> 295354a8aaSEugene Zelenko #include <cstdlib> 305354a8aaSEugene Zelenko #include <string> 315354a8aaSEugene Zelenko #include <utility> 325354a8aaSEugene Zelenko 33ef860a24SChandler Carruth using namespace llvm; 34ef860a24SChandler Carruth 35ef860a24SChandler Carruth LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { 36ef860a24SChandler Carruth // Create the fixed metadata kinds. This is done in the same order as the 37ef860a24SChandler Carruth // MD_* enum values so that they correspond. 38*6f0b4f2eSPeter Collingbourne std::pair<unsigned, StringRef> MDKinds[] = { 39*6f0b4f2eSPeter Collingbourne {MD_dbg, "dbg"}, 40*6f0b4f2eSPeter Collingbourne {MD_tbaa, "tbaa"}, 41*6f0b4f2eSPeter Collingbourne {MD_prof, "prof"}, 42*6f0b4f2eSPeter Collingbourne {MD_fpmath, "fpmath"}, 43*6f0b4f2eSPeter Collingbourne {MD_range, "range"}, 44*6f0b4f2eSPeter Collingbourne {MD_tbaa_struct, "tbaa.struct"}, 45*6f0b4f2eSPeter Collingbourne {MD_invariant_load, "invariant.load"}, 46*6f0b4f2eSPeter Collingbourne {MD_alias_scope, "alias.scope"}, 47*6f0b4f2eSPeter Collingbourne {MD_noalias, "noalias"}, 48*6f0b4f2eSPeter Collingbourne {MD_nontemporal, "nontemporal"}, 49*6f0b4f2eSPeter Collingbourne {MD_mem_parallel_loop_access, "llvm.mem.parallel_loop_access"}, 50*6f0b4f2eSPeter Collingbourne {MD_nonnull, "nonnull"}, 51*6f0b4f2eSPeter Collingbourne {MD_dereferenceable, "dereferenceable"}, 52*6f0b4f2eSPeter Collingbourne {MD_dereferenceable_or_null, "dereferenceable_or_null"}, 53*6f0b4f2eSPeter Collingbourne {MD_make_implicit, "make.implicit"}, 54*6f0b4f2eSPeter Collingbourne {MD_unpredictable, "unpredictable"}, 55*6f0b4f2eSPeter Collingbourne {MD_invariant_group, "invariant.group"}, 56*6f0b4f2eSPeter Collingbourne {MD_align, "align"}, 57*6f0b4f2eSPeter Collingbourne {MD_loop, "llvm.loop"}, 58*6f0b4f2eSPeter Collingbourne {MD_type, "type"}, 59*6f0b4f2eSPeter Collingbourne {MD_section_prefix, "section_prefix"}, 60*6f0b4f2eSPeter Collingbourne }; 61ef860a24SChandler Carruth 62*6f0b4f2eSPeter Collingbourne for (auto &MDKind : MDKinds) { 63*6f0b4f2eSPeter Collingbourne unsigned ID = getMDKindID(MDKind.second); 64*6f0b4f2eSPeter Collingbourne assert(ID == MDKind.first && "metadata kind id drifted"); 65*6f0b4f2eSPeter Collingbourne (void)ID; 66*6f0b4f2eSPeter Collingbourne } 67302b69c9SDehao Chen 68cdafd849SSanjoy Das auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); 69cdafd849SSanjoy Das assert(DeoptEntry->second == LLVMContext::OB_deopt && 70cdafd849SSanjoy Das "deopt operand bundle id drifted!"); 71cdafd849SSanjoy Das (void)DeoptEntry; 723bb88c02SDavid Majnemer 733bb88c02SDavid Majnemer auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); 743bb88c02SDavid Majnemer assert(FuncletEntry->second == LLVMContext::OB_funclet && 753bb88c02SDavid Majnemer "funclet operand bundle id drifted!"); 763bb88c02SDavid Majnemer (void)FuncletEntry; 77a34ce95bSSanjoy Das 78a34ce95bSSanjoy Das auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); 79a34ce95bSSanjoy Das assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && 80a34ce95bSSanjoy Das "gc-transition operand bundle id drifted!"); 81a34ce95bSSanjoy Das (void)GCTransitionEntry; 82ef860a24SChandler Carruth } 835354a8aaSEugene Zelenko 84ef860a24SChandler Carruth LLVMContext::~LLVMContext() { delete pImpl; } 85ef860a24SChandler Carruth 86ef860a24SChandler Carruth void LLVMContext::addModule(Module *M) { 87ef860a24SChandler Carruth pImpl->OwnedModules.insert(M); 88ef860a24SChandler Carruth } 89ef860a24SChandler Carruth 90ef860a24SChandler Carruth void LLVMContext::removeModule(Module *M) { 91ef860a24SChandler Carruth pImpl->OwnedModules.erase(M); 92ef860a24SChandler Carruth } 93ef860a24SChandler Carruth 94ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 95ef860a24SChandler Carruth // Recoverable Backend Errors 96ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 97ef860a24SChandler Carruth 98a594fab4SBob Wilson void LLVMContext:: 99a594fab4SBob Wilson setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, 100ef860a24SChandler Carruth void *DiagContext) { 101a594fab4SBob Wilson pImpl->InlineAsmDiagHandler = DiagHandler; 102a594fab4SBob Wilson pImpl->InlineAsmDiagContext = DiagContext; 103ef860a24SChandler Carruth } 104ef860a24SChandler Carruth 105a594fab4SBob Wilson /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by 106a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler. 107a594fab4SBob Wilson LLVMContext::InlineAsmDiagHandlerTy 108a594fab4SBob Wilson LLVMContext::getInlineAsmDiagnosticHandler() const { 109a594fab4SBob Wilson return pImpl->InlineAsmDiagHandler; 110ef860a24SChandler Carruth } 111ef860a24SChandler Carruth 112a594fab4SBob Wilson /// getInlineAsmDiagnosticContext - Return the diagnostic context set by 113a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler. 114a594fab4SBob Wilson void *LLVMContext::getInlineAsmDiagnosticContext() const { 115a594fab4SBob Wilson return pImpl->InlineAsmDiagContext; 116ef860a24SChandler Carruth } 117ef860a24SChandler Carruth 118b4c44d23SQuentin Colombet void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, 11930c9242cSDuncan P. N. Exon Smith void *DiagnosticContext, 12030c9242cSDuncan P. N. Exon Smith bool RespectFilters) { 121b4c44d23SQuentin Colombet pImpl->DiagnosticHandler = DiagnosticHandler; 122b4c44d23SQuentin Colombet pImpl->DiagnosticContext = DiagnosticContext; 12330c9242cSDuncan P. N. Exon Smith pImpl->RespectDiagnosticFilters = RespectFilters; 124b4c44d23SQuentin Colombet } 125b4c44d23SQuentin Colombet 126aad81608SAdam Nemet void LLVMContext::setDiagnosticHotnessRequested(bool Requested) { 127aad81608SAdam Nemet pImpl->DiagnosticHotnessRequested = Requested; 128aad81608SAdam Nemet } 129aad81608SAdam Nemet bool LLVMContext::getDiagnosticHotnessRequested() const { 130aad81608SAdam Nemet return pImpl->DiagnosticHotnessRequested; 131aad81608SAdam Nemet } 132aad81608SAdam Nemet 133a62b7e1aSAdam Nemet yaml::Output *LLVMContext::getDiagnosticsOutputFile() { 134a62b7e1aSAdam Nemet return pImpl->DiagnosticsOutputFile.get(); 135a62b7e1aSAdam Nemet } 136a62b7e1aSAdam Nemet 1376f408368SMehdi Amini void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) { 1386f408368SMehdi Amini pImpl->DiagnosticsOutputFile = std::move(F); 139a62b7e1aSAdam Nemet } 140a62b7e1aSAdam Nemet 141b4c44d23SQuentin Colombet LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { 142b4c44d23SQuentin Colombet return pImpl->DiagnosticHandler; 143b4c44d23SQuentin Colombet } 144b4c44d23SQuentin Colombet 145b4c44d23SQuentin Colombet void *LLVMContext::getDiagnosticContext() const { 146b4c44d23SQuentin Colombet return pImpl->DiagnosticContext; 147b4c44d23SQuentin Colombet } 148b4c44d23SQuentin Colombet 14934390c70SJuergen Ributzka void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 15034390c70SJuergen Ributzka { 15134390c70SJuergen Ributzka pImpl->YieldCallback = Callback; 15234390c70SJuergen Ributzka pImpl->YieldOpaqueHandle = OpaqueHandle; 15334390c70SJuergen Ributzka } 15434390c70SJuergen Ributzka 15534390c70SJuergen Ributzka void LLVMContext::yield() { 15634390c70SJuergen Ributzka if (pImpl->YieldCallback) 15734390c70SJuergen Ributzka pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 15834390c70SJuergen Ributzka } 15934390c70SJuergen Ributzka 160ef860a24SChandler Carruth void LLVMContext::emitError(const Twine &ErrorStr) { 161dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 162ef860a24SChandler Carruth } 163ef860a24SChandler Carruth 164bfb44ef9SBob Wilson void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 165dec8d55bSQuentin Colombet assert (I && "Invalid instruction"); 166dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 167ef860a24SChandler Carruth } 168ef860a24SChandler Carruth 16930c9242cSDuncan P. N. Exon Smith static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { 1707f8af8bfSDiego Novillo // Optimization remarks are selective. They need to check whether the regexp 1717f8af8bfSDiego Novillo // pattern, passed via one of the -pass-remarks* flags, matches the name of 1727f8af8bfSDiego Novillo // the pass that is emitting the diagnostic. If there is no match, ignore the 1737f8af8bfSDiego Novillo // diagnostic and return. 174e9148dd6SAkira Hatanaka if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 175e9148dd6SAkira Hatanaka return Remark->isEnabled(); 176e9148dd6SAkira Hatanaka 17730c9242cSDuncan P. N. Exon Smith return true; 17830c9242cSDuncan P. N. Exon Smith } 17930c9242cSDuncan P. N. Exon Smith 1804b9c0d4dSRenato Golin const char * 1814b9c0d4dSRenato Golin LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { 182735c47ecSAlex Lorenz switch (Severity) { 183735c47ecSAlex Lorenz case DS_Error: 184735c47ecSAlex Lorenz return "error"; 185735c47ecSAlex Lorenz case DS_Warning: 186735c47ecSAlex Lorenz return "warning"; 187735c47ecSAlex Lorenz case DS_Remark: 188735c47ecSAlex Lorenz return "remark"; 189735c47ecSAlex Lorenz case DS_Note: 190735c47ecSAlex Lorenz return "note"; 191735c47ecSAlex Lorenz } 1925220476aSAaron Ballman llvm_unreachable("Unknown DiagnosticSeverity"); 193735c47ecSAlex Lorenz } 194735c47ecSAlex Lorenz 19530c9242cSDuncan P. N. Exon Smith void LLVMContext::diagnose(const DiagnosticInfo &DI) { 19630c9242cSDuncan P. N. Exon Smith // If there is a report handler, use it. 19730c9242cSDuncan P. N. Exon Smith if (pImpl->DiagnosticHandler) { 19830c9242cSDuncan P. N. Exon Smith if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) 19930c9242cSDuncan P. N. Exon Smith pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); 20030c9242cSDuncan P. N. Exon Smith return; 20130c9242cSDuncan P. N. Exon Smith } 20230c9242cSDuncan P. N. Exon Smith 20330c9242cSDuncan P. N. Exon Smith if (!isDiagnosticEnabled(DI)) 20430c9242cSDuncan P. N. Exon Smith return; 205df655013SDiego Novillo 206b4c44d23SQuentin Colombet // Otherwise, print the message with a prefix based on the severity. 207735c47ecSAlex Lorenz DiagnosticPrinterRawOStream DP(errs()); 208735c47ecSAlex Lorenz errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 209b4c44d23SQuentin Colombet DI.print(DP); 210735c47ecSAlex Lorenz errs() << "\n"; 211735c47ecSAlex Lorenz if (DI.getSeverity() == DS_Error) 212b4c44d23SQuentin Colombet exit(1); 213b4c44d23SQuentin Colombet } 214b4c44d23SQuentin Colombet 215ef860a24SChandler Carruth void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { 216dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 217ef860a24SChandler Carruth } 218ef860a24SChandler Carruth 219ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 220ef860a24SChandler Carruth // Metadata Kind Uniquing 221ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 222ef860a24SChandler Carruth 2231ac0d2deSFilipe Cabecinhas /// Return a unique non-zero ID for the specified metadata kind. 224ef860a24SChandler Carruth unsigned LLVMContext::getMDKindID(StringRef Name) const { 225ef860a24SChandler Carruth // If this is new, assign it its ID. 2261ac0d2deSFilipe Cabecinhas return pImpl->CustomMDKindNames.insert( 2271ac0d2deSFilipe Cabecinhas std::make_pair( 2281ac0d2deSFilipe Cabecinhas Name, pImpl->CustomMDKindNames.size())) 2295106ce78SDavid Blaikie .first->second; 230ef860a24SChandler Carruth } 231ef860a24SChandler Carruth 2324104337dSSanjay Patel /// getHandlerNames - Populate client-supplied smallvector using custom 233ef860a24SChandler Carruth /// metadata name and ID. 234ef860a24SChandler Carruth void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 235ef860a24SChandler Carruth Names.resize(pImpl->CustomMDKindNames.size()); 236ef860a24SChandler Carruth for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 237ef860a24SChandler Carruth E = pImpl->CustomMDKindNames.end(); I != E; ++I) 238ef860a24SChandler Carruth Names[I->second] = I->first(); 239ef860a24SChandler Carruth } 2409303c246SSanjoy Das 2419303c246SSanjoy Das void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { 2429303c246SSanjoy Das pImpl->getOperandBundleTags(Tags); 2439303c246SSanjoy Das } 2449303c246SSanjoy Das 2459303c246SSanjoy Das uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { 2469303c246SSanjoy Das return pImpl->getOperandBundleTagID(Tag); 2479303c246SSanjoy Das } 248599ebf27SMehdi Amini 249599ebf27SMehdi Amini void LLVMContext::setGC(const Function &Fn, std::string GCName) { 250599ebf27SMehdi Amini auto It = pImpl->GCNames.find(&Fn); 251599ebf27SMehdi Amini 252599ebf27SMehdi Amini if (It == pImpl->GCNames.end()) { 253599ebf27SMehdi Amini pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); 254599ebf27SMehdi Amini return; 255599ebf27SMehdi Amini } 256599ebf27SMehdi Amini It->second = std::move(GCName); 257599ebf27SMehdi Amini } 2585354a8aaSEugene Zelenko 259599ebf27SMehdi Amini const std::string &LLVMContext::getGC(const Function &Fn) { 260599ebf27SMehdi Amini return pImpl->GCNames[&Fn]; 261599ebf27SMehdi Amini } 2625354a8aaSEugene Zelenko 263599ebf27SMehdi Amini void LLVMContext::deleteGC(const Function &Fn) { 264599ebf27SMehdi Amini pImpl->GCNames.erase(&Fn); 265599ebf27SMehdi Amini } 26609b4a8daSMehdi Amini 267e7090155SMehdi Amini bool LLVMContext::shouldDiscardValueNames() const { 268e7090155SMehdi Amini return pImpl->DiscardValueNames; 269e7090155SMehdi Amini } 27009b4a8daSMehdi Amini 271ed8fdb2aSDuncan P. N. Exon Smith bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } 2725ab2be09SDuncan P. N. Exon Smith 273ed8fdb2aSDuncan P. N. Exon Smith void LLVMContext::enableDebugTypeODRUniquing() { 2745ab2be09SDuncan P. N. Exon Smith if (pImpl->DITypeMap) 2755ab2be09SDuncan P. N. Exon Smith return; 2765ab2be09SDuncan P. N. Exon Smith 277e8b555c6SDuncan P. N. Exon Smith pImpl->DITypeMap.emplace(); 2785ab2be09SDuncan P. N. Exon Smith } 2795ab2be09SDuncan P. N. Exon Smith 280ed8fdb2aSDuncan P. N. Exon Smith void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } 2815ab2be09SDuncan P. N. Exon Smith 28209b4a8daSMehdi Amini void LLVMContext::setDiscardValueNames(bool Discard) { 28309b4a8daSMehdi Amini pImpl->DiscardValueNames = Discard; 28409b4a8daSMehdi Amini } 285aa641a51SAndrew Kaylor 286aa641a51SAndrew Kaylor OptBisect &LLVMContext::getOptBisect() { 287aa641a51SAndrew Kaylor return pImpl->getOptBisect(); 288aa641a51SAndrew Kaylor } 289