LLVM 19.0.0git
LLVMContext.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements LLVMContext, as a wrapper around the opaque
10// class LLVMContextImpl.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/IR/LLVMContext.h"
15#include "LLVMContextImpl.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
27#include <cassert>
28#include <cstdlib>
29#include <string>
30#include <utility>
31
32using namespace llvm;
33
35 // Create the fixed metadata kinds. This is done in the same order as the
36 // MD_* enum values so that they correspond.
37 std::pair<unsigned, StringRef> MDKinds[] = {
38#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
39#include "llvm/IR/FixedMetadataKinds.def"
40#undef LLVM_FIXED_MD_KIND
41 };
42
43 for (auto &MDKind : MDKinds) {
44 unsigned ID = getMDKindID(MDKind.second);
45 assert(ID == MDKind.first && "metadata kind id drifted");
46 (void)ID;
47 }
48
49 auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
50 assert(DeoptEntry->second == LLVMContext::OB_deopt &&
51 "deopt operand bundle id drifted!");
52 (void)DeoptEntry;
53
54 auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
55 assert(FuncletEntry->second == LLVMContext::OB_funclet &&
56 "funclet operand bundle id drifted!");
57 (void)FuncletEntry;
58
59 auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
60 assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
61 "gc-transition operand bundle id drifted!");
62 (void)GCTransitionEntry;
63
64 auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget");
65 assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget &&
66 "cfguardtarget operand bundle id drifted!");
67 (void)CFGuardTargetEntry;
68
69 auto *PreallocatedEntry = pImpl->getOrInsertBundleTag("preallocated");
70 assert(PreallocatedEntry->second == LLVMContext::OB_preallocated &&
71 "preallocated operand bundle id drifted!");
72 (void)PreallocatedEntry;
73
74 auto *GCLiveEntry = pImpl->getOrInsertBundleTag("gc-live");
75 assert(GCLiveEntry->second == LLVMContext::OB_gc_live &&
76 "gc-transition operand bundle id drifted!");
77 (void)GCLiveEntry;
78
79 auto *ClangAttachedCall =
80 pImpl->getOrInsertBundleTag("clang.arc.attachedcall");
81 assert(ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall &&
82 "clang.arc.attachedcall operand bundle id drifted!");
83 (void)ClangAttachedCall;
84
85 auto *PtrauthEntry = pImpl->getOrInsertBundleTag("ptrauth");
86 assert(PtrauthEntry->second == LLVMContext::OB_ptrauth &&
87 "ptrauth operand bundle id drifted!");
88 (void)PtrauthEntry;
89
90 auto *KCFIEntry = pImpl->getOrInsertBundleTag("kcfi");
91 assert(KCFIEntry->second == LLVMContext::OB_kcfi &&
92 "kcfi operand bundle id drifted!");
93 (void)KCFIEntry;
94
95 auto *ConvergenceCtrlEntry = pImpl->getOrInsertBundleTag("convergencectrl");
96 assert(ConvergenceCtrlEntry->second == LLVMContext::OB_convergencectrl &&
97 "convergencectrl operand bundle id drifted!");
98 (void)ConvergenceCtrlEntry;
99
100 SyncScope::ID SingleThreadSSID =
101 pImpl->getOrInsertSyncScopeID("singlethread");
102 assert(SingleThreadSSID == SyncScope::SingleThread &&
103 "singlethread synchronization scope ID drifted!");
104 (void)SingleThreadSSID;
105
106 SyncScope::ID SystemSSID =
108 assert(SystemSSID == SyncScope::System &&
109 "system synchronization scope ID drifted!");
110 (void)SystemSSID;
111}
112
114
115void LLVMContext::addModule(Module *M) {
117}
118
119void LLVMContext::removeModule(Module *M) {
121}
122
123//===----------------------------------------------------------------------===//
124// Recoverable Backend Errors
125//===----------------------------------------------------------------------===//
126
129 void *DiagnosticContext, bool RespectFilters) {
130 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
131 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
132 pImpl->RespectDiagnosticFilters = RespectFilters;
133}
134
135void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
136 bool RespectFilters) {
137 pImpl->DiagHandler = std::move(DH);
138 pImpl->RespectDiagnosticFilters = RespectFilters;
139}
140
143}
146}
147
148void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) {
150}
152 pImpl->MisExpectWarningRequested = Requested;
153}
156}
159}
161 std::optional<uint32_t> Tolerance) {
163}
165 return pImpl->DiagnosticsMisExpectTolerance.value_or(0);
166}
167
169 return !pImpl->DiagnosticsHotnessThreshold.has_value();
170}
171
173 return pImpl->MainRemarkStreamer.get();
174}
176 return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
177}
179 std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
180 pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
181}
182
184 return pImpl->LLVMRS.get();
185}
187 return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
188}
190 std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
191 pImpl->LLVMRS = std::move(RemarkStreamer);
192}
193
196 return pImpl->DiagHandler->DiagHandlerCallback;
197}
198
200 return pImpl->DiagHandler->DiagnosticContext;
201}
202
203void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
204{
205 pImpl->YieldCallback = Callback;
206 pImpl->YieldOpaqueHandle = OpaqueHandle;
207}
208
210 if (pImpl->YieldCallback)
212}
213
214void LLVMContext::emitError(const Twine &ErrorStr) {
216}
217
218void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
219 assert (I && "Invalid instruction");
221}
222
223static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
224 // Optimization remarks are selective. They need to check whether the regexp
225 // pattern, passed via one of the -pass-remarks* flags, matches the name of
226 // the pass that is emitting the diagnostic. If there is no match, ignore the
227 // diagnostic and return.
228 //
229 // Also noisy remarks are only enabled if we have hotness information to sort
230 // them.
231 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
232 return Remark->isEnabled() &&
233 (!Remark->isVerbose() || Remark->getHotness());
234
235 return true;
236}
237
238const char *
240 switch (Severity) {
241 case DS_Error:
242 return "error";
243 case DS_Warning:
244 return "warning";
245 case DS_Remark:
246 return "remark";
247 case DS_Note:
248 return "note";
249 }
250 llvm_unreachable("Unknown DiagnosticSeverity");
251}
252
254 if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
256 RS->emit(*OptDiagBase);
257
258 // If there is a report handler, use it.
259 if (pImpl->DiagHandler) {
260 if (DI.getSeverity() == DS_Error)
261 pImpl->DiagHandler->HasErrors = true;
263 pImpl->DiagHandler->handleDiagnostics(DI))
264 return;
265 }
266
267 if (!isDiagnosticEnabled(DI))
268 return;
269
270 // Otherwise, print the message with a prefix based on the severity.
273 DI.print(DP);
274 errs() << "\n";
275 if (DI.getSeverity() == DS_Error)
276 exit(1);
277}
278
279void LLVMContext::emitError(uint64_t LocCookie, const Twine &ErrorStr) {
280 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
281}
282
283//===----------------------------------------------------------------------===//
284// Metadata Kind Uniquing
285//===----------------------------------------------------------------------===//
286
287/// Return a unique non-zero ID for the specified metadata kind.
289 // If this is new, assign it its ID.
291 std::make_pair(
293 .first->second;
294}
295
296/// getHandlerNames - Populate client-supplied smallvector using custom
297/// metadata name and ID.
301 E = pImpl->CustomMDKindNames.end(); I != E; ++I)
302 Names[I->second] = I->first();
303}
304
307}
308
311 return pImpl->getOrInsertBundleTag(TagName);
312}
313
316}
317
319 return pImpl->getOrInsertSyncScopeID(SSN);
320}
321
324}
325
326void LLVMContext::setGC(const Function &Fn, std::string GCName) {
327 auto It = pImpl->GCNames.find(&Fn);
328
329 if (It == pImpl->GCNames.end()) {
330 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
331 return;
332 }
333 It->second = std::move(GCName);
334}
335
336const std::string &LLVMContext::getGC(const Function &Fn) {
337 return pImpl->GCNames[&Fn];
338}
339
341 pImpl->GCNames.erase(&Fn);
342}
343
345 return pImpl->DiscardValueNames;
346}
347
349
351 if (pImpl->DITypeMap)
352 return;
353
354 pImpl->DITypeMap.emplace();
355}
356
358
360 pImpl->DiscardValueNames = Discard;
361}
362
364 return pImpl->getOptPassGate();
365}
366
368 pImpl->setOptPassGate(OPG);
369}
370
372 return pImpl->DiagHandler.get();
373}
374
375std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
376 return std::move(pImpl->DiagHandler);
377}
378
380 assert(Enable && "Cannot disable opaque pointers");
381}
382
384 return false;
385}
This file defines the StringMap class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
static bool isDiagnosticEnabled(const DiagnosticInfo &DI)
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Diagnostic information for inline asm reporting.
This is the base abstract class for diagnostic reporting in the backend.
DiagnosticSeverity getSeverity() const
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
Basic diagnostic printer that uses an underlying raw_ostream.
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
SmallPtrSet< Module *, 4 > OwnedModules
OwnedModules - The set of modules instantiated in this context, and which will be automatically delet...
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The percentage of difference between profiling branch weights and llvm.expect branch weights to toler...
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time.
std::unique_ptr< LLVMRemarkStreamer > LLVMRS
The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
bool DiscardValueNames
Flag to indicate if Value (other than GlobalValue) retains their name or not.
DenseMap< const Function *, std::string > GCNames
Maintain the GC name for each function.
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time.
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef Tag)
std::unique_ptr< DiagnosticHandler > DiagHandler
std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer
The main remark streamer used by all the other streamers (e.g.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Tags) const
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
uint32_t getOperandBundleTagID(StringRef Tag) const
LLVMContext::YieldCallbackTy YieldCallback
std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void setMisExpectWarningRequested(bool Requested)
remarks::RemarkStreamer * getMainRemarkStreamer()
The "main remark streamer" used by all the specialized remark streamers.
uint32_t getOperandBundleTagID(StringRef Tag) const
getOperandBundleTagID - Maps a bundle tag to an integer ID.
void disableDebugTypeODRUniquing()
void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
Registers a yield callback with the given context.
void deleteGC(const Function &Fn)
Remove the GC for a function.
const std::string & getGC(const Function &Fn)
Return the GC for a function.
DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const
getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by setDiagnosticHandlerCal...
void setLLVMRemarkStreamer(std::unique_ptr< LLVMRemarkStreamer > RemarkStreamer)
unsigned getMDKindID(StringRef Name) const
getMDKindID - Return a unique non-zero ID for the specified metadata kind.
static const char * getDiagnosticMessagePrefix(DiagnosticSeverity Severity)
Get the prefix that should be printed in front of a diagnostic of the given Severity.
void enableDebugTypeODRUniquing()
std::unique_ptr< DiagnosticHandler > getDiagnosticHandler()
getDiagnosticHandler - transfers ownership of DiagnosticHandler unique_ptr to caller.
bool getDiagnosticsHotnessRequested() const
Return if a code hotness metric should be included in optimization diagnostics.
bool getMisExpectWarningRequested() const
void yield()
Calls the yield callback (if applicable).
void setDiagnosticsHotnessThreshold(std::optional< uint64_t > Threshold)
Set the minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
void setMainRemarkStreamer(std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer)
bool isDiagnosticsHotnessThresholdSetFromPSI() const
Return if hotness threshold is requested from PSI.
bool supportsTypedPointers() const
Whether typed pointers are supported. If false, all pointers are opaque.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time.
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef TagName) const
getOrInsertBundleTag - Returns the Tag to use for an operand bundle of name TagName.
void setDiagnosticsHotnessRequested(bool Requested)
Set if a code hotness metric should be included in optimization diagnostics.
void setGC(const Function &Fn, std::string GCName)
Define the GC for a function.
bool shouldDiscardValueNames() const
Return true if the Context runtime configuration is set to discard all value names.
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Definition: LLVMContext.h:160
bool isODRUniquingDebugTypes() const
Whether there is a string map for uniquing debug info identifiers across the context.
void setDiagnosticsMisExpectTolerance(std::optional< uint32_t > Tolerance)
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:69
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Result) const
getOperandBundleTags - Populate client supplied SmallVector with the bundle tags registered in this L...
void setDiagnosticHandlerCallBack(DiagnosticHandler::DiagnosticHandlerTy DiagHandler, void *DiagContext=nullptr, bool RespectFilters=false)
setDiagnosticHandlerCallBack - This method sets a handler call back that is invoked when the backend ...
void setOpaquePointers(bool Enable) const
Set whether opaque pointers are enabled.
void setDiscardValueNames(bool Discard)
Set the Context runtime configuration to discard all value name (but GlobalValue).
void getMDKindNames(SmallVectorImpl< StringRef > &Result) const
getMDKindNames - Populate client supplied SmallVector with the name for custom metadata IDs registere...
void * getDiagnosticContext() const
getDiagnosticContext - Return the diagnostic context set by setDiagnosticContext.
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
uint64_t getDiagnosticsHotnessThreshold() const
Return the minimum hotness value a diagnostic would need in order to be included in optimization diag...
const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
void setDiagnosticHandler(std::unique_ptr< DiagnosticHandler > &&DH, bool RespectFilters=false)
setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler to provide custom d...
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time.
LLVMRemarkStreamer * getLLVMRemarkStreamer()
The "LLVM remark streamer" used by LLVM to serialize remark diagnostics comming from IR and MIR passe...
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
uint32_t getDiagnosticsMisExpectTolerance() const
Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo objects.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:24
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
Definition: SmallPtrSet.h:356
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:342
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void resize(size_type N)
Definition: SmallVector.h:651
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
unsigned size() const
Definition: StringMap.h:104
iterator end()
Definition: StringMap.h:221
iterator begin()
Definition: StringMap.h:220
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:307
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
#define UINT64_MAX
Definition: DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:54
@ System
Synchronized with respect to all concurrently executing threads.
Definition: LLVMContext.h:57
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Remark
@ DS_Warning
@ DS_Error
@ Enable
Enable colors.
This is the base class for diagnostic handling in LLVM.
void(*)(const DiagnosticInfo &DI, void *Context) DiagnosticHandlerTy