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 *DiagnosticInfoOptimizationRemarkAnalysis::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 DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
    116   DP << getResourceName() << " limit";
    117 
    118   if (getResourceLimit() != 0)
    119     DP << " of " << getResourceLimit();
    120 
    121   DP << " exceeded (" <<  getResourceSize() << ") in " << getFunction();
    122 }
    123 
    124 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
    125   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
    126      << ") in " << getModule();
    127 }
    128 
    129 void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
    130     DiagnosticPrinter &DP) const {
    131   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
    132 }
    133 
    134 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
    135   if (!FileName.empty()) {
    136     DP << getFileName();
    137     if (LineNum > 0)
    138       DP << ":" << getLineNum();
    139     DP << ": ";
    140   }
    141   DP << getMsg();
    142 }
    143 
    144 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
    145   if (getFileName())
    146     DP << getFileName() << ": ";
    147   DP << getMsg();
    148 }
    149 
    150 bool DiagnosticInfoWithDebugLocBase::isLocationAvailable() const {
    151   return getDebugLoc();
    152 }
    153 
    154 void DiagnosticInfoWithDebugLocBase::getLocation(StringRef *Filename,
    155                                                  unsigned *Line,
    156                                                  unsigned *Column) const {
    157   DILocation *L = getDebugLoc();
    158   assert(L != nullptr && "debug location is invalid");
    159   *Filename = L->getFilename();
    160   *Line = L->getLine();
    161   *Column = L->getColumn();
    162 }
    163 
    164 const std::string DiagnosticInfoWithDebugLocBase::getLocationStr() const {
    165   StringRef Filename("<unknown>");
    166   unsigned Line = 0;
    167   unsigned Column = 0;
    168   if (isLocationAvailable())
    169     getLocation(&Filename, &Line, &Column);
    170   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
    171 }
    172 
    173 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
    174   DP << getLocationStr() << ": " << getMsg();
    175 }
    176 
    177 bool DiagnosticInfoOptimizationRemark::isEnabled() const {
    178   return PassRemarksOptLoc.Pattern &&
    179          PassRemarksOptLoc.Pattern->match(getPassName());
    180 }
    181 
    182 bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
    183   return PassRemarksMissedOptLoc.Pattern &&
    184          PassRemarksMissedOptLoc.Pattern->match(getPassName());
    185 }
    186 
    187 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
    188   return shouldAlwaysPrint() ||
    189          (PassRemarksAnalysisOptLoc.Pattern &&
    190           PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
    191 }
    192 
    193 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
    194   DP << Diagnostic;
    195 }
    196 
    197 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    198                                   const Function &Fn, const DebugLoc &DLoc,
    199                                   const Twine &Msg) {
    200   Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
    201 }
    202 
    203 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
    204                                         const Function &Fn,
    205                                         const DebugLoc &DLoc,
    206                                         const Twine &Msg) {
    207   Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
    208 }
    209 
    210 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
    211                                           const char *PassName,
    212                                           const Function &Fn,
    213                                           const DebugLoc &DLoc,
    214                                           const Twine &Msg) {
    215   Ctx.diagnose(
    216       DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
    217 }
    218 
    219 void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
    220                                                    const char *PassName,
    221                                                    const Function &Fn,
    222                                                    const DebugLoc &DLoc,
    223                                                    const Twine &Msg) {
    224   Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisFPCommute(PassName, Fn,
    225                                                                  DLoc, Msg));
    226 }
    227 
    228 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
    229                                                   const char *PassName,
    230                                                   const Function &Fn,
    231                                                   const DebugLoc &DLoc,
    232                                                   const Twine &Msg) {
    233   Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisAliasing(PassName, Fn,
    234                                                                 DLoc, Msg));
    235 }
    236 
    237 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
    238   // Only print warnings.
    239   return getSeverity() == DS_Warning;
    240 }
    241 
    242 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
    243   std::string Str;
    244   raw_string_ostream OS(Str);
    245 
    246   OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
    247      << *getFunction().getFunctionType() << ": " << Msg << '\n';
    248   OS.flush();
    249   DP << Str;
    250 }
    251 
    252 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
    253                                     const DebugLoc &DLoc, const Twine &Msg) {
    254   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
    255       Fn, DLoc, Twine("loop not vectorized: " + Msg)));
    256 }
    257 
    258 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
    259                                      const DebugLoc &DLoc, const Twine &Msg) {
    260   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
    261       Fn, DLoc, Twine("loop not interleaved: " + Msg)));
    262 }
    263