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/Atomic.h"
     26 #include "llvm/Support/CommandLine.h"
     27 #include "llvm/Support/Regex.h"
     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 sys::cas_flag PluginKindID = DK_FirstPluginKind;
     91   return (int)sys::AtomicIncrement(&PluginKindID);
     92 }
     93 
     94 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
     95                                                  const Twine &MsgStr,
     96                                                  DiagnosticSeverity Severity)
     97     : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
     98       Instr(&I) {
     99   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
    100     if (SrcLoc->getNumOperands() != 0)
    101       if (const auto *CI =
    102               mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
    103         LocCookie = CI->getZExtValue();
    104   }
    105 }
    106 
    107 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
    108   DP << getMsgStr();
    109   if (getLocCookie())
    110     DP << " at line " << getLocCookie();
    111 }
    112 
    113 void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {
    114   DP << "stack size limit exceeded (" << getStackSize() << ") in "
    115      << getFunction();
    116 }
    117 
    118 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
    119   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
    120      << ") in " << getModule();
    121 }
    122 
    123 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
    124   if (getFileName() && getLineNum() > 0)
    125     DP << getFileName() << ":" << getLineNum() << ": ";
    126   else if (getFileName())
    127     DP << getFileName() << ": ";
    128   DP << getMsg();
    129 }
    130 
    131 bool DiagnosticInfoOptimizationBase::isLocationAvailable() const {
    132   return getDebugLoc();
    133 }
    134 
    135 void DiagnosticInfoOptimizationBase::getLocation(StringRef *Filename,
    136                                                  unsigned *Line,
    137                                                  unsigned *Column) const {
    138   MDLocation *L = getDebugLoc();
    139   *Filename = L->getFilename();
    140   *Line = L->getLine();
    141   *Column = L->getColumn();
    142 }
    143 
    144 const std::string DiagnosticInfoOptimizationBase::getLocationStr() const {
    145   StringRef Filename("<unknown>");
    146   unsigned Line = 0;
    147   unsigned Column = 0;
    148   if (isLocationAvailable())
    149     getLocation(&Filename, &Line, &Column);
    150   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
    151 }
    152 
    153 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
    154   DP << getLocationStr() << ": " << getMsg();
    155 }
    156 
    157 bool DiagnosticInfoOptimizationRemark::isEnabled() const {
    158   return PassRemarksOptLoc.Pattern &&
    159          PassRemarksOptLoc.Pattern->match(getPassName());
    160 }
    161 
    162 bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
    163   return PassRemarksMissedOptLoc.Pattern &&
    164          PassRemarksMissedOptLoc.Pattern->match(getPassName());
    165 }
    166 
    167 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
    168   return PassRemarksAnalysisOptLoc.Pattern &&
    169          PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
    170 }
    171 
    172 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    173                                   const Function &Fn, const DebugLoc &DLoc,
    174                                   const Twine &Msg) {
    175   Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
    176 }
    177 
    178 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
    179                                         const Function &Fn,
    180                                         const DebugLoc &DLoc,
    181                                         const Twine &Msg) {
    182   Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
    183 }
    184 
    185 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
    186                                           const char *PassName,
    187                                           const Function &Fn,
    188                                           const DebugLoc &DLoc,
    189                                           const Twine &Msg) {
    190   Ctx.diagnose(
    191       DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
    192 }
    193 
    194 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
    195   // Only print warnings.
    196   return getSeverity() == DS_Warning;
    197 }
    198 
    199 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
    200                                     const DebugLoc &DLoc, const Twine &Msg) {
    201   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
    202       Fn, DLoc, Twine("loop not vectorized: " + Msg)));
    203 }
    204 
    205 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
    206                                      const DebugLoc &DLoc, const Twine &Msg) {
    207   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
    208       Fn, DLoc, Twine("loop not interleaved: " + Msg)));
    209 }
    210