LLVMContext.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. #include "llvm/IR/LLVMContext.h"
  14. #include "LLVMContextImpl.h"
  15. #include "llvm/ADT/SmallVector.h"
  16. #include "llvm/ADT/StringMap.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/ADT/Twine.h"
  19. #include "llvm/IR/DiagnosticInfo.h"
  20. #include "llvm/IR/DiagnosticPrinter.h"
  21. #include "llvm/IR/Metadata.h"
  22. #include "llvm/IR/Module.h"
  23. #include "llvm/IR/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. using namespace llvm;
  32. LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
  33. // Create the fixed metadata kinds. This is done in the same order as the
  34. // MD_* enum values so that they correspond.
  35. std::pair<unsigned, StringRef> MDKinds[] = {
  36. #define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
  37. #include "llvm/IR/FixedMetadataKinds.def"
  38. #undef LLVM_FIXED_MD_KIND
  39. };
  40. for (auto &MDKind : MDKinds) {
  41. unsigned ID = getMDKindID(MDKind.second);
  42. assert(ID == MDKind.first && "metadata kind id drifted");
  43. (void)ID;
  44. }
  45. auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
  46. assert(DeoptEntry->second == LLVMContext::OB_deopt &&
  47. "deopt operand bundle id drifted!");
  48. (void)DeoptEntry;
  49. auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
  50. assert(FuncletEntry->second == LLVMContext::OB_funclet &&
  51. "funclet operand bundle id drifted!");
  52. (void)FuncletEntry;
  53. auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
  54. assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
  55. "gc-transition operand bundle id drifted!");
  56. (void)GCTransitionEntry;
  57. SyncScope::ID SingleThreadSSID =
  58. pImpl->getOrInsertSyncScopeID("singlethread");
  59. assert(SingleThreadSSID == SyncScope::SingleThread &&
  60. "singlethread synchronization scope ID drifted!");
  61. (void)SingleThreadSSID;
  62. SyncScope::ID SystemSSID =
  63. pImpl->getOrInsertSyncScopeID("");
  64. assert(SystemSSID == SyncScope::System &&
  65. "system synchronization scope ID drifted!");
  66. (void)SystemSSID;
  67. }
  68. LLVMContext::~LLVMContext() { delete pImpl; }
  69. void LLVMContext::addModule(Module *M) {
  70. pImpl->OwnedModules.insert(M);
  71. }
  72. void LLVMContext::removeModule(Module *M) {
  73. pImpl->OwnedModules.erase(M);
  74. }
  75. //===----------------------------------------------------------------------===//
  76. // Recoverable Backend Errors
  77. //===----------------------------------------------------------------------===//
  78. void LLVMContext::
  79. setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
  80. void *DiagContext) {
  81. pImpl->InlineAsmDiagHandler = DiagHandler;
  82. pImpl->InlineAsmDiagContext = DiagContext;
  83. }
  84. /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
  85. /// setInlineAsmDiagnosticHandler.
  86. LLVMContext::InlineAsmDiagHandlerTy
  87. LLVMContext::getInlineAsmDiagnosticHandler() const {
  88. return pImpl->InlineAsmDiagHandler;
  89. }
  90. /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
  91. /// setInlineAsmDiagnosticHandler.
  92. void *LLVMContext::getInlineAsmDiagnosticContext() const {
  93. return pImpl->InlineAsmDiagContext;
  94. }
  95. void LLVMContext::setDiagnosticHandlerCallBack(
  96. DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
  97. void *DiagnosticContext, bool RespectFilters) {
  98. pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
  99. pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
  100. pImpl->RespectDiagnosticFilters = RespectFilters;
  101. }
  102. void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
  103. bool RespectFilters) {
  104. pImpl->DiagHandler = std::move(DH);
  105. pImpl->RespectDiagnosticFilters = RespectFilters;
  106. }
  107. void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
  108. pImpl->DiagnosticsHotnessRequested = Requested;
  109. }
  110. bool LLVMContext::getDiagnosticsHotnessRequested() const {
  111. return pImpl->DiagnosticsHotnessRequested;
  112. }
  113. void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
  114. pImpl->DiagnosticsHotnessThreshold = Threshold;
  115. }
  116. uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
  117. return pImpl->DiagnosticsHotnessThreshold;
  118. }
  119. RemarkStreamer *LLVMContext::getRemarkStreamer() {
  120. return pImpl->RemarkDiagStreamer.get();
  121. }
  122. const RemarkStreamer *LLVMContext::getRemarkStreamer() const {
  123. return const_cast<LLVMContext *>(this)->getRemarkStreamer();
  124. }
  125. void LLVMContext::setRemarkStreamer(
  126. std::unique_ptr<RemarkStreamer> RemarkStreamer) {
  127. pImpl->RemarkDiagStreamer = std::move(RemarkStreamer);
  128. }
  129. DiagnosticHandler::DiagnosticHandlerTy
  130. LLVMContext::getDiagnosticHandlerCallBack() const {
  131. return pImpl->DiagHandler->DiagHandlerCallback;
  132. }
  133. void *LLVMContext::getDiagnosticContext() const {
  134. return pImpl->DiagHandler->DiagnosticContext;
  135. }
  136. void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
  137. {
  138. pImpl->YieldCallback = Callback;
  139. pImpl->YieldOpaqueHandle = OpaqueHandle;
  140. }
  141. void LLVMContext::yield() {
  142. if (pImpl->YieldCallback)
  143. pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
  144. }
  145. void LLVMContext::emitError(const Twine &ErrorStr) {
  146. diagnose(DiagnosticInfoInlineAsm(ErrorStr));
  147. }
  148. void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  149. assert (I && "Invalid instruction");
  150. diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
  151. }
  152. static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
  153. // Optimization remarks are selective. They need to check whether the regexp
  154. // pattern, passed via one of the -pass-remarks* flags, matches the name of
  155. // the pass that is emitting the diagnostic. If there is no match, ignore the
  156. // diagnostic and return.
  157. //
  158. // Also noisy remarks are only enabled if we have hotness information to sort
  159. // them.
  160. if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
  161. return Remark->isEnabled() &&
  162. (!Remark->isVerbose() || Remark->getHotness());
  163. return true;
  164. }
  165. const char *
  166. LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
  167. switch (Severity) {
  168. case DS_Error:
  169. return "error";
  170. case DS_Warning:
  171. return "warning";
  172. case DS_Remark:
  173. return "remark";
  174. case DS_Note:
  175. return "note";
  176. }
  177. llvm_unreachable("Unknown DiagnosticSeverity");
  178. }
  179. void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  180. if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
  181. if (RemarkStreamer *RS = getRemarkStreamer())
  182. RS->emit(*OptDiagBase);
  183. // If there is a report handler, use it.
  184. if (pImpl->DiagHandler &&
  185. (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
  186. pImpl->DiagHandler->handleDiagnostics(DI))
  187. return;
  188. if (!isDiagnosticEnabled(DI))
  189. return;
  190. // Otherwise, print the message with a prefix based on the severity.
  191. DiagnosticPrinterRawOStream DP(errs());
  192. errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
  193. DI.print(DP);
  194. errs() << "\n";
  195. if (DI.getSeverity() == DS_Error)
  196. exit(1);
  197. }
  198. void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
  199. diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
  200. }
  201. //===----------------------------------------------------------------------===//
  202. // Metadata Kind Uniquing
  203. //===----------------------------------------------------------------------===//
  204. /// Return a unique non-zero ID for the specified metadata kind.
  205. unsigned LLVMContext::getMDKindID(StringRef Name) const {
  206. // If this is new, assign it its ID.
  207. return pImpl->CustomMDKindNames.insert(
  208. std::make_pair(
  209. Name, pImpl->CustomMDKindNames.size()))
  210. .first->second;
  211. }
  212. /// getHandlerNames - Populate client-supplied smallvector using custom
  213. /// metadata name and ID.
  214. void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  215. Names.resize(pImpl->CustomMDKindNames.size());
  216. for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
  217. E = pImpl->CustomMDKindNames.end(); I != E; ++I)
  218. Names[I->second] = I->first();
  219. }
  220. void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
  221. pImpl->getOperandBundleTags(Tags);
  222. }
  223. uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
  224. return pImpl->getOperandBundleTagID(Tag);
  225. }
  226. SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
  227. return pImpl->getOrInsertSyncScopeID(SSN);
  228. }
  229. void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
  230. pImpl->getSyncScopeNames(SSNs);
  231. }
  232. void LLVMContext::setGC(const Function &Fn, std::string GCName) {
  233. auto It = pImpl->GCNames.find(&Fn);
  234. if (It == pImpl->GCNames.end()) {
  235. pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
  236. return;
  237. }
  238. It->second = std::move(GCName);
  239. }
  240. const std::string &LLVMContext::getGC(const Function &Fn) {
  241. return pImpl->GCNames[&Fn];
  242. }
  243. void LLVMContext::deleteGC(const Function &Fn) {
  244. pImpl->GCNames.erase(&Fn);
  245. }
  246. bool LLVMContext::shouldDiscardValueNames() const {
  247. return pImpl->DiscardValueNames;
  248. }
  249. bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
  250. void LLVMContext::enableDebugTypeODRUniquing() {
  251. if (pImpl->DITypeMap)
  252. return;
  253. pImpl->DITypeMap.emplace();
  254. }
  255. void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
  256. void LLVMContext::setDiscardValueNames(bool Discard) {
  257. pImpl->DiscardValueNames = Discard;
  258. }
  259. OptPassGate &LLVMContext::getOptPassGate() const {
  260. return pImpl->getOptPassGate();
  261. }
  262. void LLVMContext::setOptPassGate(OptPassGate& OPG) {
  263. pImpl->setOptPassGate(OPG);
  264. }
  265. const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
  266. return pImpl->DiagHandler.get();
  267. }
  268. std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
  269. return std::move(pImpl->DiagHandler);
  270. }