LLVM 23.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
34static StringRef knownBundleName(unsigned BundleTagID) {
35 switch (BundleTagID) {
36#define ATTR(Name, Str) \
37 case LLVMContext::OB_##Name: \
38 return #Str;
39#include "llvm/IR/BundleAttributes.def"
41 return "deopt";
43 return "funclet";
45 return "gc-transition";
47 return "cfguardtarget";
49 return "preallocated";
51 return "gc-live";
53 return "clang.arc.attachedcall";
55 return "ptrauth";
57 return "kcfi";
59 return "convergencectrl";
61 return "deactivation-symbol";
62 default:
63 llvm_unreachable("unknown bundle id");
64 }
65
66 llvm_unreachable("covered switch");
67}
68
70 // Create the fixed metadata kinds. This is done in the same order as the
71 // MD_* enum values so that they correspond.
72 std::pair<unsigned, StringRef> MDKinds[] = {
73#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
74#include "llvm/IR/FixedMetadataKinds.def"
75#undef LLVM_FIXED_MD_KIND
76 };
77
78 for (auto &MDKind : MDKinds) {
79 unsigned ID = getMDKindID(MDKind.second);
80 assert(ID == MDKind.first && "metadata kind id drifted");
81 (void)ID;
82 }
83
84 for (unsigned BundleTagID = 0; BundleTagID <= LLVMContext::OB_LastBundleID;
85 ++BundleTagID) {
86 [[maybe_unused]] const auto *Entry =
87 pImpl->getOrInsertBundleTag(knownBundleName(BundleTagID));
88 assert(Entry->second == BundleTagID && "operand bundle id drifted!");
89 }
90
91 SyncScope::ID SingleThreadSSID =
92 pImpl->getOrInsertSyncScopeID("singlethread");
93 assert(SingleThreadSSID == SyncScope::SingleThread &&
94 "singlethread synchronization scope ID drifted!");
95 (void)SingleThreadSSID;
96
97 SyncScope::ID SystemSSID =
98 pImpl->getOrInsertSyncScopeID("");
99 assert(SystemSSID == SyncScope::System &&
100 "system synchronization scope ID drifted!");
101 (void)SystemSSID;
102}
103
105
106void LLVMContext::addModule(Module *M) {
108}
109
110void LLVMContext::removeModule(Module *M) {
112 pImpl->MachineFunctionNums.erase(M);
113}
114
116 Module *M = F.getParent();
117 assert(pImpl->OwnedModules.contains(M) && "Unexpected module!");
118 return pImpl->MachineFunctionNums[M]++;
119}
120
121//===----------------------------------------------------------------------===//
122// Recoverable Backend Errors
123//===----------------------------------------------------------------------===//
124
127 void *DiagnosticContext, bool RespectFilters) {
128 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
129 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
130 pImpl->RespectDiagnosticFilters = RespectFilters;
131}
132
133void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
134 bool RespectFilters) {
135 pImpl->DiagHandler = std::move(DH);
136 pImpl->RespectDiagnosticFilters = RespectFilters;
137}
138
140 pImpl->DiagnosticsHotnessRequested = Requested;
141}
143 return pImpl->DiagnosticsHotnessRequested;
144}
145
146void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) {
147 pImpl->DiagnosticsHotnessThreshold = Threshold;
148}
150 pImpl->MisExpectWarningRequested = Requested;
151}
153 return pImpl->MisExpectWarningRequested;
154}
156 return pImpl->DiagnosticsHotnessThreshold.value_or(UINT64_MAX);
157}
159 std::optional<uint32_t> Tolerance) {
160 pImpl->DiagnosticsMisExpectTolerance = Tolerance;
161}
163 return pImpl->DiagnosticsMisExpectTolerance.value_or(0);
164}
165
167 return !pImpl->DiagnosticsHotnessThreshold.has_value();
168}
169
171 return pImpl->MainRemarkStreamer.get();
172}
177 std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
178 pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
179}
180
185 return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
186}
188 std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
189 pImpl->LLVMRS = std::move(RemarkStreamer);
190}
191
194 return pImpl->DiagHandler->DiagHandlerCallback;
195}
196
198 return pImpl->DiagHandler->DiagnosticContext;
199}
200
201void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
202{
203 pImpl->YieldCallback = Callback;
204 pImpl->YieldOpaqueHandle = OpaqueHandle;
205}
206
208 if (pImpl->YieldCallback)
209 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
210}
211
212void LLVMContext::emitError(const Twine &ErrorStr) {
214}
215
216void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
217 assert(I && "Invalid instruction");
218 diagnose(DiagnosticInfoGeneric(I, ErrorStr));
219}
220
221static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
222 // Optimization remarks are selective. They need to check whether the regexp
223 // pattern, passed via one of the -pass-remarks* flags, matches the name of
224 // the pass that is emitting the diagnostic. If there is no match, ignore the
225 // diagnostic and return.
226 //
227 // Also noisy remarks are only enabled if we have hotness information to sort
228 // them.
230 return Remark->isEnabled() &&
231 (!Remark->isVerbose() || Remark->getHotness());
232
233 return true;
234}
235
236const char *
238 switch (Severity) {
239 case DS_Error:
240 return "error";
241 case DS_Warning:
242 return "warning";
243 case DS_Remark:
244 return "remark";
245 case DS_Note:
246 return "note";
247 }
248 llvm_unreachable("Unknown DiagnosticSeverity");
249}
250
252 if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
254 RS->emit(*OptDiagBase);
255
256 // If there is a report handler, use it.
257 if (pImpl->DiagHandler) {
258 if (DI.getSeverity() == DS_Error)
259 pImpl->DiagHandler->HasErrors = true;
260 if ((!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
261 pImpl->DiagHandler->handleDiagnostics(DI))
262 return;
263 }
264
265 if (!isDiagnosticEnabled(DI))
266 return;
267
268 // Otherwise, print the message with a prefix based on the severity.
271 DI.print(DP);
272 errs() << "\n";
273}
274
275//===----------------------------------------------------------------------===//
276// Metadata Kind Uniquing
277//===----------------------------------------------------------------------===//
278
279/// Return a unique non-zero ID for the specified metadata kind.
281 // If this is new, assign it its ID.
282 return pImpl->CustomMDKindNames.insert(
283 std::make_pair(
284 Name, pImpl->CustomMDKindNames.size()))
285 .first->second;
286}
287
288/// getHandlerNames - Populate client-supplied smallvector using custom
289/// metadata name and ID.
291 Names.resize(pImpl->CustomMDKindNames.size());
292 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
293 E = pImpl->CustomMDKindNames.end(); I != E; ++I)
294 Names[I->second] = I->first();
295}
296
298 pImpl->getOperandBundleTags(Tags);
299}
300
303 return pImpl->getOrInsertBundleTag(TagName);
304}
305
307 return pImpl->getOperandBundleTagID(Tag);
308}
309
311 return pImpl->getOrInsertSyncScopeID(SSN);
312}
313
315 pImpl->getSyncScopeNames(SSNs);
316}
317
318std::optional<StringRef> LLVMContext::getSyncScopeName(SyncScope::ID Id) const {
319 return pImpl->getSyncScopeName(Id);
320}
321
322void LLVMContext::setGC(const Function &Fn, std::string GCName) {
323 pImpl->GCNames[&Fn] = std::move(GCName);
324}
325
326const std::string &LLVMContext::getGC(const Function &Fn) {
327 return pImpl->GCNames[&Fn];
328}
329
331 pImpl->GCNames.erase(&Fn);
332}
333
335 return pImpl->DiscardValueNames;
336}
337
338bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
339
341 if (pImpl->DITypeMap)
342 return;
343
344 pImpl->DITypeMap.emplace();
345}
346
348
350 pImpl->DiscardValueNames = Discard;
351}
352
354 return pImpl->getOptPassGate();
355}
356
358 pImpl->setOptPassGate(OPG);
359}
360
362 return pImpl->DiagHandler.get();
363}
364
365std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
366 return std::move(pImpl->DiagHandler);
367}
368
370 return pImpl->DefaultTargetCPU;
371}
372
374 pImpl->DefaultTargetCPU = CPU;
375}
376
378 return pImpl->DefaultTargetFeatures;
379}
380
382 pImpl->DefaultTargetFeatures = Features;
383}
384
386 pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V);
387}
388
390 return pImpl->NextAtomGroup++;
391}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isDiagnosticEnabled(const DiagnosticInfo &DI)
static StringRef knownBundleName(unsigned BundleTagID)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file defines the SmallVector class.
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.
SmallPtrSet< Module *, 4 > OwnedModules
OwnedModules - The set of modules instantiated in this context, and which will be automatically delet...
DenseMap< Module *, unsigned > MachineFunctionNums
MachineFunctionNums - Keep the next available unique number available for a MachineFunction in given ...
LLVM_ABI uint64_t incNextDILocationAtomGroup()
Key Instructions: get the next free atom group number and increment the global tracker.
LLVM_ABI void setMisExpectWarningRequested(bool Requested)
LLVM_ABI std::optional< StringRef > getSyncScopeName(SyncScope::ID Id) const
getSyncScopeName - Returns the name of a SyncScope::ID registered with LLVMContext,...
LLVM_ABI remarks::RemarkStreamer * getMainRemarkStreamer()
The "main remark streamer" used by all the specialized remark streamers.
LLVM_ABI uint32_t getOperandBundleTagID(StringRef Tag) const
getOperandBundleTagID - Maps a bundle tag to an integer ID.
friend class Module
LLVM_ABI void disableDebugTypeODRUniquing()
LLVM_ABI void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
Registers a yield callback with the given context.
LLVM_ABI void deleteGC(const Function &Fn)
Remove the GC for a function.
LLVM_ABI const std::string & getGC(const Function &Fn)
Return the GC for a function.
LLVM_ABI DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const
getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by setDiagnosticHandlerCal...
LLVM_ABI void setLLVMRemarkStreamer(std::unique_ptr< LLVMRemarkStreamer > RemarkStreamer)
LLVM_ABI unsigned getMDKindID(StringRef Name) const
getMDKindID - Return a unique non-zero ID for the specified metadata kind.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
static LLVM_ABI const char * getDiagnosticMessagePrefix(DiagnosticSeverity Severity)
Get the prefix that should be printed in front of a diagnostic of the given Severity.
LLVM_ABI void enableDebugTypeODRUniquing()
LLVM_ABI ~LLVMContext()
LLVM_ABI std::unique_ptr< DiagnosticHandler > getDiagnosticHandler()
getDiagnosticHandler - transfers ownership of DiagnosticHandler unique_ptr to caller.
LLVM_ABI void setDefaultTargetCPU(StringRef CPU)
LLVM_ABI LLVMContext()
LLVM_ABI bool getDiagnosticsHotnessRequested() const
Return if a code hotness metric should be included in optimization diagnostics.
LLVM_ABI bool getMisExpectWarningRequested() const
LLVM_ABI void yield()
Calls the yield callback (if applicable).
LLVM_ABI void setDiagnosticsHotnessThreshold(std::optional< uint64_t > Threshold)
Set the minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
LLVM_ABI void setMainRemarkStreamer(std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer)
LLVM_ABI bool isDiagnosticsHotnessThresholdSetFromPSI() const
Return if hotness threshold is requested from PSI.
LLVM_ABI void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time.
LLVM_ABI StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef TagName) const
getOrInsertBundleTag - Returns the Tag to use for an operand bundle of name TagName.
LLVM_ABI void setDiagnosticsHotnessRequested(bool Requested)
Set if a code hotness metric should be included in optimization diagnostics.
LLVM_ABI void setGC(const Function &Fn, std::string GCName)
Define the GC for a function.
LLVM_ABI 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.
LLVM_ABI bool isODRUniquingDebugTypes() const
Whether there is a string map for uniquing debug info identifiers across the context.
LLVM_ABI unsigned generateMachineFunctionNum(Function &)
generateMachineFunctionNum - Get a unique number for MachineFunction that associated with the given F...
LLVM_ABI StringRef getDefaultTargetFeatures()
Similar to {get,set}DefaultTargetCPU() but for default target-features.
LLVM_ABI void setDiagnosticsMisExpectTolerance(std::optional< uint32_t > Tolerance)
LLVMContextImpl *const pImpl
Definition LLVMContext.h:70
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
LLVM_ABI void getOperandBundleTags(SmallVectorImpl< StringRef > &Result) const
getOperandBundleTags - Populate client supplied SmallVector with the bundle tags registered in this L...
LLVM_ABI 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 ...
LLVM_ABI void setDiscardValueNames(bool Discard)
Set the Context runtime configuration to discard all value name (but GlobalValue).
LLVM_ABI StringRef getDefaultTargetCPU()
Get or set the current "default" target CPU (target-cpu function attribute).
LLVM_ABI void getMDKindNames(SmallVectorImpl< StringRef > &Result) const
getMDKindNames - Populate client supplied SmallVector with the name for custom metadata IDs registere...
LLVM_ABI void * getDiagnosticContext() const
getDiagnosticContext - Return the diagnostic context set by setDiagnosticContext.
LLVM_ABI void updateDILocationAtomGroupWaterline(uint64_t G)
Key Instructions: update the highest number atom group emitted for any function.
LLVM_ABI SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
LLVM_ABI uint64_t getDiagnosticsHotnessThreshold() const
Return the minimum hotness value a diagnostic would need in order to be included in optimization diag...
LLVM_ABI void setDefaultTargetFeatures(StringRef Features)
LLVM_ABI const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
LLVM_ABI void setDiagnosticHandler(std::unique_ptr< DiagnosticHandler > &&DH, bool RespectFilters=false)
setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler to provide custom d...
LLVM_ABI OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time.
LLVM_ABI LLVMRemarkStreamer * getLLVMRemarkStreamer()
The "LLVM remark streamer" used by LLVM to serialize remark diagnostics comming from IR and MIR passe...
LLVM_ABI void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
LLVM_ABI 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:67
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition OptBisect.h:26
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize(size_type N)
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMapIterBase< ValueTy, true > const_iterator
Definition StringMap.h:207
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
#define UINT64_MAX
Definition DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:58
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
This is the base class for diagnostic handling in LLVM.
void(*)(const DiagnosticInfo *DI, void *Context) DiagnosticHandlerTy