1 //===- llvm/LLVMContext.h - Class for managing "global" state ---*- C++ -*-===// 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 declares LLVMContext, a container of "global" state in LLVM, such 10 // as the global type and constant uniquing tables. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_IR_LLVMCONTEXT_H 15 #define LLVM_IR_LLVMCONTEXT_H 16 17 #include "llvm-c/Types.h" 18 #include "llvm/IR/DiagnosticHandler.h" 19 #include "llvm/Support/CBindingWrapping.h" 20 #include <cstdint> 21 #include <memory> 22 #include <string> 23 24 namespace llvm { 25 26 class DiagnosticInfo; 27 enum DiagnosticSeverity : char; 28 class Function; 29 class Instruction; 30 class LLVMContextImpl; 31 class Module; 32 class OptPassGate; 33 template <typename T> class SmallVectorImpl; 34 template <typename T> class StringMapEntry; 35 class SMDiagnostic; 36 class StringRef; 37 class Twine; 38 class LLVMRemarkStreamer; 39 class raw_ostream; 40 41 namespace remarks { 42 class RemarkStreamer; 43 } 44 45 namespace SyncScope { 46 47 typedef uint8_t ID; 48 49 /// Known synchronization scope IDs, which always have the same value. All 50 /// synchronization scope IDs that LLVM has special knowledge of are listed 51 /// here. Additionally, this scheme allows LLVM to efficiently check for 52 /// specific synchronization scope ID without comparing strings. 53 enum { 54 /// Synchronized with respect to signal handlers executing in the same thread. 55 SingleThread = 0, 56 57 /// Synchronized with respect to all concurrently executing threads. 58 System = 1 59 }; 60 61 } // end namespace SyncScope 62 63 /// This is an important class for using LLVM in a threaded context. It 64 /// (opaquely) owns and manages the core "global" data of LLVM's core 65 /// infrastructure, including the type and constant uniquing tables. 66 /// LLVMContext itself provides no locking guarantees, so you should be careful 67 /// to have one context per thread. 68 class LLVMContext { 69 public: 70 LLVMContextImpl *const pImpl; 71 LLVMContext(); 72 LLVMContext(LLVMContext &) = delete; 73 LLVMContext &operator=(const LLVMContext &) = delete; 74 ~LLVMContext(); 75 76 // Pinned metadata names, which always have the same value. This is a 77 // compile-time performance optimization, not a correctness optimization. 78 enum : unsigned { 79 #define LLVM_FIXED_MD_KIND(EnumID, Name, Value) EnumID = Value, 80 #include "llvm/IR/FixedMetadataKinds.def" 81 #undef LLVM_FIXED_MD_KIND 82 }; 83 84 /// Known operand bundle tag IDs, which always have the same value. All 85 /// operand bundle tags that LLVM has special knowledge of are listed here. 86 /// Additionally, this scheme allows LLVM to efficiently check for specific 87 /// operand bundle tags without comparing strings. Keep this in sync with 88 /// LLVMContext::LLVMContext(). 89 enum : unsigned { 90 OB_deopt = 0, // "deopt" 91 OB_funclet = 1, // "funclet" 92 OB_gc_transition = 2, // "gc-transition" 93 OB_cfguardtarget = 3, // "cfguardtarget" 94 OB_preallocated = 4, // "preallocated" 95 OB_gc_live = 5, // "gc-live" 96 }; 97 98 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. 99 /// This ID is uniqued across modules in the current LLVMContext. 100 unsigned getMDKindID(StringRef Name) const; 101 102 /// getMDKindNames - Populate client supplied SmallVector with the name for 103 /// custom metadata IDs registered in this LLVMContext. 104 void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; 105 106 /// getOperandBundleTags - Populate client supplied SmallVector with the 107 /// bundle tags registered in this LLVMContext. The bundle tags are ordered 108 /// by increasing bundle IDs. 109 /// \see LLVMContext::getOperandBundleTagID 110 void getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const; 111 112 /// getOrInsertBundleTag - Returns the Tag to use for an operand bundle of 113 /// name TagName. 114 StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef TagName) const; 115 116 /// getOperandBundleTagID - Maps a bundle tag to an integer ID. Every bundle 117 /// tag registered with an LLVMContext has an unique ID. 118 uint32_t getOperandBundleTagID(StringRef Tag) const; 119 120 /// getOrInsertSyncScopeID - Maps synchronization scope name to 121 /// synchronization scope ID. Every synchronization scope registered with 122 /// LLVMContext has unique ID except pre-defined ones. 123 SyncScope::ID getOrInsertSyncScopeID(StringRef SSN); 124 125 /// getSyncScopeNames - Populates client supplied SmallVector with 126 /// synchronization scope names registered with LLVMContext. Synchronization 127 /// scope names are ordered by increasing synchronization scope IDs. 128 void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const; 129 130 /// Define the GC for a function 131 void setGC(const Function &Fn, std::string GCName); 132 133 /// Return the GC for a function 134 const std::string &getGC(const Function &Fn); 135 136 /// Remove the GC for a function 137 void deleteGC(const Function &Fn); 138 139 /// Return true if the Context runtime configuration is set to discard all 140 /// value names. When true, only GlobalValue names will be available in the 141 /// IR. 142 bool shouldDiscardValueNames() const; 143 144 /// Set the Context runtime configuration to discard all value name (but 145 /// GlobalValue). Clients can use this flag to save memory and runtime, 146 /// especially in release mode. 147 void setDiscardValueNames(bool Discard); 148 149 /// Whether there is a string map for uniquing debug info 150 /// identifiers across the context. Off by default. 151 bool isODRUniquingDebugTypes() const; 152 void enableDebugTypeODRUniquing(); 153 void disableDebugTypeODRUniquing(); 154 155 using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context, 156 unsigned LocCookie); 157 158 /// Defines the type of a yield callback. 159 /// \see LLVMContext::setYieldCallback. 160 using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle); 161 162 /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked 163 /// when problems with inline asm are detected by the backend. The first 164 /// argument is a function pointer and the second is a context pointer that 165 /// gets passed into the DiagHandler. 166 /// 167 /// LLVMContext doesn't take ownership or interpret either of these 168 /// pointers. 169 void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, 170 void *DiagContext = nullptr); 171 172 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by 173 /// setInlineAsmDiagnosticHandler. 174 InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const; 175 176 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by 177 /// setInlineAsmDiagnosticHandler. 178 void *getInlineAsmDiagnosticContext() const; 179 180 /// setDiagnosticHandlerCallBack - This method sets a handler call back 181 /// that is invoked when the backend needs to report anything to the user. 182 /// The first argument is a function pointer and the second is a context pointer 183 /// that gets passed into the DiagHandler. The third argument should be set to 184 /// true if the handler only expects enabled diagnostics. 185 /// 186 /// LLVMContext doesn't take ownership or interpret either of these 187 /// pointers. 188 void setDiagnosticHandlerCallBack( 189 DiagnosticHandler::DiagnosticHandlerTy DiagHandler, 190 void *DiagContext = nullptr, bool RespectFilters = false); 191 192 /// setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler 193 /// to provide custom diagnostic handling. The first argument is unique_ptr of object 194 /// of type DiagnosticHandler or a derived of that. The third argument should be 195 /// set to true if the handler only expects enabled diagnostics. 196 /// 197 /// Ownership of this pointer is moved to LLVMContextImpl. 198 void setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, 199 bool RespectFilters = false); 200 201 /// getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by 202 /// setDiagnosticHandlerCallBack. 203 DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const; 204 205 /// getDiagnosticContext - Return the diagnostic context set by 206 /// setDiagnosticContext. 207 void *getDiagnosticContext() const; 208 209 /// getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by 210 /// setDiagnosticHandler. 211 const DiagnosticHandler *getDiagHandlerPtr() const; 212 213 /// getDiagnosticHandler - transfers owenership of DiagnosticHandler unique_ptr 214 /// to caller. 215 std::unique_ptr<DiagnosticHandler> getDiagnosticHandler(); 216 217 /// Return if a code hotness metric should be included in optimization 218 /// diagnostics. 219 bool getDiagnosticsHotnessRequested() const; 220 /// Set if a code hotness metric should be included in optimization 221 /// diagnostics. 222 void setDiagnosticsHotnessRequested(bool Requested); 223 224 /// Return the minimum hotness value a diagnostic would need in order 225 /// to be included in optimization diagnostics. 226 /// 227 /// Three possible return values: 228 /// 0 - threshold is disabled. Everything will be printed out. 229 /// positive int - threshold is set. 230 /// UINT64_MAX - threshold is not yet set, and needs to be synced from 231 /// profile summary. Note that in case of missing profile 232 /// summary, threshold will be kept at "MAX", effectively 233 /// suppresses all remarks output. 234 uint64_t getDiagnosticsHotnessThreshold() const; 235 236 /// Set the minimum hotness value a diagnostic needs in order to be 237 /// included in optimization diagnostics. 238 void setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold); 239 240 /// Return if hotness threshold is requested from PSI. 241 bool isDiagnosticsHotnessThresholdSetFromPSI() const; 242 243 /// The "main remark streamer" used by all the specialized remark streamers. 244 /// This streamer keeps generic remark metadata in memory throughout the life 245 /// of the LLVMContext. This metadata may be emitted in a section in object 246 /// files depending on the format requirements. 247 /// 248 /// All specialized remark streamers should convert remarks to 249 /// llvm::remarks::Remark and emit them through this streamer. 250 remarks::RemarkStreamer *getMainRemarkStreamer(); 251 const remarks::RemarkStreamer *getMainRemarkStreamer() const; 252 void setMainRemarkStreamer( 253 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer); 254 255 /// The "LLVM remark streamer" used by LLVM to serialize remark diagnostics 256 /// comming from IR and MIR passes. 257 /// 258 /// If it does not exist, diagnostics are not saved in a file but only emitted 259 /// via the diagnostic handler. 260 LLVMRemarkStreamer *getLLVMRemarkStreamer(); 261 const LLVMRemarkStreamer *getLLVMRemarkStreamer() const; 262 void 263 setLLVMRemarkStreamer(std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer); 264 265 /// Get the prefix that should be printed in front of a diagnostic of 266 /// the given \p Severity 267 static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity); 268 269 /// Report a message to the currently installed diagnostic handler. 270 /// 271 /// This function returns, in particular in the case of error reporting 272 /// (DI.Severity == \a DS_Error), so the caller should leave the compilation 273 /// process in a self-consistent state, even though the generated code 274 /// need not be correct. 275 /// 276 /// The diagnostic message will be implicitly prefixed with a severity keyword 277 /// according to \p DI.getSeverity(), i.e., "error: " for \a DS_Error, 278 /// "warning: " for \a DS_Warning, and "note: " for \a DS_Note. 279 void diagnose(const DiagnosticInfo &DI); 280 281 /// Registers a yield callback with the given context. 282 /// 283 /// The yield callback function may be called by LLVM to transfer control back 284 /// to the client that invoked the LLVM compilation. This can be used to yield 285 /// control of the thread, or perform periodic work needed by the client. 286 /// There is no guaranteed frequency at which callbacks must occur; in fact, 287 /// the client is not guaranteed to ever receive this callback. It is at the 288 /// sole discretion of LLVM to do so and only if it can guarantee that 289 /// suspending the thread won't block any forward progress in other LLVM 290 /// contexts in the same process. 291 /// 292 /// At a suspend point, the state of the current LLVM context is intentionally 293 /// undefined. No assumptions about it can or should be made. Only LLVM 294 /// context API calls that explicitly state that they can be used during a 295 /// yield callback are allowed to be used. Any other API calls into the 296 /// context are not supported until the yield callback function returns 297 /// control to LLVM. Other LLVM contexts are unaffected by this restriction. 298 void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle); 299 300 /// Calls the yield callback (if applicable). 301 /// 302 /// This transfers control of the current thread back to the client, which may 303 /// suspend the current thread. Only call this method when LLVM doesn't hold 304 /// any global mutex or cannot block the execution in another LLVM context. 305 void yield(); 306 307 /// emitError - Emit an error message to the currently installed error handler 308 /// with optional location information. This function returns, so code should 309 /// be prepared to drop the erroneous construct on the floor and "not crash". 310 /// The generated code need not be correct. The error message will be 311 /// implicitly prefixed with "error: " and should not end with a ".". 312 void emitError(unsigned LocCookie, const Twine &ErrorStr); 313 void emitError(const Instruction *I, const Twine &ErrorStr); 314 void emitError(const Twine &ErrorStr); 315 316 /// Access the object which can disable optional passes and individual 317 /// optimizations at compile time. 318 OptPassGate &getOptPassGate() const; 319 320 /// Set the object which can disable optional passes and individual 321 /// optimizations at compile time. 322 /// 323 /// The lifetime of the object must be guaranteed to extend as long as the 324 /// LLVMContext is used by compilation. 325 void setOptPassGate(OptPassGate&); 326 327 private: 328 // Module needs access to the add/removeModule methods. 329 friend class Module; 330 331 /// addModule - Register a module as being instantiated in this context. If 332 /// the context is deleted, the module will be deleted as well. 333 void addModule(Module*); 334 335 /// removeModule - Unregister a module from this context. 336 void removeModule(Module*); 337 }; 338 339 // Create wrappers for C Binding types (see CBindingWrapping.h). 340 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef) 341 342 /* Specialized opaque context conversions. 343 */ 344 inline LLVMContext **unwrap(LLVMContextRef* Tys) { 345 return reinterpret_cast<LLVMContext**>(Tys); 346 } 347 348 inline LLVMContextRef *wrap(const LLVMContext **Tys) { 349 return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys)); 350 } 351 352 } // end namespace llvm 353 354 #endif // LLVM_IR_LLVMCONTEXT_H 355