LLVMContext.cpp 11 KB

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