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 ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
    102         LocCookie = CI->getZExtValue();
    103   }
    104 }
    105 
    106 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
    107   DP << getMsgStr();
    108   if (getLocCookie())
    109     DP << " at line " << getLocCookie();
    110 }
    111 
    112 void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {
    113   DP << "stack size limit exceeded (" << getStackSize() << ") in "
    114      << getFunction();
    115 }
    116 
    117 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
    118   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
    119      << ") in " << getModule();
    120 }
    121 
    122 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
    123   if (getFileName() && getLineNum() > 0)
    124     DP << getFileName() << ":" << getLineNum() << ": ";
    125   else if (getFileName())
    126     DP << getFileName() << ": ";
    127   DP << getMsg();
    128 }
    129 
    130 bool DiagnosticInfoOptimizationRemarkBase::isLocationAvailable() const {
    131   return getDebugLoc().isUnknown() == false;
    132 }
    133 
    134 void DiagnosticInfoOptimizationRemarkBase::getLocation(StringRef *Filename,
    135                                                        unsigned *Line,
    136                                                        unsigned *Column) const {
    137   DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext()));
    138   *Filename = DIL.getFilename();
    139   *Line = DIL.getLineNumber();
    140   *Column = DIL.getColumnNumber();
    141 }
    142 
    143 const std::string DiagnosticInfoOptimizationRemarkBase::getLocationStr() const {
    144   StringRef Filename("<unknown>");
    145   unsigned Line = 0;
    146   unsigned Column = 0;
    147   if (isLocationAvailable())
    148     getLocation(&Filename, &Line, &Column);
    149   return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
    150 }
    151 
    152 void DiagnosticInfoOptimizationRemarkBase::print(DiagnosticPrinter &DP) const {
    153   DP << getLocationStr() << ": " << getMsg();
    154 }
    155 
    156 bool DiagnosticInfoOptimizationRemark::isEnabled() const {
    157   return PassRemarksOptLoc.Pattern &&
    158          PassRemarksOptLoc.Pattern->match(getPassName());
    159 }
    160 
    161 bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
    162   return PassRemarksMissedOptLoc.Pattern &&
    163          PassRemarksMissedOptLoc.Pattern->match(getPassName());
    164 }
    165 
    166 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
    167   return PassRemarksAnalysisOptLoc.Pattern &&
    168          PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
    169 }
    170 
    171 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    172                                   const Function &Fn, const DebugLoc &DLoc,
    173                                   const Twine &Msg) {
    174   Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
    175 }
    176 
    177 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
    178                                         const Function &Fn,
    179                                         const DebugLoc &DLoc,
    180                                         const Twine &Msg) {
    181   Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
    182 }
    183 
    184 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
    185                                           const char *PassName,
    186                                           const Function &Fn,
    187                                           const DebugLoc &DLoc,
    188                                           const Twine &Msg) {
    189   Ctx.diagnose(
    190       DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
    191 }
    192