LLVMContext.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. auto *PtrauthEntry = pImpl->getOrInsertBundleTag("ptrauth");
  74. assert(PtrauthEntry->second == LLVMContext::OB_ptrauth &&
  75. "ptrauth operand bundle id drifted!");
  76. (void)PtrauthEntry;
  77. auto *KCFIEntry = pImpl->getOrInsertBundleTag("kcfi");
  78. assert(KCFIEntry->second == LLVMContext::OB_kcfi &&
  79. "kcfi operand bundle id drifted!");
  80. (void)KCFIEntry;
  81. SyncScope::ID SingleThreadSSID =
  82. pImpl->getOrInsertSyncScopeID("singlethread");
  83. assert(SingleThreadSSID == SyncScope::SingleThread &&
  84. "singlethread synchronization scope ID drifted!");
  85. (void)SingleThreadSSID;
  86. SyncScope::ID SystemSSID =
  87. pImpl->getOrInsertSyncScopeID("");
  88. assert(SystemSSID == SyncScope::System &&
  89. "system synchronization scope ID drifted!");
  90. (void)SystemSSID;
  91. }
  92. LLVMContext::~LLVMContext() { delete pImpl; }
  93. void LLVMContext::addModule(Module *M) {
  94. pImpl->OwnedModules.insert(M);
  95. }
  96. void LLVMContext::removeModule(Module *M) {
  97. pImpl->OwnedModules.erase(M);
  98. }
  99. //===----------------------------------------------------------------------===//
  100. // Recoverable Backend Errors
  101. //===----------------------------------------------------------------------===//
  102. void LLVMContext::setDiagnosticHandlerCallBack(
  103. DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
  104. void *DiagnosticContext, bool RespectFilters) {
  105. pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
  106. pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
  107. pImpl->RespectDiagnosticFilters = RespectFilters;
  108. }
  109. void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
  110. bool RespectFilters) {
  111. pImpl->DiagHandler = std::move(DH);
  112. pImpl->RespectDiagnosticFilters = RespectFilters;
  113. }
  114. void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
  115. pImpl->DiagnosticsHotnessRequested = Requested;
  116. }
  117. bool LLVMContext::getDiagnosticsHotnessRequested() const {
  118. return pImpl->DiagnosticsHotnessRequested;
  119. }
  120. void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) {
  121. pImpl->DiagnosticsHotnessThreshold = Threshold;
  122. }
  123. void LLVMContext::setMisExpectWarningRequested(bool Requested) {
  124. pImpl->MisExpectWarningRequested = Requested;
  125. }
  126. bool LLVMContext::getMisExpectWarningRequested() const {
  127. return pImpl->MisExpectWarningRequested;
  128. }
  129. uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
  130. return pImpl->DiagnosticsHotnessThreshold.value_or(UINT64_MAX);
  131. }
  132. void LLVMContext::setDiagnosticsMisExpectTolerance(
  133. std::optional<uint32_t> Tolerance) {
  134. pImpl->DiagnosticsMisExpectTolerance = Tolerance;
  135. }
  136. uint32_t LLVMContext::getDiagnosticsMisExpectTolerance() const {
  137. return pImpl->DiagnosticsMisExpectTolerance.value_or(0);
  138. }
  139. bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
  140. return !pImpl->DiagnosticsHotnessThreshold.has_value();
  141. }
  142. remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
  143. return pImpl->MainRemarkStreamer.get();
  144. }
  145. const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {
  146. return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
  147. }
  148. void LLVMContext::setMainRemarkStreamer(
  149. std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
  150. pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
  151. }
  152. LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {
  153. return pImpl->LLVMRS.get();
  154. }
  155. const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {
  156. return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
  157. }
  158. void LLVMContext::setLLVMRemarkStreamer(
  159. std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
  160. pImpl->LLVMRS = std::move(RemarkStreamer);
  161. }
  162. DiagnosticHandler::DiagnosticHandlerTy
  163. LLVMContext::getDiagnosticHandlerCallBack() const {
  164. return pImpl->DiagHandler->DiagHandlerCallback;
  165. }
  166. void *LLVMContext::getDiagnosticContext() const {
  167. return pImpl->DiagHandler->DiagnosticContext;
  168. }
  169. void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
  170. {
  171. pImpl->YieldCallback = Callback;
  172. pImpl->YieldOpaqueHandle = OpaqueHandle;
  173. }
  174. void LLVMContext::yield() {
  175. if (pImpl->YieldCallback)
  176. pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
  177. }
  178. void LLVMContext::emitError(const Twine &ErrorStr) {
  179. diagnose(DiagnosticInfoInlineAsm(ErrorStr));
  180. }
  181. void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  182. assert (I && "Invalid instruction");
  183. diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
  184. }
  185. static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
  186. // Optimization remarks are selective. They need to check whether the regexp
  187. // pattern, passed via one of the -pass-remarks* flags, matches the name of
  188. // the pass that is emitting the diagnostic. If there is no match, ignore the
  189. // diagnostic and return.
  190. //
  191. // Also noisy remarks are only enabled if we have hotness information to sort
  192. // them.
  193. if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
  194. return Remark->isEnabled() &&
  195. (!Remark->isVerbose() || Remark->getHotness());
  196. return true;
  197. }
  198. const char *
  199. LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
  200. switch (Severity) {
  201. case DS_Error:
  202. return "error";
  203. case DS_Warning:
  204. return "warning";
  205. case DS_Remark:
  206. return "remark";
  207. case DS_Note:
  208. return "note";
  209. }
  210. llvm_unreachable("Unknown DiagnosticSeverity");
  211. }
  212. void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  213. if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
  214. if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())
  215. RS->emit(*OptDiagBase);
  216. // If there is a report handler, use it.
  217. if (pImpl->DiagHandler &&
  218. (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
  219. pImpl->DiagHandler->handleDiagnostics(DI))
  220. return;
  221. if (!isDiagnosticEnabled(DI))
  222. return;
  223. // Otherwise, print the message with a prefix based on the severity.
  224. DiagnosticPrinterRawOStream DP(errs());
  225. errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
  226. DI.print(DP);
  227. errs() << "\n";
  228. if (DI.getSeverity() == DS_Error)
  229. exit(1);
  230. }
  231. void LLVMContext::emitError(uint64_t LocCookie, const Twine &ErrorStr) {
  232. diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
  233. }
  234. //===----------------------------------------------------------------------===//
  235. // Metadata Kind Uniquing
  236. //===----------------------------------------------------------------------===//
  237. /// Return a unique non-zero ID for the specified metadata kind.
  238. unsigned LLVMContext::getMDKindID(StringRef Name) const {
  239. // If this is new, assign it its ID.
  240. return pImpl->CustomMDKindNames.insert(
  241. std::make_pair(
  242. Name, pImpl->CustomMDKindNames.size()))
  243. .first->second;
  244. }
  245. /// getHandlerNames - Populate client-supplied smallvector using custom
  246. /// metadata name and ID.
  247. void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  248. Names.resize(pImpl->CustomMDKindNames.size());
  249. for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
  250. E = pImpl->CustomMDKindNames.end(); I != E; ++I)
  251. Names[I->second] = I->first();
  252. }
  253. void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
  254. pImpl->getOperandBundleTags(Tags);
  255. }
  256. StringMapEntry<uint32_t> *
  257. LLVMContext::getOrInsertBundleTag(StringRef TagName) const {
  258. return pImpl->getOrInsertBundleTag(TagName);
  259. }
  260. uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
  261. return pImpl->getOperandBundleTagID(Tag);
  262. }
  263. SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
  264. return pImpl->getOrInsertSyncScopeID(SSN);
  265. }
  266. void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
  267. pImpl->getSyncScopeNames(SSNs);
  268. }
  269. void LLVMContext::setGC(const Function &Fn, std::string GCName) {
  270. auto It = pImpl->GCNames.find(&Fn);
  271. if (It == pImpl->GCNames.end()) {
  272. pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
  273. return;
  274. }
  275. It->second = std::move(GCName);
  276. }
  277. const std::string &LLVMContext::getGC(const Function &Fn) {
  278. return pImpl->GCNames[&Fn];
  279. }
  280. void LLVMContext::deleteGC(const Function &Fn) {
  281. pImpl->GCNames.erase(&Fn);
  282. }
  283. bool LLVMContext::shouldDiscardValueNames() const {
  284. return pImpl->DiscardValueNames;
  285. }
  286. bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
  287. void LLVMContext::enableDebugTypeODRUniquing() {
  288. if (pImpl->DITypeMap)
  289. return;
  290. pImpl->DITypeMap.emplace();
  291. }
  292. void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
  293. void LLVMContext::setDiscardValueNames(bool Discard) {
  294. pImpl->DiscardValueNames = Discard;
  295. }
  296. OptPassGate &LLVMContext::getOptPassGate() const {
  297. return pImpl->getOptPassGate();
  298. }
  299. void LLVMContext::setOptPassGate(OptPassGate& OPG) {
  300. pImpl->setOptPassGate(OPG);
  301. }
  302. const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
  303. return pImpl->DiagHandler.get();
  304. }
  305. std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
  306. return std::move(pImpl->DiagHandler);
  307. }
  308. void LLVMContext::setOpaquePointers(bool Enable) const {
  309. pImpl->setOpaquePointers(Enable);
  310. }
  311. bool LLVMContext::supportsTypedPointers() const {
  312. return !pImpl->getOpaquePointers();
  313. }