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 "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "LLVMContextImpl.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 }; 62 63 for (auto &MDKind : MDKinds) { 64 unsigned ID = getMDKindID(MDKind.second); 65 assert(ID == MDKind.first && "metadata kind id drifted"); 66 (void)ID; 67 } 68 69 auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); 70 assert(DeoptEntry->second == LLVMContext::OB_deopt && 71 "deopt operand bundle id drifted!"); 72 (void)DeoptEntry; 73 74 auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); 75 assert(FuncletEntry->second == LLVMContext::OB_funclet && 76 "funclet operand bundle id drifted!"); 77 (void)FuncletEntry; 78 79 auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); 80 assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && 81 "gc-transition operand bundle id drifted!"); 82 (void)GCTransitionEntry; 83 } 84 85 LLVMContext::~LLVMContext() { delete pImpl; } 86 87 void LLVMContext::addModule(Module *M) { 88 pImpl->OwnedModules.insert(M); 89 } 90 91 void LLVMContext::removeModule(Module *M) { 92 pImpl->OwnedModules.erase(M); 93 } 94 95 //===----------------------------------------------------------------------===// 96 // Recoverable Backend Errors 97 //===----------------------------------------------------------------------===// 98 99 void LLVMContext:: 100 setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, 101 void *DiagContext) { 102 pImpl->InlineAsmDiagHandler = DiagHandler; 103 pImpl->InlineAsmDiagContext = DiagContext; 104 } 105 106 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by 107 /// setInlineAsmDiagnosticHandler. 108 LLVMContext::InlineAsmDiagHandlerTy 109 LLVMContext::getInlineAsmDiagnosticHandler() const { 110 return pImpl->InlineAsmDiagHandler; 111 } 112 113 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by 114 /// setInlineAsmDiagnosticHandler. 115 void *LLVMContext::getInlineAsmDiagnosticContext() const { 116 return pImpl->InlineAsmDiagContext; 117 } 118 119 void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, 120 void *DiagnosticContext, 121 bool RespectFilters) { 122 pImpl->DiagnosticHandler = DiagnosticHandler; 123 pImpl->DiagnosticContext = DiagnosticContext; 124 pImpl->RespectDiagnosticFilters = RespectFilters; 125 } 126 127 void LLVMContext::setDiagnosticHotnessRequested(bool Requested) { 128 pImpl->DiagnosticHotnessRequested = Requested; 129 } 130 bool LLVMContext::getDiagnosticHotnessRequested() const { 131 return pImpl->DiagnosticHotnessRequested; 132 } 133 134 yaml::Output *LLVMContext::getDiagnosticsOutputFile() { 135 return pImpl->DiagnosticsOutputFile.get(); 136 } 137 138 void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) { 139 pImpl->DiagnosticsOutputFile = std::move(F); 140 } 141 142 LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { 143 return pImpl->DiagnosticHandler; 144 } 145 146 void *LLVMContext::getDiagnosticContext() const { 147 return pImpl->DiagnosticContext; 148 } 149 150 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 151 { 152 pImpl->YieldCallback = Callback; 153 pImpl->YieldOpaqueHandle = OpaqueHandle; 154 } 155 156 void LLVMContext::yield() { 157 if (pImpl->YieldCallback) 158 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 159 } 160 161 void LLVMContext::emitError(const Twine &ErrorStr) { 162 diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 163 } 164 165 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 166 assert (I && "Invalid instruction"); 167 diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 168 } 169 170 static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { 171 // Optimization remarks are selective. They need to check whether the regexp 172 // pattern, passed via one of the -pass-remarks* flags, matches the name of 173 // the pass that is emitting the diagnostic. If there is no match, ignore the 174 // diagnostic and return. 175 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 176 return Remark->isEnabled(); 177 178 return true; 179 } 180 181 const char * 182 LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { 183 switch (Severity) { 184 case DS_Error: 185 return "error"; 186 case DS_Warning: 187 return "warning"; 188 case DS_Remark: 189 return "remark"; 190 case DS_Note: 191 return "note"; 192 } 193 llvm_unreachable("Unknown DiagnosticSeverity"); 194 } 195 196 void LLVMContext::diagnose(const DiagnosticInfo &DI) { 197 // If there is a report handler, use it. 198 if (pImpl->DiagnosticHandler) { 199 if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) 200 pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); 201 return; 202 } 203 204 if (!isDiagnosticEnabled(DI)) 205 return; 206 207 // Otherwise, print the message with a prefix based on the severity. 208 DiagnosticPrinterRawOStream DP(errs()); 209 errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 210 DI.print(DP); 211 errs() << "\n"; 212 if (DI.getSeverity() == DS_Error) 213 exit(1); 214 } 215 216 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { 217 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 218 } 219 220 //===----------------------------------------------------------------------===// 221 // Metadata Kind Uniquing 222 //===----------------------------------------------------------------------===// 223 224 /// Return a unique non-zero ID for the specified metadata kind. 225 unsigned LLVMContext::getMDKindID(StringRef Name) const { 226 // If this is new, assign it its ID. 227 return pImpl->CustomMDKindNames.insert( 228 std::make_pair( 229 Name, pImpl->CustomMDKindNames.size())) 230 .first->second; 231 } 232 233 /// getHandlerNames - Populate client-supplied smallvector using custom 234 /// metadata name and ID. 235 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 236 Names.resize(pImpl->CustomMDKindNames.size()); 237 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 238 E = pImpl->CustomMDKindNames.end(); I != E; ++I) 239 Names[I->second] = I->first(); 240 } 241 242 void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { 243 pImpl->getOperandBundleTags(Tags); 244 } 245 246 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { 247 return pImpl->getOperandBundleTagID(Tag); 248 } 249 250 void LLVMContext::setGC(const Function &Fn, std::string GCName) { 251 auto It = pImpl->GCNames.find(&Fn); 252 253 if (It == pImpl->GCNames.end()) { 254 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); 255 return; 256 } 257 It->second = std::move(GCName); 258 } 259 260 const std::string &LLVMContext::getGC(const Function &Fn) { 261 return pImpl->GCNames[&Fn]; 262 } 263 264 void LLVMContext::deleteGC(const Function &Fn) { 265 pImpl->GCNames.erase(&Fn); 266 } 267 268 bool LLVMContext::shouldDiscardValueNames() const { 269 return pImpl->DiscardValueNames; 270 } 271 272 bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } 273 274 void LLVMContext::enableDebugTypeODRUniquing() { 275 if (pImpl->DITypeMap) 276 return; 277 278 pImpl->DITypeMap.emplace(); 279 } 280 281 void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } 282 283 void LLVMContext::setDiscardValueNames(bool Discard) { 284 pImpl->DiscardValueNames = Discard; 285 } 286 287 OptBisect &LLVMContext::getOptBisect() { 288 return pImpl->getOptBisect(); 289 } 290