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