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