DiagnosticInfo.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
  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 defines the different classes involved in low level diagnostics.
  11. //
  12. // Diagnostics reporting is still done as part of the LLVMContext.
  13. //===----------------------------------------------------------------------===//
  14. #include "LLVMContextImpl.h"
  15. #include "llvm/ADT/Twine.h"
  16. #include "llvm/IR/Constants.h"
  17. #include "llvm/IR/DebugInfo.h"
  18. #include "llvm/IR/DiagnosticInfo.h"
  19. #include "llvm/IR/DiagnosticPrinter.h"
  20. #include "llvm/IR/Function.h"
  21. #include "llvm/IR/Instruction.h"
  22. #include "llvm/IR/Metadata.h"
  23. #include "llvm/IR/Module.h"
  24. #include "llvm/Support/CommandLine.h"
  25. #include "llvm/Support/Regex.h"
  26. #include <atomic>
  27. #include <string>
  28. using namespace llvm;
  29. namespace {
  30. /// \brief Regular expression corresponding to the value given in one of the
  31. /// -pass-remarks* command line flags. Passes whose name matches this regexp
  32. /// will emit a diagnostic when calling the associated diagnostic function
  33. /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
  34. /// emitOptimizationRemarkAnalysis).
  35. struct PassRemarksOpt {
  36. std::shared_ptr<Regex> Pattern;
  37. void operator=(const std::string &Val) {
  38. // Create a regexp object to match pass names for emitOptimizationRemark.
  39. if (!Val.empty()) {
  40. Pattern = std::make_shared<Regex>(Val);
  41. std::string RegexError;
  42. if (!Pattern->isValid(RegexError))
  43. report_fatal_error("Invalid regular expression '" + Val +
  44. "' in -pass-remarks: " + RegexError,
  45. false);
  46. }
  47. };
  48. };
  49. #if 0
  50. // These should all be specific to a pipline, not global to the process.
  51. static PassRemarksOpt PassRemarksOptLoc;
  52. static PassRemarksOpt PassRemarksMissedOptLoc;
  53. static PassRemarksOpt PassRemarksAnalysisOptLoc;
  54. // -pass-remarks
  55. // Command line flag to enable emitOptimizationRemark()
  56. static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
  57. PassRemarks("pass-remarks", cl::value_desc("pattern"),
  58. cl::desc("Enable optimization remarks from passes whose name match "
  59. "the given regular expression"),
  60. cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
  61. cl::ZeroOrMore);
  62. // -pass-remarks-missed
  63. // Command line flag to enable emitOptimizationRemarkMissed()
  64. static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
  65. "pass-remarks-missed", cl::value_desc("pattern"),
  66. cl::desc("Enable missed optimization remarks from passes whose name match "
  67. "the given regular expression"),
  68. cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
  69. cl::ZeroOrMore);
  70. // -pass-remarks-analysis
  71. // Command line flag to enable emitOptimizationRemarkAnalysis()
  72. static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
  73. PassRemarksAnalysis(
  74. "pass-remarks-analysis", cl::value_desc("pattern"),
  75. cl::desc(
  76. "Enable optimization analysis remarks from passes whose name match "
  77. "the given regular expression"),
  78. cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
  79. cl::ZeroOrMore);
  80. }
  81. #else
  82. struct PassRemarksOptNull {
  83. Regex *Pattern = nullptr;
  84. void operator=(const std::string &Val) {
  85. }
  86. };
  87. static PassRemarksOptNull PassRemarksOptLoc;
  88. static PassRemarksOptNull PassRemarksMissedOptLoc;
  89. static PassRemarksOptNull PassRemarksAnalysisOptLoc;
  90. static PassRemarksOptNull PassRemarks;
  91. static PassRemarksOptNull PassRemarksMissed;
  92. static PassRemarksOptNull PassRemarksAnalysis;
  93. }
  94. #endif
  95. int llvm::getNextAvailablePluginDiagnosticKind() {
  96. static std::atomic<int> PluginKindID(DK_FirstPluginKind);
  97. return ++PluginKindID;
  98. }
  99. DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
  100. const Twine &MsgStr,
  101. DiagnosticSeverity Severity)
  102. : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
  103. Instr(&I) {
  104. if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
  105. if (SrcLoc->getNumOperands() != 0)
  106. if (const auto *CI =
  107. mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
  108. LocCookie = CI->getZExtValue();
  109. }
  110. }
  111. void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
  112. DP << getMsgStr();
  113. if (getLocCookie())
  114. DP << " at line " << getLocCookie();
  115. }
  116. void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {
  117. DP << "stack size limit exceeded (" << getStackSize() << ") in "
  118. << getFunction();
  119. }
  120. void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
  121. DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
  122. << ") in " << getModule();
  123. }
  124. void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
  125. if (getFileName() && getLineNum() > 0)
  126. DP << getFileName() << ":" << getLineNum() << ": ";
  127. else if (getFileName())
  128. DP << getFileName() << ": ";
  129. DP << getMsg();
  130. }
  131. bool DiagnosticInfoOptimizationBase::isLocationAvailable() const {
  132. return getDebugLoc();
  133. }
  134. void DiagnosticInfoOptimizationBase::getLocation(StringRef *Filename,
  135. unsigned *Line,
  136. unsigned *Column) const {
  137. DILocation *L = getDebugLoc();
  138. assert(L != nullptr && "debug location is invalid");
  139. *Filename = L->getFilename();
  140. *Line = L->getLine();
  141. *Column = L->getColumn();
  142. }
  143. const std::string DiagnosticInfoOptimizationBase::getLocationStr() const {
  144. StringRef Filename("<unknown>");
  145. unsigned Line = 0;
  146. unsigned Column = 0;
  147. if (isLocationAvailable())
  148. getLocation(&Filename, &Line, &Column);
  149. return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
  150. }
  151. void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
  152. DP << getLocationStr() << ": " << getMsg();
  153. }
  154. bool DiagnosticInfoOptimizationRemark::isEnabled() const {
  155. return PassRemarksOptLoc.Pattern &&
  156. PassRemarksOptLoc.Pattern->match(getPassName());
  157. }
  158. bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
  159. return PassRemarksMissedOptLoc.Pattern &&
  160. PassRemarksMissedOptLoc.Pattern->match(getPassName());
  161. }
  162. bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
  163. return PassRemarksAnalysisOptLoc.Pattern &&
  164. PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
  165. }
  166. void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
  167. DP << Diagnostic;
  168. }
  169. void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
  170. const Function &Fn, const DebugLoc &DLoc,
  171. const Twine &Msg) {
  172. Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
  173. }
  174. void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
  175. const Function &Fn,
  176. const DebugLoc &DLoc,
  177. const Twine &Msg) {
  178. Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
  179. }
  180. void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
  181. const char *PassName,
  182. const Function &Fn,
  183. const DebugLoc &DLoc,
  184. const Twine &Msg) {
  185. Ctx.diagnose(
  186. DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
  187. }
  188. bool DiagnosticInfoOptimizationFailure::isEnabled() const {
  189. // Only print warnings.
  190. return getSeverity() == DS_Warning;
  191. }
  192. void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
  193. const DebugLoc &DLoc, const Twine &Msg) {
  194. Ctx.diagnose(DiagnosticInfoOptimizationFailure(
  195. Fn, DLoc, Twine("loop not vectorized: " + Msg)));
  196. }
  197. void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
  198. const DebugLoc &DLoc, const Twine &Msg) {
  199. Ctx.diagnose(DiagnosticInfoOptimizationFailure(
  200. Fn, DLoc, Twine("loop not interleaved: " + Msg)));
  201. }