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" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/IR/DiagnosticInfo.h" 21 #include "llvm/IR/DiagnosticPrinter.h" 22 #include "llvm/IR/LLVMRemarkStreamer.h" 23 #include "llvm/IR/Metadata.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/Remarks/RemarkStreamer.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <cassert> 30 #include <cstdlib> 31 #include <string> 32 #include <utility> 33 34 using namespace llvm; 35 36 LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { 37 // Create the fixed metadata kinds. This is done in the same order as the 38 // MD_* enum values so that they correspond. 39 std::pair<unsigned, StringRef> MDKinds[] = { 40 #define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name}, 41 #include "llvm/IR/FixedMetadataKinds.def" 42 #undef LLVM_FIXED_MD_KIND 43 }; 44 45 for (auto &MDKind : MDKinds) { 46 unsigned ID = getMDKindID(MDKind.second); 47 assert(ID == MDKind.first && "metadata kind id drifted"); 48 (void)ID; 49 } 50 51 auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); 52 assert(DeoptEntry->second == LLVMContext::OB_deopt && 53 "deopt operand bundle id drifted!"); 54 (void)DeoptEntry; 55 56 auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); 57 assert(FuncletEntry->second == LLVMContext::OB_funclet && 58 "funclet operand bundle id drifted!"); 59 (void)FuncletEntry; 60 61 auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); 62 assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && 63 "gc-transition operand bundle id drifted!"); 64 (void)GCTransitionEntry; 65 66 auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget"); 67 assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget && 68 "cfguardtarget operand bundle id drifted!"); 69 (void)CFGuardTargetEntry; 70 71 auto *PreallocatedEntry = pImpl->getOrInsertBundleTag("preallocated"); 72 assert(PreallocatedEntry->second == LLVMContext::OB_preallocated && 73 "preallocated operand bundle id drifted!"); 74 (void)PreallocatedEntry; 75 76 auto *GCLiveEntry = pImpl->getOrInsertBundleTag("gc-live"); 77 assert(GCLiveEntry->second == LLVMContext::OB_gc_live && 78 "gc-transition operand bundle id drifted!"); 79 (void)GCLiveEntry; 80 81 auto *ClangAttachedCall = 82 pImpl->getOrInsertBundleTag("clang.arc.attachedcall"); 83 assert(ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall && 84 "clang.arc.attachedcall operand bundle id drifted!"); 85 (void)ClangAttachedCall; 86 87 SyncScope::ID SingleThreadSSID = 88 pImpl->getOrInsertSyncScopeID("singlethread"); 89 assert(SingleThreadSSID == SyncScope::SingleThread && 90 "singlethread synchronization scope ID drifted!"); 91 (void)SingleThreadSSID; 92 93 SyncScope::ID SystemSSID = 94 pImpl->getOrInsertSyncScopeID(""); 95 assert(SystemSSID == SyncScope::System && 96 "system synchronization scope ID drifted!"); 97 (void)SystemSSID; 98 } 99 100 LLVMContext::~LLVMContext() { delete pImpl; } 101 102 void LLVMContext::addModule(Module *M) { 103 pImpl->OwnedModules.insert(M); 104 } 105 106 void LLVMContext::removeModule(Module *M) { 107 pImpl->OwnedModules.erase(M); 108 } 109 110 //===----------------------------------------------------------------------===// 111 // Recoverable Backend Errors 112 //===----------------------------------------------------------------------===// 113 114 void LLVMContext::setDiagnosticHandlerCallBack( 115 DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, 116 void *DiagnosticContext, bool RespectFilters) { 117 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler; 118 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext; 119 pImpl->RespectDiagnosticFilters = RespectFilters; 120 } 121 122 void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, 123 bool RespectFilters) { 124 pImpl->DiagHandler = std::move(DH); 125 pImpl->RespectDiagnosticFilters = RespectFilters; 126 } 127 128 void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) { 129 pImpl->DiagnosticsHotnessRequested = Requested; 130 } 131 bool LLVMContext::getDiagnosticsHotnessRequested() const { 132 return pImpl->DiagnosticsHotnessRequested; 133 } 134 135 void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) { 136 pImpl->DiagnosticsHotnessThreshold = Threshold; 137 } 138 139 uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { 140 return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX); 141 } 142 143 bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const { 144 return !pImpl->DiagnosticsHotnessThreshold.hasValue(); 145 } 146 147 remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() { 148 return pImpl->MainRemarkStreamer.get(); 149 } 150 const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const { 151 return const_cast<LLVMContext *>(this)->getMainRemarkStreamer(); 152 } 153 void LLVMContext::setMainRemarkStreamer( 154 std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) { 155 pImpl->MainRemarkStreamer = std::move(RemarkStreamer); 156 } 157 158 LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() { 159 return pImpl->LLVMRS.get(); 160 } 161 const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const { 162 return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer(); 163 } 164 void LLVMContext::setLLVMRemarkStreamer( 165 std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) { 166 pImpl->LLVMRS = std::move(RemarkStreamer); 167 } 168 169 DiagnosticHandler::DiagnosticHandlerTy 170 LLVMContext::getDiagnosticHandlerCallBack() const { 171 return pImpl->DiagHandler->DiagHandlerCallback; 172 } 173 174 void *LLVMContext::getDiagnosticContext() const { 175 return pImpl->DiagHandler->DiagnosticContext; 176 } 177 178 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 179 { 180 pImpl->YieldCallback = Callback; 181 pImpl->YieldOpaqueHandle = OpaqueHandle; 182 } 183 184 void LLVMContext::yield() { 185 if (pImpl->YieldCallback) 186 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 187 } 188 189 void LLVMContext::emitError(const Twine &ErrorStr) { 190 diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 191 } 192 193 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 194 assert (I && "Invalid instruction"); 195 diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 196 } 197 198 static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { 199 // Optimization remarks are selective. They need to check whether the regexp 200 // pattern, passed via one of the -pass-remarks* flags, matches the name of 201 // the pass that is emitting the diagnostic. If there is no match, ignore the 202 // diagnostic and return. 203 // 204 // Also noisy remarks are only enabled if we have hotness information to sort 205 // them. 206 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 207 return Remark->isEnabled() && 208 (!Remark->isVerbose() || Remark->getHotness()); 209 210 return true; 211 } 212 213 const char * 214 LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { 215 switch (Severity) { 216 case DS_Error: 217 return "error"; 218 case DS_Warning: 219 return "warning"; 220 case DS_Remark: 221 return "remark"; 222 case DS_Note: 223 return "note"; 224 } 225 llvm_unreachable("Unknown DiagnosticSeverity"); 226 } 227 228 void LLVMContext::diagnose(const DiagnosticInfo &DI) { 229 if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 230 if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer()) 231 RS->emit(*OptDiagBase); 232 233 // If there is a report handler, use it. 234 if (pImpl->DiagHandler && 235 (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && 236 pImpl->DiagHandler->handleDiagnostics(DI)) 237 return; 238 239 if (!isDiagnosticEnabled(DI)) 240 return; 241 242 // Otherwise, print the message with a prefix based on the severity. 243 DiagnosticPrinterRawOStream DP(errs()); 244 errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 245 DI.print(DP); 246 errs() << "\n"; 247 if (DI.getSeverity() == DS_Error) 248 exit(1); 249 } 250 251 void LLVMContext::emitError(uint64_t LocCookie, const Twine &ErrorStr) { 252 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 253 } 254 255 //===----------------------------------------------------------------------===// 256 // Metadata Kind Uniquing 257 //===----------------------------------------------------------------------===// 258 259 /// Return a unique non-zero ID for the specified metadata kind. 260 unsigned LLVMContext::getMDKindID(StringRef Name) const { 261 // If this is new, assign it its ID. 262 return pImpl->CustomMDKindNames.insert( 263 std::make_pair( 264 Name, pImpl->CustomMDKindNames.size())) 265 .first->second; 266 } 267 268 /// getHandlerNames - Populate client-supplied smallvector using custom 269 /// metadata name and ID. 270 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 271 Names.resize(pImpl->CustomMDKindNames.size()); 272 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 273 E = pImpl->CustomMDKindNames.end(); I != E; ++I) 274 Names[I->second] = I->first(); 275 } 276 277 void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { 278 pImpl->getOperandBundleTags(Tags); 279 } 280 281 StringMapEntry<uint32_t> * 282 LLVMContext::getOrInsertBundleTag(StringRef TagName) const { 283 return pImpl->getOrInsertBundleTag(TagName); 284 } 285 286 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { 287 return pImpl->getOperandBundleTagID(Tag); 288 } 289 290 SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) { 291 return pImpl->getOrInsertSyncScopeID(SSN); 292 } 293 294 void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const { 295 pImpl->getSyncScopeNames(SSNs); 296 } 297 298 void LLVMContext::setGC(const Function &Fn, std::string GCName) { 299 auto It = pImpl->GCNames.find(&Fn); 300 301 if (It == pImpl->GCNames.end()) { 302 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); 303 return; 304 } 305 It->second = std::move(GCName); 306 } 307 308 const std::string &LLVMContext::getGC(const Function &Fn) { 309 return pImpl->GCNames[&Fn]; 310 } 311 312 void LLVMContext::deleteGC(const Function &Fn) { 313 pImpl->GCNames.erase(&Fn); 314 } 315 316 bool LLVMContext::shouldDiscardValueNames() const { 317 return pImpl->DiscardValueNames; 318 } 319 320 bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } 321 322 void LLVMContext::enableDebugTypeODRUniquing() { 323 if (pImpl->DITypeMap) 324 return; 325 326 pImpl->DITypeMap.emplace(); 327 } 328 329 void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } 330 331 void LLVMContext::setDiscardValueNames(bool Discard) { 332 pImpl->DiscardValueNames = Discard; 333 } 334 335 OptPassGate &LLVMContext::getOptPassGate() const { 336 return pImpl->getOptPassGate(); 337 } 338 339 void LLVMContext::setOptPassGate(OptPassGate& OPG) { 340 pImpl->setOptPassGate(OPG); 341 } 342 343 const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { 344 return pImpl->DiagHandler.get(); 345 } 346 347 std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() { 348 return std::move(pImpl->DiagHandler); 349 } 350 351 bool LLVMContext::supportsTypedPointers() const { 352 return !pImpl->ForceOpaquePointers; 353 } 354