DiagnosticInfo.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
  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 defines the different classes involved in low level diagnostics.
  10. //
  11. // Diagnostics reporting is still done as part of the LLVMContext.
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/IR/DiagnosticInfo.h"
  14. #include "LLVMContextImpl.h"
  15. #include "llvm/ADT/StringExtras.h"
  16. #include "llvm/ADT/Twine.h"
  17. #include "llvm/ADT/iterator_range.h"
  18. #include "llvm/IR/BasicBlock.h"
  19. #include "llvm/IR/Constants.h"
  20. #include "llvm/IR/DebugInfoMetadata.h"
  21. #include "llvm/IR/DerivedTypes.h"
  22. #include "llvm/IR/DiagnosticPrinter.h"
  23. #include "llvm/IR/Function.h"
  24. #include "llvm/IR/GlobalValue.h"
  25. #include "llvm/IR/Instruction.h"
  26. #include "llvm/IR/LLVMContext.h"
  27. #include "llvm/IR/Metadata.h"
  28. #include "llvm/IR/Module.h"
  29. #include "llvm/IR/Type.h"
  30. #include "llvm/IR/Value.h"
  31. #include "llvm/Support/Casting.h"
  32. #include "llvm/Support/CommandLine.h"
  33. #include "llvm/Support/ErrorHandling.h"
  34. #include "llvm/Support/Path.h"
  35. #include "llvm/Support/Regex.h"
  36. #include "llvm/Support/ScopedPrinter.h"
  37. #include "llvm/Support/raw_ostream.h"
  38. #include <atomic>
  39. #include <cassert>
  40. #include <memory>
  41. #include <string>
  42. using namespace llvm;
  43. int llvm::getNextAvailablePluginDiagnosticKind() {
  44. static std::atomic<int> PluginKindID(DK_FirstPluginKind);
  45. return ++PluginKindID;
  46. }
  47. const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
  48. DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
  49. const Twine &MsgStr,
  50. DiagnosticSeverity Severity)
  51. : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
  52. if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
  53. if (SrcLoc->getNumOperands() != 0)
  54. if (const auto *CI =
  55. mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
  56. LocCookie = CI->getZExtValue();
  57. }
  58. }
  59. void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
  60. DP << getMsgStr();
  61. if (getLocCookie())
  62. DP << " at line " << getLocCookie();
  63. }
  64. void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
  65. DP << getResourceName() << " limit";
  66. if (getResourceLimit() != 0)
  67. DP << " of " << getResourceLimit();
  68. DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
  69. }
  70. void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
  71. DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
  72. << ") in " << getModule();
  73. }
  74. void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
  75. DiagnosticPrinter &DP) const {
  76. DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
  77. }
  78. void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
  79. if (!FileName.empty()) {
  80. DP << getFileName();
  81. if (LineNum > 0)
  82. DP << ":" << getLineNum();
  83. DP << ": ";
  84. }
  85. DP << getMsg();
  86. }
  87. void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
  88. if (getFileName())
  89. DP << getFileName() << ": ";
  90. DP << getMsg();
  91. }
  92. void DiagnosticInfo::anchor() {}
  93. void DiagnosticInfoStackSize::anchor() {}
  94. void DiagnosticInfoWithLocationBase::anchor() {}
  95. void DiagnosticInfoIROptimization::anchor() {}
  96. DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
  97. if (!DL)
  98. return;
  99. File = DL->getFile();
  100. Line = DL->getLine();
  101. Column = DL->getColumn();
  102. }
  103. DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
  104. if (!SP)
  105. return;
  106. File = SP->getFile();
  107. Line = SP->getScopeLine();
  108. Column = 0;
  109. }
  110. StringRef DiagnosticLocation::getRelativePath() const {
  111. return File->getFilename();
  112. }
  113. std::string DiagnosticLocation::getAbsolutePath() const {
  114. StringRef Name = File->getFilename();
  115. if (sys::path::is_absolute(Name))
  116. return Name;
  117. SmallString<128> Path;
  118. sys::path::append(Path, File->getDirectory(), Name);
  119. return sys::path::remove_leading_dotslash(Path).str();
  120. }
  121. std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {
  122. return Loc.getAbsolutePath();
  123. }
  124. void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,
  125. unsigned &Line,
  126. unsigned &Column) const {
  127. RelativePath = Loc.getRelativePath();
  128. Line = Loc.getLine();
  129. Column = Loc.getColumn();
  130. }
  131. const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
  132. StringRef Filename("<unknown>");
  133. unsigned Line = 0;
  134. unsigned Column = 0;
  135. if (isLocationAvailable())
  136. getLocation(Filename, Line, Column);
  137. return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
  138. }
  139. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V)
  140. : Key(Key) {
  141. if (auto *F = dyn_cast<Function>(V)) {
  142. if (DISubprogram *SP = F->getSubprogram())
  143. Loc = SP;
  144. }
  145. else if (auto *I = dyn_cast<Instruction>(V))
  146. Loc = I->getDebugLoc();
  147. // Only include names that correspond to user variables. FIXME: We should use
  148. // debug info if available to get the name of the user variable.
  149. if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
  150. Val = GlobalValue::dropLLVMManglingEscape(V->getName());
  151. else if (isa<Constant>(V)) {
  152. raw_string_ostream OS(Val);
  153. V->printAsOperand(OS, /*PrintType=*/false);
  154. } else if (auto *I = dyn_cast<Instruction>(V))
  155. Val = I->getOpcodeName();
  156. }
  157. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
  158. : Key(Key) {
  159. raw_string_ostream OS(Val);
  160. OS << *T;
  161. }
  162. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
  163. : Key(Key), Val(S.str()) {}
  164. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
  165. : Key(Key), Val(itostr(N)) {}
  166. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
  167. : Key(Key), Val(llvm::to_string(N)) {}
  168. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
  169. : Key(Key), Val(itostr(N)) {}
  170. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
  171. : Key(Key), Val(itostr(N)) {}
  172. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
  173. : Key(Key), Val(utostr(N)) {}
  174. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
  175. unsigned long N)
  176. : Key(Key), Val(utostr(N)) {}
  177. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
  178. unsigned long long N)
  179. : Key(Key), Val(utostr(N)) {}
  180. DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
  181. : Key(Key), Loc(Loc) {
  182. if (Loc) {
  183. Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
  184. Twine(Loc.getCol())).str();
  185. } else {
  186. Val = "<UNKNOWN LOCATION>";
  187. }
  188. }
  189. void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
  190. DP << getLocationStr() << ": " << getMsg();
  191. if (Hotness)
  192. DP << " (hotness: " << *Hotness << ")";
  193. }
  194. OptimizationRemark::OptimizationRemark(const char *PassName,
  195. StringRef RemarkName,
  196. const DiagnosticLocation &Loc,
  197. const Value *CodeRegion)
  198. : DiagnosticInfoIROptimization(
  199. DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
  200. *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
  201. OptimizationRemark::OptimizationRemark(const char *PassName,
  202. StringRef RemarkName,
  203. const Instruction *Inst)
  204. : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
  205. RemarkName, *Inst->getParent()->getParent(),
  206. Inst->getDebugLoc(), Inst->getParent()) {}
  207. // Helper to allow for an assert before attempting to return an invalid
  208. // reference.
  209. static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
  210. assert(!Func->empty() && "Function does not have a body");
  211. return Func->front();
  212. }
  213. OptimizationRemark::OptimizationRemark(const char *PassName,
  214. StringRef RemarkName,
  215. const Function *Func)
  216. : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
  217. RemarkName, *Func, Func->getSubprogram(),
  218. &getFirstFunctionBlock(Func)) {}
  219. bool OptimizationRemark::isEnabled() const {
  220. const Function &Fn = getFunction();
  221. LLVMContext &Ctx = Fn.getContext();
  222. return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
  223. }
  224. OptimizationRemarkMissed::OptimizationRemarkMissed(
  225. const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
  226. const Value *CodeRegion)
  227. : DiagnosticInfoIROptimization(
  228. DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
  229. *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
  230. OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
  231. StringRef RemarkName,
  232. const Instruction *Inst)
  233. : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
  234. PassName, RemarkName,
  235. *Inst->getParent()->getParent(),
  236. Inst->getDebugLoc(), Inst->getParent()) {}
  237. bool OptimizationRemarkMissed::isEnabled() const {
  238. const Function &Fn = getFunction();
  239. LLVMContext &Ctx = Fn.getContext();
  240. return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
  241. }
  242. OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
  243. const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
  244. const Value *CodeRegion)
  245. : DiagnosticInfoIROptimization(
  246. DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
  247. *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
  248. OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
  249. StringRef RemarkName,
  250. const Instruction *Inst)
  251. : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
  252. PassName, RemarkName,
  253. *Inst->getParent()->getParent(),
  254. Inst->getDebugLoc(), Inst->getParent()) {}
  255. OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
  256. enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
  257. const DiagnosticLocation &Loc, const Value *CodeRegion)
  258. : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
  259. *cast<BasicBlock>(CodeRegion)->getParent(),
  260. Loc, CodeRegion) {}
  261. bool OptimizationRemarkAnalysis::isEnabled() const {
  262. const Function &Fn = getFunction();
  263. LLVMContext &Ctx = Fn.getContext();
  264. return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
  265. shouldAlwaysPrint();
  266. }
  267. void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
  268. DP << Diagnostic;
  269. }
  270. DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
  271. const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
  272. const Value *CodeRegion)
  273. : DiagnosticInfoIROptimization(
  274. DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
  275. *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
  276. bool DiagnosticInfoOptimizationFailure::isEnabled() const {
  277. // Only print warnings.
  278. return getSeverity() == DS_Warning;
  279. }
  280. void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
  281. std::string Str;
  282. raw_string_ostream OS(Str);
  283. OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
  284. << *getFunction().getFunctionType() << ": " << Msg << '\n';
  285. OS.flush();
  286. DP << Str;
  287. }
  288. void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
  289. DP << "Instruction selection used fallback path for " << getFunction();
  290. }
  291. void DiagnosticInfoOptimizationBase::insert(StringRef S) {
  292. Args.emplace_back(S);
  293. }
  294. void DiagnosticInfoOptimizationBase::insert(Argument A) {
  295. Args.push_back(std::move(A));
  296. }
  297. void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
  298. IsVerbose = true;
  299. }
  300. void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
  301. FirstExtraArgIndex = Args.size();
  302. }
  303. std::string DiagnosticInfoOptimizationBase::getMsg() const {
  304. std::string Str;
  305. raw_string_ostream OS(Str);
  306. for (const DiagnosticInfoOptimizationBase::Argument &Arg :
  307. make_range(Args.begin(), FirstExtraArgIndex == -1
  308. ? Args.end()
  309. : Args.begin() + FirstExtraArgIndex))
  310. OS << Arg.Val;
  311. return OS.str();
  312. }
  313. DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
  314. Twine &Msg)
  315. : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
  316. *Inst->getParent()->getParent(),
  317. Inst->getDebugLoc()),
  318. Msg(Msg) {}
  319. void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
  320. DP << getLocationStr() << ": " << getMsg();
  321. }
  322. void OptimizationRemarkAnalysisFPCommute::anchor() {}
  323. void OptimizationRemarkAnalysisAliasing::anchor() {}