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/Remarks/RemarkStreamer.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <cassert> 28 #include <cstdlib> 29 #include <string> 30 #include <utility> 31 32 using namespace llvm; 33 34 LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { 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 = 107 pImpl->getOrInsertSyncScopeID(""); 108 assert(SystemSSID == SyncScope::System && 109 "system synchronization scope ID drifted!"); 110 (void)SystemSSID; 111 } 112 113 LLVMContext::~LLVMContext() { delete pImpl; } 114 115 void LLVMContext::addModule(Module *M) { 116 pImpl->OwnedModules.insert(M); 117 } 118 119 void LLVMContext::removeModule(Module *M) { 120 pImpl->OwnedModules.erase(M); 121 pImpl->MachineFunctionNums.erase(M); 122 } 123 124 unsigned LLVMContext::generateMachineFunctionNum(Function &F) { 125 Module *M = F.getParent(); 126 assert(pImpl->OwnedModules.contains(M) && "Unexpected module!"); 127 return pImpl->MachineFunctionNums[M]++; 128 } 129 130 //===----------------------------------------------------------------------===// 131 // Recoverable Backend Errors 132 //===----------------------------------------------------------------------===// 133 134 void LLVMContext::setDiagnosticHandlerCallBack( 135 DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, 136 void *DiagnosticContext, bool RespectFilters) { 137 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler; 138 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext; 139 pImpl->RespectDiagnosticFilters = RespectFilters; 140 } 141 142 void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, 143 bool RespectFilters) { 144 pImpl->DiagHandler = std::move(DH); 145 pImpl->RespectDiagnosticFilters = RespectFilters; 146 } 147 148 void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) { 149 pImpl->DiagnosticsHotnessRequested = Requested; 150 } 151 bool LLVMContext::getDiagnosticsHotnessRequested() const { 152 return pImpl->DiagnosticsHotnessRequested; 153 } 154 155 void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) { 156 pImpl->DiagnosticsHotnessThreshold = Threshold; 157 } 158 void LLVMContext::setMisExpectWarningRequested(bool Requested) { 159 pImpl->MisExpectWarningRequested = Requested; 160 } 161 bool LLVMContext::getMisExpectWarningRequested() const { 162 return pImpl->MisExpectWarningRequested; 163 } 164 uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { 165 return pImpl->DiagnosticsHotnessThreshold.value_or(UINT64_MAX); 166 } 167 void LLVMContext::setDiagnosticsMisExpectTolerance( 168 std::optional<uint32_t> Tolerance) { 169 pImpl->DiagnosticsMisExpectTolerance = Tolerance; 170 } 171 uint32_t LLVMContext::getDiagnosticsMisExpectTolerance() const { 172 return pImpl->DiagnosticsMisExpectTolerance.value_or(0); 173 } 174 175 bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const { 176 return !pImpl->DiagnosticsHotnessThreshold.has_value(); 177 } 178 179 remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() { 180 return pImpl->MainRemarkStreamer.get(); 181 } 182 const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const { 183 return const_cast<LLVMContext *>(this)->getMainRemarkStreamer(); 184 } 185 void LLVMContext::setMainRemarkStreamer( 186 std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) { 187 pImpl->MainRemarkStreamer = std::move(RemarkStreamer); 188 } 189 190 LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() { 191 return pImpl->LLVMRS.get(); 192 } 193 const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const { 194 return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer(); 195 } 196 void LLVMContext::setLLVMRemarkStreamer( 197 std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) { 198 pImpl->LLVMRS = std::move(RemarkStreamer); 199 } 200 201 DiagnosticHandler::DiagnosticHandlerTy 202 LLVMContext::getDiagnosticHandlerCallBack() const { 203 return pImpl->DiagHandler->DiagHandlerCallback; 204 } 205 206 void *LLVMContext::getDiagnosticContext() const { 207 return pImpl->DiagHandler->DiagnosticContext; 208 } 209 210 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 211 { 212 pImpl->YieldCallback = Callback; 213 pImpl->YieldOpaqueHandle = OpaqueHandle; 214 } 215 216 void LLVMContext::yield() { 217 if (pImpl->YieldCallback) 218 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 219 } 220 221 void LLVMContext::emitError(const Twine &ErrorStr) { 222 diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 223 } 224 225 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 226 assert (I && "Invalid instruction"); 227 diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 228 } 229 230 static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { 231 // Optimization remarks are selective. They need to check whether the regexp 232 // pattern, passed via one of the -pass-remarks* flags, matches the name of 233 // the pass that is emitting the diagnostic. If there is no match, ignore the 234 // diagnostic and return. 235 // 236 // Also noisy remarks are only enabled if we have hotness information to sort 237 // them. 238 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 239 return Remark->isEnabled() && 240 (!Remark->isVerbose() || Remark->getHotness()); 241 242 return true; 243 } 244 245 const char * 246 LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { 247 switch (Severity) { 248 case DS_Error: 249 return "error"; 250 case DS_Warning: 251 return "warning"; 252 case DS_Remark: 253 return "remark"; 254 case DS_Note: 255 return "note"; 256 } 257 llvm_unreachable("Unknown DiagnosticSeverity"); 258 } 259 260 void LLVMContext::diagnose(const DiagnosticInfo &DI) { 261 if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 262 if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer()) 263 RS->emit(*OptDiagBase); 264 265 // If there is a report handler, use it. 266 if (pImpl->DiagHandler) { 267 if (DI.getSeverity() == DS_Error) 268 pImpl->DiagHandler->HasErrors = true; 269 if ((!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && 270 pImpl->DiagHandler->handleDiagnostics(DI)) 271 return; 272 } 273 274 if (!isDiagnosticEnabled(DI)) 275 return; 276 277 // Otherwise, print the message with a prefix based on the severity. 278 DiagnosticPrinterRawOStream DP(errs()); 279 errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 280 DI.print(DP); 281 errs() << "\n"; 282 if (DI.getSeverity() == DS_Error) 283 exit(1); 284 } 285 286 void LLVMContext::emitError(uint64_t LocCookie, const Twine &ErrorStr) { 287 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 288 } 289 290 //===----------------------------------------------------------------------===// 291 // Metadata Kind Uniquing 292 //===----------------------------------------------------------------------===// 293 294 /// Return a unique non-zero ID for the specified metadata kind. 295 unsigned LLVMContext::getMDKindID(StringRef Name) const { 296 // If this is new, assign it its ID. 297 return pImpl->CustomMDKindNames.insert( 298 std::make_pair( 299 Name, pImpl->CustomMDKindNames.size())) 300 .first->second; 301 } 302 303 /// getHandlerNames - Populate client-supplied smallvector using custom 304 /// metadata name and ID. 305 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 306 Names.resize(pImpl->CustomMDKindNames.size()); 307 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 308 E = pImpl->CustomMDKindNames.end(); I != E; ++I) 309 Names[I->second] = I->first(); 310 } 311 312 void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { 313 pImpl->getOperandBundleTags(Tags); 314 } 315 316 StringMapEntry<uint32_t> * 317 LLVMContext::getOrInsertBundleTag(StringRef TagName) const { 318 return pImpl->getOrInsertBundleTag(TagName); 319 } 320 321 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { 322 return pImpl->getOperandBundleTagID(Tag); 323 } 324 325 SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) { 326 return pImpl->getOrInsertSyncScopeID(SSN); 327 } 328 329 void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const { 330 pImpl->getSyncScopeNames(SSNs); 331 } 332 333 void LLVMContext::setGC(const Function &Fn, std::string GCName) { 334 auto It = pImpl->GCNames.find(&Fn); 335 336 if (It == pImpl->GCNames.end()) { 337 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); 338 return; 339 } 340 It->second = std::move(GCName); 341 } 342 343 const std::string &LLVMContext::getGC(const Function &Fn) { 344 return pImpl->GCNames[&Fn]; 345 } 346 347 void LLVMContext::deleteGC(const Function &Fn) { 348 pImpl->GCNames.erase(&Fn); 349 } 350 351 bool LLVMContext::shouldDiscardValueNames() const { 352 return pImpl->DiscardValueNames; 353 } 354 355 bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } 356 357 void LLVMContext::enableDebugTypeODRUniquing() { 358 if (pImpl->DITypeMap) 359 return; 360 361 pImpl->DITypeMap.emplace(); 362 } 363 364 void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } 365 366 void LLVMContext::setDiscardValueNames(bool Discard) { 367 pImpl->DiscardValueNames = Discard; 368 } 369 370 OptPassGate &LLVMContext::getOptPassGate() const { 371 return pImpl->getOptPassGate(); 372 } 373 374 void LLVMContext::setOptPassGate(OptPassGate& OPG) { 375 pImpl->setOptPassGate(OPG); 376 } 377 378 const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { 379 return pImpl->DiagHandler.get(); 380 } 381 382 std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() { 383 return std::move(pImpl->DiagHandler); 384 } 385 386 void LLVMContext::setOpaquePointers(bool Enable) const { 387 assert(Enable && "Cannot disable opaque pointers"); 388 } 389 390 bool LLVMContext::supportsTypedPointers() const { 391 return false; 392 } 393 394 StringRef LLVMContext::getDefaultTargetCPU() { 395 return pImpl->DefaultTargetCPU; 396 } 397 398 void LLVMContext::setDefaultTargetCPU(StringRef CPU) { 399 pImpl->DefaultTargetCPU = CPU; 400 } 401 402 StringRef LLVMContext::getDefaultTargetFeatures() { 403 return pImpl->DefaultTargetFeatures; 404 } 405 406 void LLVMContext::setDefaultTargetFeatures(StringRef Features) { 407 pImpl->DefaultTargetFeatures = Features; 408 } 409