LLVMContext.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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. #include "llvm/IR/LLVMContext.h"
  15. #include "LLVMContextImpl.h"
  16. #include "llvm/IR/Constants.h"
  17. #include "llvm/IR/DebugLoc.h"
  18. #include "llvm/IR/DiagnosticInfo.h"
  19. #include "llvm/IR/DiagnosticPrinter.h"
  20. #include "llvm/IR/Instruction.h"
  21. #include "llvm/IR/Metadata.h"
  22. #include "llvm/Support/ManagedStatic.h"
  23. #include "llvm/Support/SourceMgr.h"
  24. #include <cctype>
  25. using namespace llvm;
  26. static ManagedStatic<LLVMContext> GlobalContext;
  27. LLVMContext& llvm::getGlobalContext() {
  28. return *GlobalContext;
  29. }
  30. LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
  31. // Create the fixed metadata kinds. This is done in the same order as the
  32. // MD_* enum values so that they correspond.
  33. // Create the 'dbg' metadata kind.
  34. unsigned DbgID = getMDKindID("dbg");
  35. assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
  36. // Create the 'tbaa' metadata kind.
  37. unsigned TBAAID = getMDKindID("tbaa");
  38. assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;
  39. // Create the 'prof' metadata kind.
  40. unsigned ProfID = getMDKindID("prof");
  41. assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
  42. // Create the 'fpmath' metadata kind.
  43. unsigned FPAccuracyID = getMDKindID("fpmath");
  44. assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
  45. (void)FPAccuracyID;
  46. // Create the 'range' metadata kind.
  47. unsigned RangeID = getMDKindID("range");
  48. assert(RangeID == MD_range && "range kind id drifted");
  49. (void)RangeID;
  50. // Create the 'tbaa.struct' metadata kind.
  51. unsigned TBAAStructID = getMDKindID("tbaa.struct");
  52. assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
  53. (void)TBAAStructID;
  54. // Create the 'invariant.load' metadata kind.
  55. unsigned InvariantLdId = getMDKindID("invariant.load");
  56. assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
  57. (void)InvariantLdId;
  58. // Create the 'alias.scope' metadata kind.
  59. unsigned AliasScopeID = getMDKindID("alias.scope");
  60. assert(AliasScopeID == MD_alias_scope && "alias.scope kind id drifted");
  61. (void)AliasScopeID;
  62. // Create the 'noalias' metadata kind.
  63. unsigned NoAliasID = getMDKindID("noalias");
  64. assert(NoAliasID == MD_noalias && "noalias kind id drifted");
  65. (void)NoAliasID;
  66. // Create the 'nontemporal' metadata kind.
  67. unsigned NonTemporalID = getMDKindID("nontemporal");
  68. assert(NonTemporalID == MD_nontemporal && "nontemporal kind id drifted");
  69. (void)NonTemporalID;
  70. // Create the 'llvm.mem.parallel_loop_access' metadata kind.
  71. unsigned MemParallelLoopAccessID = getMDKindID("llvm.mem.parallel_loop_access");
  72. assert(MemParallelLoopAccessID == MD_mem_parallel_loop_access &&
  73. "mem_parallel_loop_access kind id drifted");
  74. (void)MemParallelLoopAccessID;
  75. // Create the 'nonnull' metadata kind.
  76. unsigned NonNullID = getMDKindID("nonnull");
  77. assert(NonNullID == MD_nonnull && "nonnull kind id drifted");
  78. (void)NonNullID;
  79. // Create the 'dereferenceable' metadata kind.
  80. unsigned DereferenceableID = getMDKindID("dereferenceable");
  81. assert(DereferenceableID == MD_dereferenceable &&
  82. "dereferenceable kind id drifted");
  83. (void)DereferenceableID;
  84. // Create the 'dereferenceable_or_null' metadata kind.
  85. unsigned DereferenceableOrNullID = getMDKindID("dereferenceable_or_null");
  86. assert(DereferenceableOrNullID == MD_dereferenceable_or_null &&
  87. "dereferenceable_or_null kind id drifted");
  88. (void)DereferenceableOrNullID;
  89. }
  90. LLVMContext::~LLVMContext() { delete pImpl; }
  91. void LLVMContext::addModule(Module *M) {
  92. pImpl->OwnedModules.insert(M);
  93. }
  94. void LLVMContext::removeModule(Module *M) {
  95. pImpl->OwnedModules.erase(M);
  96. }
  97. //===----------------------------------------------------------------------===//
  98. // Recoverable Backend Errors
  99. //===----------------------------------------------------------------------===//
  100. void LLVMContext::
  101. setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
  102. void *DiagContext) {
  103. pImpl->InlineAsmDiagHandler = DiagHandler;
  104. pImpl->InlineAsmDiagContext = DiagContext;
  105. }
  106. /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
  107. /// setInlineAsmDiagnosticHandler.
  108. LLVMContext::InlineAsmDiagHandlerTy
  109. LLVMContext::getInlineAsmDiagnosticHandler() const {
  110. return pImpl->InlineAsmDiagHandler;
  111. }
  112. /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
  113. /// setInlineAsmDiagnosticHandler.
  114. void *LLVMContext::getInlineAsmDiagnosticContext() const {
  115. return pImpl->InlineAsmDiagContext;
  116. }
  117. void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
  118. void *DiagnosticContext,
  119. bool RespectFilters) {
  120. pImpl->DiagnosticHandler = DiagnosticHandler;
  121. pImpl->DiagnosticContext = DiagnosticContext;
  122. pImpl->RespectDiagnosticFilters = RespectFilters;
  123. }
  124. LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
  125. return pImpl->DiagnosticHandler;
  126. }
  127. void *LLVMContext::getDiagnosticContext() const {
  128. return pImpl->DiagnosticContext;
  129. }
  130. void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
  131. {
  132. pImpl->YieldCallback = Callback;
  133. pImpl->YieldOpaqueHandle = OpaqueHandle;
  134. }
  135. void LLVMContext::yield() {
  136. if (pImpl->YieldCallback)
  137. pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
  138. }
  139. void LLVMContext::emitError(const Twine &ErrorStr) {
  140. diagnose(DiagnosticInfoInlineAsm(ErrorStr));
  141. }
  142. void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  143. assert (I && "Invalid instruction");
  144. diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
  145. }
  146. static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
  147. // Optimization remarks are selective. They need to check whether the regexp
  148. // pattern, passed via one of the -pass-remarks* flags, matches the name of
  149. // the pass that is emitting the diagnostic. If there is no match, ignore the
  150. // diagnostic and return.
  151. switch (DI.getKind()) {
  152. case llvm::DK_OptimizationRemark:
  153. if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled())
  154. return false;
  155. break;
  156. case llvm::DK_OptimizationRemarkMissed:
  157. if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled())
  158. return false;
  159. break;
  160. case llvm::DK_OptimizationRemarkAnalysis:
  161. if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled())
  162. return false;
  163. break;
  164. default:
  165. break;
  166. }
  167. return true;
  168. }
  169. static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
  170. switch (Severity) {
  171. case DS_Error:
  172. return "error";
  173. case DS_Warning:
  174. return "warning";
  175. case DS_Remark:
  176. return "remark";
  177. case DS_Note:
  178. return "note";
  179. }
  180. llvm_unreachable("Unknown DiagnosticSeverity");
  181. }
  182. void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  183. // If there is a report handler, use it.
  184. if (pImpl->DiagnosticHandler) {
  185. if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI))
  186. pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
  187. return;
  188. }
  189. if (!isDiagnosticEnabled(DI))
  190. return;
  191. // Otherwise, print the message with a prefix based on the severity.
  192. DiagnosticPrinterRawOStream DP(errs());
  193. errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
  194. DI.print(DP);
  195. errs() << "\n";
  196. if (DI.getSeverity() == DS_Error)
  197. // exit(1); // HLSL Change - unwind if necessary, but don't terminate the process
  198. throw std::exception();
  199. }
  200. void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
  201. diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
  202. }
  203. //===----------------------------------------------------------------------===//
  204. // Metadata Kind Uniquing
  205. //===----------------------------------------------------------------------===//
  206. /// Return a unique non-zero ID for the specified metadata kind.
  207. unsigned LLVMContext::getMDKindID(StringRef Name) const {
  208. // If this is new, assign it its ID.
  209. return pImpl->CustomMDKindNames.insert(
  210. std::make_pair(
  211. Name, pImpl->CustomMDKindNames.size()))
  212. .first->second;
  213. }
  214. /// getHandlerNames - Populate client supplied smallvector using custome
  215. /// metadata name and ID.
  216. void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  217. Names.resize(pImpl->CustomMDKindNames.size());
  218. for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
  219. E = pImpl->CustomMDKindNames.end(); I != E; ++I)
  220. Names[I->second] = I->first();
  221. }