1ef860a24SChandler Carruth //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===// 2ef860a24SChandler Carruth // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ef860a24SChandler Carruth // 7ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 8ef860a24SChandler Carruth // 9ef860a24SChandler Carruth // This file implements LLVMContext, as a wrapper around the opaque 10ef860a24SChandler Carruth // class LLVMContextImpl. 11ef860a24SChandler Carruth // 12ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 13ef860a24SChandler Carruth 149fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 156bda14b3SChandler Carruth #include "LLVMContextImpl.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" 20b4c44d23SQuentin Colombet #include "llvm/IR/DiagnosticInfo.h" 21b4c44d23SQuentin Colombet #include "llvm/IR/DiagnosticPrinter.h" 229fb823bbSChandler Carruth #include "llvm/IR/Metadata.h" 235354a8aaSEugene Zelenko #include "llvm/IR/Module.h" 24b8a847c0SFrancis Visoiu Mistrih #include "llvm/IR/RemarkStreamer.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. 386f0b4f2eSPeter Collingbourne std::pair<unsigned, StringRef> MDKinds[] = { 39*d01ae675SVedant Kumar #define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name}, 40*d01ae675SVedant Kumar #include "llvm/IR/FixedMetadataKinds.def" 41*d01ae675SVedant Kumar #undef LLVM_FIXED_MD_KIND 426f0b4f2eSPeter Collingbourne }; 43ef860a24SChandler Carruth 446f0b4f2eSPeter Collingbourne for (auto &MDKind : MDKinds) { 456f0b4f2eSPeter Collingbourne unsigned ID = getMDKindID(MDKind.second); 466f0b4f2eSPeter Collingbourne assert(ID == MDKind.first && "metadata kind id drifted"); 476f0b4f2eSPeter Collingbourne (void)ID; 486f0b4f2eSPeter Collingbourne } 49302b69c9SDehao Chen 50cdafd849SSanjoy Das auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); 51cdafd849SSanjoy Das assert(DeoptEntry->second == LLVMContext::OB_deopt && 52cdafd849SSanjoy Das "deopt operand bundle id drifted!"); 53cdafd849SSanjoy Das (void)DeoptEntry; 543bb88c02SDavid Majnemer 553bb88c02SDavid Majnemer auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); 563bb88c02SDavid Majnemer assert(FuncletEntry->second == LLVMContext::OB_funclet && 573bb88c02SDavid Majnemer "funclet operand bundle id drifted!"); 583bb88c02SDavid Majnemer (void)FuncletEntry; 59a34ce95bSSanjoy Das 60a34ce95bSSanjoy Das auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); 61a34ce95bSSanjoy Das assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && 62a34ce95bSSanjoy Das "gc-transition operand bundle id drifted!"); 63a34ce95bSSanjoy Das (void)GCTransitionEntry; 64bb80d3e1SKonstantin Zhuravlyov 65bb80d3e1SKonstantin Zhuravlyov SyncScope::ID SingleThreadSSID = 66bb80d3e1SKonstantin Zhuravlyov pImpl->getOrInsertSyncScopeID("singlethread"); 67bb80d3e1SKonstantin Zhuravlyov assert(SingleThreadSSID == SyncScope::SingleThread && 68bb80d3e1SKonstantin Zhuravlyov "singlethread synchronization scope ID drifted!"); 69878fdee0SKonstantin Zhuravlyov (void)SingleThreadSSID; 70bb80d3e1SKonstantin Zhuravlyov 71bb80d3e1SKonstantin Zhuravlyov SyncScope::ID SystemSSID = 72bb80d3e1SKonstantin Zhuravlyov pImpl->getOrInsertSyncScopeID(""); 73bb80d3e1SKonstantin Zhuravlyov assert(SystemSSID == SyncScope::System && 74bb80d3e1SKonstantin Zhuravlyov "system synchronization scope ID drifted!"); 75878fdee0SKonstantin Zhuravlyov (void)SystemSSID; 76ef860a24SChandler Carruth } 775354a8aaSEugene Zelenko 78ef860a24SChandler Carruth LLVMContext::~LLVMContext() { delete pImpl; } 79ef860a24SChandler Carruth 80ef860a24SChandler Carruth void LLVMContext::addModule(Module *M) { 81ef860a24SChandler Carruth pImpl->OwnedModules.insert(M); 82ef860a24SChandler Carruth } 83ef860a24SChandler Carruth 84ef860a24SChandler Carruth void LLVMContext::removeModule(Module *M) { 85ef860a24SChandler Carruth pImpl->OwnedModules.erase(M); 86ef860a24SChandler Carruth } 87ef860a24SChandler Carruth 88ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 89ef860a24SChandler Carruth // Recoverable Backend Errors 90ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 91ef860a24SChandler Carruth 92a594fab4SBob Wilson void LLVMContext:: 93a594fab4SBob Wilson setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, 94ef860a24SChandler Carruth void *DiagContext) { 95a594fab4SBob Wilson pImpl->InlineAsmDiagHandler = DiagHandler; 96a594fab4SBob Wilson pImpl->InlineAsmDiagContext = DiagContext; 97ef860a24SChandler Carruth } 98ef860a24SChandler Carruth 99a594fab4SBob Wilson /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by 100a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler. 101a594fab4SBob Wilson LLVMContext::InlineAsmDiagHandlerTy 102a594fab4SBob Wilson LLVMContext::getInlineAsmDiagnosticHandler() const { 103a594fab4SBob Wilson return pImpl->InlineAsmDiagHandler; 104ef860a24SChandler Carruth } 105ef860a24SChandler Carruth 106a594fab4SBob Wilson /// getInlineAsmDiagnosticContext - Return the diagnostic context set by 107a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler. 108a594fab4SBob Wilson void *LLVMContext::getInlineAsmDiagnosticContext() const { 109a594fab4SBob Wilson return pImpl->InlineAsmDiagContext; 110ef860a24SChandler Carruth } 111ef860a24SChandler Carruth 112b5ab895eSVivek Pandya void LLVMContext::setDiagnosticHandlerCallBack( 113b5ab895eSVivek Pandya DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, 114b5ab895eSVivek Pandya void *DiagnosticContext, bool RespectFilters) { 115b5ab895eSVivek Pandya pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler; 116b5ab895eSVivek Pandya pImpl->DiagHandler->DiagnosticContext = DiagnosticContext; 117b5ab895eSVivek Pandya pImpl->RespectDiagnosticFilters = RespectFilters; 118b5ab895eSVivek Pandya } 119b5ab895eSVivek Pandya 120b5ab895eSVivek Pandya void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, 12130c9242cSDuncan P. N. Exon Smith bool RespectFilters) { 122b5ab895eSVivek Pandya pImpl->DiagHandler = std::move(DH); 12330c9242cSDuncan P. N. Exon Smith pImpl->RespectDiagnosticFilters = RespectFilters; 124b4c44d23SQuentin Colombet } 125b4c44d23SQuentin Colombet 12644e5f6c4SBrian Gesiak void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) { 12744e5f6c4SBrian Gesiak pImpl->DiagnosticsHotnessRequested = Requested; 12844e5f6c4SBrian Gesiak } 12944e5f6c4SBrian Gesiak bool LLVMContext::getDiagnosticsHotnessRequested() const { 13044e5f6c4SBrian Gesiak return pImpl->DiagnosticsHotnessRequested; 131aad81608SAdam Nemet } 132aad81608SAdam Nemet 1334ef3daafSBrian Gesiak void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) { 1344ef3daafSBrian Gesiak pImpl->DiagnosticsHotnessThreshold = Threshold; 1354ef3daafSBrian Gesiak } 1364ef3daafSBrian Gesiak uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { 1374ef3daafSBrian Gesiak return pImpl->DiagnosticsHotnessThreshold; 1384ef3daafSBrian Gesiak } 1394ef3daafSBrian Gesiak 140b8a847c0SFrancis Visoiu Mistrih RemarkStreamer *LLVMContext::getRemarkStreamer() { 141b8a847c0SFrancis Visoiu Mistrih return pImpl->RemarkDiagStreamer.get(); 142a62b7e1aSAdam Nemet } 143b8a847c0SFrancis Visoiu Mistrih const RemarkStreamer *LLVMContext::getRemarkStreamer() const { 144b8a847c0SFrancis Visoiu Mistrih return const_cast<LLVMContext *>(this)->getRemarkStreamer(); 145b8a847c0SFrancis Visoiu Mistrih } 146b8a847c0SFrancis Visoiu Mistrih void LLVMContext::setRemarkStreamer( 147b8a847c0SFrancis Visoiu Mistrih std::unique_ptr<RemarkStreamer> RemarkStreamer) { 148b8a847c0SFrancis Visoiu Mistrih pImpl->RemarkDiagStreamer = std::move(RemarkStreamer); 149a62b7e1aSAdam Nemet } 150a62b7e1aSAdam Nemet 151b5ab895eSVivek Pandya DiagnosticHandler::DiagnosticHandlerTy 152b5ab895eSVivek Pandya LLVMContext::getDiagnosticHandlerCallBack() const { 153b5ab895eSVivek Pandya return pImpl->DiagHandler->DiagHandlerCallback; 154b4c44d23SQuentin Colombet } 155b4c44d23SQuentin Colombet 156b4c44d23SQuentin Colombet void *LLVMContext::getDiagnosticContext() const { 157b5ab895eSVivek Pandya return pImpl->DiagHandler->DiagnosticContext; 158b4c44d23SQuentin Colombet } 159b4c44d23SQuentin Colombet 16034390c70SJuergen Ributzka void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 16134390c70SJuergen Ributzka { 16234390c70SJuergen Ributzka pImpl->YieldCallback = Callback; 16334390c70SJuergen Ributzka pImpl->YieldOpaqueHandle = OpaqueHandle; 16434390c70SJuergen Ributzka } 16534390c70SJuergen Ributzka 16634390c70SJuergen Ributzka void LLVMContext::yield() { 16734390c70SJuergen Ributzka if (pImpl->YieldCallback) 16834390c70SJuergen Ributzka pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 16934390c70SJuergen Ributzka } 17034390c70SJuergen Ributzka 171ef860a24SChandler Carruth void LLVMContext::emitError(const Twine &ErrorStr) { 172dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 173ef860a24SChandler Carruth } 174ef860a24SChandler Carruth 175bfb44ef9SBob Wilson void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 176dec8d55bSQuentin Colombet assert (I && "Invalid instruction"); 177dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 178ef860a24SChandler Carruth } 179ef860a24SChandler Carruth 18030c9242cSDuncan P. N. Exon Smith static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { 1817f8af8bfSDiego Novillo // Optimization remarks are selective. They need to check whether the regexp 1827f8af8bfSDiego Novillo // pattern, passed via one of the -pass-remarks* flags, matches the name of 1837f8af8bfSDiego Novillo // the pass that is emitting the diagnostic. If there is no match, ignore the 1847f8af8bfSDiego Novillo // diagnostic and return. 185f31b1f31SAdam Nemet // 186f31b1f31SAdam Nemet // Also noisy remarks are only enabled if we have hotness information to sort 187f31b1f31SAdam Nemet // them. 188e9148dd6SAkira Hatanaka if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 189f31b1f31SAdam Nemet return Remark->isEnabled() && 190f31b1f31SAdam Nemet (!Remark->isVerbose() || Remark->getHotness()); 191e9148dd6SAkira Hatanaka 19230c9242cSDuncan P. N. Exon Smith return true; 19330c9242cSDuncan P. N. Exon Smith } 19430c9242cSDuncan P. N. Exon Smith 1954b9c0d4dSRenato Golin const char * 1964b9c0d4dSRenato Golin LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { 197735c47ecSAlex Lorenz switch (Severity) { 198735c47ecSAlex Lorenz case DS_Error: 199735c47ecSAlex Lorenz return "error"; 200735c47ecSAlex Lorenz case DS_Warning: 201735c47ecSAlex Lorenz return "warning"; 202735c47ecSAlex Lorenz case DS_Remark: 203735c47ecSAlex Lorenz return "remark"; 204735c47ecSAlex Lorenz case DS_Note: 205735c47ecSAlex Lorenz return "note"; 206735c47ecSAlex Lorenz } 2075220476aSAaron Ballman llvm_unreachable("Unknown DiagnosticSeverity"); 208735c47ecSAlex Lorenz } 209735c47ecSAlex Lorenz 21030c9242cSDuncan P. N. Exon Smith void LLVMContext::diagnose(const DiagnosticInfo &DI) { 211b8a847c0SFrancis Visoiu Mistrih if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 212b8a847c0SFrancis Visoiu Mistrih if (RemarkStreamer *RS = getRemarkStreamer()) 213b8a847c0SFrancis Visoiu Mistrih RS->emit(*OptDiagBase); 214b8a847c0SFrancis Visoiu Mistrih 21530c9242cSDuncan P. N. Exon Smith // If there is a report handler, use it. 216b5ab895eSVivek Pandya if (pImpl->DiagHandler && 217b5ab895eSVivek Pandya (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && 218b5ab895eSVivek Pandya pImpl->DiagHandler->handleDiagnostics(DI)) 21930c9242cSDuncan P. N. Exon Smith return; 22030c9242cSDuncan P. N. Exon Smith 22130c9242cSDuncan P. N. Exon Smith if (!isDiagnosticEnabled(DI)) 22230c9242cSDuncan P. N. Exon Smith return; 223df655013SDiego Novillo 224b4c44d23SQuentin Colombet // Otherwise, print the message with a prefix based on the severity. 225735c47ecSAlex Lorenz DiagnosticPrinterRawOStream DP(errs()); 226735c47ecSAlex Lorenz errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 227b4c44d23SQuentin Colombet DI.print(DP); 228735c47ecSAlex Lorenz errs() << "\n"; 229735c47ecSAlex Lorenz if (DI.getSeverity() == DS_Error) 230b4c44d23SQuentin Colombet exit(1); 231b4c44d23SQuentin Colombet } 232b4c44d23SQuentin Colombet 233ef860a24SChandler Carruth void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { 234dec8d55bSQuentin Colombet diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 235ef860a24SChandler Carruth } 236ef860a24SChandler Carruth 237ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 238ef860a24SChandler Carruth // Metadata Kind Uniquing 239ef860a24SChandler Carruth //===----------------------------------------------------------------------===// 240ef860a24SChandler Carruth 2411ac0d2deSFilipe Cabecinhas /// Return a unique non-zero ID for the specified metadata kind. 242ef860a24SChandler Carruth unsigned LLVMContext::getMDKindID(StringRef Name) const { 243ef860a24SChandler Carruth // If this is new, assign it its ID. 2441ac0d2deSFilipe Cabecinhas return pImpl->CustomMDKindNames.insert( 2451ac0d2deSFilipe Cabecinhas std::make_pair( 2461ac0d2deSFilipe Cabecinhas Name, pImpl->CustomMDKindNames.size())) 2475106ce78SDavid Blaikie .first->second; 248ef860a24SChandler Carruth } 249ef860a24SChandler Carruth 2504104337dSSanjay Patel /// getHandlerNames - Populate client-supplied smallvector using custom 251ef860a24SChandler Carruth /// metadata name and ID. 252ef860a24SChandler Carruth void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 253ef860a24SChandler Carruth Names.resize(pImpl->CustomMDKindNames.size()); 254ef860a24SChandler Carruth for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 255ef860a24SChandler Carruth E = pImpl->CustomMDKindNames.end(); I != E; ++I) 256ef860a24SChandler Carruth Names[I->second] = I->first(); 257ef860a24SChandler Carruth } 2589303c246SSanjoy Das 2599303c246SSanjoy Das void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { 2609303c246SSanjoy Das pImpl->getOperandBundleTags(Tags); 2619303c246SSanjoy Das } 2629303c246SSanjoy Das 2639303c246SSanjoy Das uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { 2649303c246SSanjoy Das return pImpl->getOperandBundleTagID(Tag); 2659303c246SSanjoy Das } 266599ebf27SMehdi Amini 267bb80d3e1SKonstantin Zhuravlyov SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) { 268bb80d3e1SKonstantin Zhuravlyov return pImpl->getOrInsertSyncScopeID(SSN); 269bb80d3e1SKonstantin Zhuravlyov } 270bb80d3e1SKonstantin Zhuravlyov 271bb80d3e1SKonstantin Zhuravlyov void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const { 272bb80d3e1SKonstantin Zhuravlyov pImpl->getSyncScopeNames(SSNs); 273bb80d3e1SKonstantin Zhuravlyov } 274bb80d3e1SKonstantin Zhuravlyov 275599ebf27SMehdi Amini void LLVMContext::setGC(const Function &Fn, std::string GCName) { 276599ebf27SMehdi Amini auto It = pImpl->GCNames.find(&Fn); 277599ebf27SMehdi Amini 278599ebf27SMehdi Amini if (It == pImpl->GCNames.end()) { 279599ebf27SMehdi Amini pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); 280599ebf27SMehdi Amini return; 281599ebf27SMehdi Amini } 282599ebf27SMehdi Amini It->second = std::move(GCName); 283599ebf27SMehdi Amini } 2845354a8aaSEugene Zelenko 285599ebf27SMehdi Amini const std::string &LLVMContext::getGC(const Function &Fn) { 286599ebf27SMehdi Amini return pImpl->GCNames[&Fn]; 287599ebf27SMehdi Amini } 2885354a8aaSEugene Zelenko 289599ebf27SMehdi Amini void LLVMContext::deleteGC(const Function &Fn) { 290599ebf27SMehdi Amini pImpl->GCNames.erase(&Fn); 291599ebf27SMehdi Amini } 29209b4a8daSMehdi Amini 293e7090155SMehdi Amini bool LLVMContext::shouldDiscardValueNames() const { 294e7090155SMehdi Amini return pImpl->DiscardValueNames; 295e7090155SMehdi Amini } 29609b4a8daSMehdi Amini 297ed8fdb2aSDuncan P. N. Exon Smith bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } 2985ab2be09SDuncan P. N. Exon Smith 299ed8fdb2aSDuncan P. N. Exon Smith void LLVMContext::enableDebugTypeODRUniquing() { 3005ab2be09SDuncan P. N. Exon Smith if (pImpl->DITypeMap) 3015ab2be09SDuncan P. N. Exon Smith return; 3025ab2be09SDuncan P. N. Exon Smith 303e8b555c6SDuncan P. N. Exon Smith pImpl->DITypeMap.emplace(); 3045ab2be09SDuncan P. N. Exon Smith } 3055ab2be09SDuncan P. N. Exon Smith 306ed8fdb2aSDuncan P. N. Exon Smith void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } 3075ab2be09SDuncan P. N. Exon Smith 30809b4a8daSMehdi Amini void LLVMContext::setDiscardValueNames(bool Discard) { 30909b4a8daSMehdi Amini pImpl->DiscardValueNames = Discard; 31009b4a8daSMehdi Amini } 311aa641a51SAndrew Kaylor 312d29884c7SFedor Sergeev OptPassGate &LLVMContext::getOptPassGate() const { 31398014e43SFedor Sergeev return pImpl->getOptPassGate(); 314aa641a51SAndrew Kaylor } 315b5ab895eSVivek Pandya 316d29884c7SFedor Sergeev void LLVMContext::setOptPassGate(OptPassGate& OPG) { 317d29884c7SFedor Sergeev pImpl->setOptPassGate(OPG); 318d29884c7SFedor Sergeev } 319d29884c7SFedor Sergeev 320b5ab895eSVivek Pandya const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { 321b5ab895eSVivek Pandya return pImpl->DiagHandler.get(); 322b5ab895eSVivek Pandya } 323b5ab895eSVivek Pandya 324b5ab895eSVivek Pandya std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() { 325b5ab895eSVivek Pandya return std::move(pImpl->DiagHandler); 326b5ab895eSVivek Pandya } 327