LCOV - code coverage report
Current view: top level - lib/IR - DiagnosticInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 207 212 97.6 %
Date: 2017-09-14 15:23:50 Functions: 46 48 95.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "llvm/IR/DiagnosticInfo.h"
      16             : #include "llvm/ADT/StringExtras.h"
      17             : #include "llvm/ADT/Twine.h"
      18             : #include "llvm/ADT/iterator_range.h"
      19             : #include "llvm/IR/BasicBlock.h"
      20             : #include "llvm/IR/Constants.h"
      21             : #include "llvm/IR/DebugInfoMetadata.h"
      22             : #include "llvm/IR/DerivedTypes.h"
      23             : #include "llvm/IR/DiagnosticPrinter.h"
      24             : #include "llvm/IR/Function.h"
      25             : #include "llvm/IR/GlobalValue.h"
      26             : #include "llvm/IR/Instruction.h"
      27             : #include "llvm/IR/LLVMContext.h"
      28             : #include "llvm/IR/Metadata.h"
      29             : #include "llvm/IR/Module.h"
      30             : #include "llvm/IR/Type.h"
      31             : #include "llvm/IR/Value.h"
      32             : #include "llvm/Support/Casting.h"
      33             : #include "llvm/Support/CommandLine.h"
      34             : #include "llvm/Support/ErrorHandling.h"
      35             : #include "llvm/Support/Regex.h"
      36             : #include "llvm/Support/raw_ostream.h"
      37             : #include <atomic>
      38             : #include <cassert>
      39             : #include <memory>
      40             : #include <string>
      41             : 
      42             : using namespace llvm;
      43             : 
      44             : namespace {
      45             : 
      46             : /// \brief Regular expression corresponding to the value given in one of the
      47             : /// -pass-remarks* command line flags. Passes whose name matches this regexp
      48             : /// will emit a diagnostic via ORE->emit(...);
      49      433980 : struct PassRemarksOpt {
      50             :   std::shared_ptr<Regex> Pattern;
      51             : 
      52         307 :   void operator=(const std::string &Val) {
      53         307 :     if (!Val.empty()) {
      54         921 :       Pattern = std::make_shared<Regex>(Val);
      55         613 :       std::string RegexError;
      56         614 :       if (!Pattern->isValid(RegexError))
      57           2 :         report_fatal_error("Invalid regular expression '" + Val +
      58           1 :                                "' in -pass-remarks: " + RegexError,
      59             :                            false);
      60             :     }
      61         306 :   }
      62             : };
      63             : 
      64             : } // end anonymous namespace
      65             : 
      66       72330 : static PassRemarksOpt PassRemarksOptLoc;
      67       72330 : static PassRemarksOpt PassRemarksMissedOptLoc;
      68       72330 : static PassRemarksOpt PassRemarksAnalysisOptLoc;
      69             : 
      70             : // -pass-remarks
      71             : //    Command line flag to enable optimization remarks
      72             : static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
      73      289320 : PassRemarks("pass-remarks", cl::value_desc("pattern"),
      74      216990 :             cl::desc("Enable optimization remarks from passes whose name match "
      75             :                      "the given regular expression"),
      76      144660 :             cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
      77      361650 :             cl::ZeroOrMore);
      78             : 
      79             : // -pass-remarks-missed
      80             : //    Command line flag to enable missed optimization remarks
      81       72330 : static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
      82      216990 :     "pass-remarks-missed", cl::value_desc("pattern"),
      83      216990 :     cl::desc("Enable missed optimization remarks from passes whose name match "
      84             :              "the given regular expression"),
      85      144660 :     cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
      86      361650 :     cl::ZeroOrMore);
      87             : 
      88             : // -pass-remarks-analysis
      89             : //    Command line flag to enable optimization analysis remarks
      90             : static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
      91       72330 : PassRemarksAnalysis(
      92      216990 :     "pass-remarks-analysis", cl::value_desc("pattern"),
      93      216990 :     cl::desc(
      94             :         "Enable optimization analysis remarks from passes whose name match "
      95             :         "the given regular expression"),
      96      144660 :     cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
      97      361650 :     cl::ZeroOrMore);
      98             : 
      99       30981 : int llvm::getNextAvailablePluginDiagnosticKind() {
     100             :   static std::atomic<int> PluginKindID(DK_FirstPluginKind);
     101       30981 :   return ++PluginKindID;
     102             : }
     103             : 
     104             : const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
     105             : 
     106          85 : DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
     107             :                                                  const Twine &MsgStr,
     108          85 :                                                  DiagnosticSeverity Severity)
     109         170 :     : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
     110          96 :   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
     111          11 :     if (SrcLoc->getNumOperands() != 0)
     112             :       if (const auto *CI =
     113          22 :               mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
     114          11 :         LocCookie = CI->getZExtValue();
     115             :   }
     116          85 : }
     117             : 
     118         253 : void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
     119         253 :   DP << getMsgStr();
     120         253 :   if (getLocCookie())
     121           7 :     DP << " at line " << getLocCookie();
     122         253 : }
     123             : 
     124          12 : void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
     125          12 :   DP << getResourceName() << " limit";
     126             : 
     127          12 :   if (getResourceLimit() != 0)
     128           5 :     DP << " of " << getResourceLimit();
     129             : 
     130          12 :   DP << " exceeded (" <<  getResourceSize() << ") in " << getFunction();
     131          12 : }
     132             : 
     133          54 : void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
     134          54 :   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
     135          54 :      << ") in " << getModule();
     136          54 : }
     137             : 
     138          10 : void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
     139             :     DiagnosticPrinter &DP) const {
     140          20 :   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
     141          10 : }
     142             : 
     143          26 : void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
     144          52 :   if (!FileName.empty()) {
     145          20 :     DP << getFileName();
     146          20 :     if (LineNum > 0)
     147          16 :       DP << ":" << getLineNum();
     148          20 :     DP << ": ";
     149             :   }
     150          26 :   DP << getMsg();
     151          26 : }
     152             : 
     153           8 : void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
     154           8 :   if (getFileName())
     155           8 :     DP << getFileName() << ": ";
     156           8 :   DP << getMsg();
     157           8 : }
     158             : 
     159     2229914 : DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
     160     1114957 :   if (!DL)
     161             :     return;
     162     1123216 :   Filename = DL->getFilename();
     163      561608 :   Line = DL->getLine();
     164     1123216 :   Column = DL->getColumn();
     165             : }
     166             : 
     167     1420470 : DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
     168      710235 :   if (!SP)
     169             :     return;
     170      434510 :   Filename = SP->getFilename();
     171      434510 :   Line = SP->getScopeLine();
     172      434510 :   Column = 0;
     173             : }
     174             : 
     175         383 : void DiagnosticInfoWithLocationBase::getLocation(StringRef *Filename,
     176             :                                                  unsigned *Line,
     177             :                                                  unsigned *Column) const {
     178         383 :   *Filename = Loc.getFilename();
     179         383 :   *Line = Loc.getLine();
     180         383 :   *Column = Loc.getColumn();
     181         383 : }
     182             : 
     183        1161 : const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
     184        1161 :   StringRef Filename("<unknown>");
     185        1161 :   unsigned Line = 0;
     186        1161 :   unsigned Column = 0;
     187        1161 :   if (isLocationAvailable())
     188         357 :     getLocation(&Filename, &Line, &Column);
     189        9288 :   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
     190             : }
     191             : 
     192      818479 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V)
     193     2455437 :     : Key(Key) {
     194     1623858 :   if (auto *F = dyn_cast<Function>(V)) {
     195      805379 :     if (DISubprogram *SP = F->getSubprogram())
     196      421941 :       Loc = SP;
     197             :   }
     198       25864 :   else if (auto *I = dyn_cast<Instruction>(V))
     199       12764 :     Loc = I->getDebugLoc();
     200             : 
     201             :   // Only include names that correspond to user variables.  FIXME: we should use
     202             :   // debug info if available to get the name of the user variable.
     203     1636958 :   if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
     204     2416398 :     Val = GlobalValue::dropLLVMManglingEscape(V->getName());
     205       13013 :   else if (isa<Constant>(V)) {
     206         747 :     raw_string_ostream OS(Val);
     207         249 :     V->printAsOperand(OS, /*PrintType=*/false);
     208       25528 :   } else if (auto *I = dyn_cast<Instruction>(V))
     209       12764 :     Val = I->getOpcodeName();
     210      818479 : }
     211             : 
     212        6545 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
     213       19635 :     : Key(Key) {
     214       19635 :   raw_string_ostream OS(Val);
     215        6545 :   OS << *T;
     216        6545 : }
     217             : 
     218          28 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
     219          84 :     : Key(Key), Val(S.str()) {}
     220             : 
     221      480521 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
     222      961041 :     : Key(Key), Val(itostr(N)) {}
     223             : 
     224      141269 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
     225      282538 :     : Key(Key), Val(itostr(N)) {}
     226             : 
     227           0 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
     228           0 :     : Key(Key), Val(itostr(N)) {}
     229             : 
     230       73171 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
     231      146342 :     : Key(Key), Val(utostr(N)) {}
     232             : 
     233         342 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
     234         342 :                                                    unsigned long N)
     235         684 :     : Key(Key), Val(utostr(N)) {}
     236             : 
     237           0 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
     238           0 :                                                    unsigned long long N)
     239           0 :     : Key(Key), Val(utostr(N)) {}
     240             : 
     241          78 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
     242         156 :     : Key(Key), Loc(Loc) {
     243          78 :   if (Loc) {
     244         600 :     Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
     245         300 :            Twine(Loc.getCol())).str();
     246             :   } else {
     247          18 :     Val = "<UNKNOWN LOCATION>";
     248             :   }
     249          78 : }
     250             : 
     251        1039 : void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
     252        3117 :   DP << getLocationStr() << ": " << getMsg();
     253        1039 :   if (Hotness)
     254          70 :     DP << " (hotness: " << *Hotness << ")";
     255        1039 : }
     256             : 
     257      445904 : OptimizationRemark::OptimizationRemark(const char *PassName,
     258             :                                        StringRef RemarkName,
     259             :                                        const DiagnosticLocation &Loc,
     260             :                                        const Value *CodeRegion)
     261             :     : DiagnosticInfoIROptimization(
     262             :           DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
     263     1337712 :           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
     264             : 
     265      197717 : OptimizationRemark::OptimizationRemark(const char *PassName,
     266             :                                        StringRef RemarkName,
     267      197717 :                                        const Instruction *Inst)
     268             :     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
     269      197717 :                                    RemarkName, *Inst->getParent()->getParent(),
     270      593151 :                                    Inst->getDebugLoc(), Inst->getParent()) {}
     271             : 
     272             : // Helper to allow for an assert before attempting to return an invalid
     273             : // reference.
     274             : static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
     275             :   assert(!Func->empty() && "Function does not have a body");
     276         189 :   return Func->front();
     277             : }
     278             : 
     279         189 : OptimizationRemark::OptimizationRemark(const char *PassName,
     280             :                                        StringRef RemarkName,
     281         189 :                                        const Function *Func)
     282             :     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
     283         189 :                                    RemarkName, *Func, Func->getSubprogram(),
     284         756 :                                    &getFirstFunctionBlock(Func)) {}
     285             : 
     286      363927 : bool OptimizationRemark::isEnabled(StringRef PassName) {
     287      364075 :   return PassRemarksOptLoc.Pattern &&
     288      728002 :          PassRemarksOptLoc.Pattern->match(PassName);
     289             : }
     290             : 
     291       13826 : OptimizationRemarkMissed::OptimizationRemarkMissed(
     292             :     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
     293             :     const Value *CodeRegion)
     294             :     : DiagnosticInfoIROptimization(
     295             :           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
     296       41478 :           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
     297             : 
     298      434316 : OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
     299             :                                                    StringRef RemarkName,
     300      434316 :                                                    const Instruction *Inst)
     301             :     : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
     302             :                                    PassName, RemarkName,
     303      434316 :                                    *Inst->getParent()->getParent(),
     304     1302948 :                                    Inst->getDebugLoc(), Inst->getParent()) {}
     305             : 
     306       17170 : bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
     307       17597 :   return PassRemarksMissedOptLoc.Pattern &&
     308       34767 :          PassRemarksMissedOptLoc.Pattern->match(PassName);
     309             : }
     310             : 
     311       10299 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
     312             :     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
     313             :     const Value *CodeRegion)
     314             :     : DiagnosticInfoIROptimization(
     315             :           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
     316       30897 :           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
     317             : 
     318        3003 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
     319             :                                                        StringRef RemarkName,
     320        3003 :                                                        const Instruction *Inst)
     321             :     : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
     322             :                                    PassName, RemarkName,
     323        3003 :                                    *Inst->getParent()->getParent(),
     324        9009 :                                    Inst->getDebugLoc(), Inst->getParent()) {}
     325             : 
     326          16 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
     327             :     enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
     328             :     const DiagnosticLocation &Loc, const Value *CodeRegion)
     329             :     : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
     330          16 :                                    *cast<BasicBlock>(CodeRegion)->getParent(),
     331          32 :                                    Loc, CodeRegion) {}
     332             : 
     333      281377 : bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
     334      281823 :   return PassRemarksAnalysisOptLoc.Pattern &&
     335      563200 :          PassRemarksAnalysisOptLoc.Pattern->match(PassName);
     336             : }
     337             : 
     338         112 : void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
     339         112 :   DP << Diagnostic;
     340         112 : }
     341             : 
     342          13 : DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
     343             :     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
     344             :     const Value *CodeRegion)
     345             :     : DiagnosticInfoIROptimization(
     346             :           DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
     347          39 :           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
     348             : 
     349          17 : bool DiagnosticInfoOptimizationFailure::isEnabled() const {
     350             :   // Only print warnings.
     351          17 :   return getSeverity() == DS_Warning;
     352             : }
     353             : 
     354         122 : void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
     355         244 :   std::string Str;
     356         244 :   raw_string_ostream OS(Str);
     357             : 
     358         366 :   OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
     359         610 :      << *getFunction().getFunctionType() << ": " << Msg << '\n';
     360         122 :   OS.flush();
     361         122 :   DP << Str;
     362         122 : }
     363             : 
     364          83 : void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
     365          83 :   DP << "Instruction selection used fallback path for " << getFunction();
     366          83 : }
     367             : 
     368     1794585 : DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
     369             : operator<<(StringRef S) {
     370     1794585 :   Args.emplace_back(S);
     371     1794584 :   return *this;
     372             : }
     373             : 
     374     1520467 : DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
     375             : operator<<(Argument A) {
     376     1520467 :   Args.push_back(std::move(A));
     377     1520467 :   return *this;
     378             : }
     379             : 
     380       95357 : DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
     381             : operator<<(setIsVerbose V) {
     382       95357 :   IsVerbose = true;
     383       95357 :   return *this;
     384             : }
     385             : 
     386        2440 : DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
     387             : operator<<(setExtraArgs EA) {
     388        4880 :   FirstExtraArgIndex = Args.size();
     389        2440 :   return *this;
     390             : }
     391             : 
     392        1114 : std::string DiagnosticInfoOptimizationBase::getMsg() const {
     393        2228 :   std::string Str;
     394        2228 :   raw_string_ostream OS(Str);
     395        4400 :   for (const DiagnosticInfoOptimizationBase::Argument &Arg :
     396        1114 :        make_range(Args.begin(), FirstExtraArgIndex == -1
     397        1108 :                                     ? Args.end()
     398        4456 :                                     : Args.begin() + FirstExtraArgIndex))
     399        4400 :     OS << Arg.Val;
     400        3342 :   return OS.str();
     401      216990 : }

Generated by: LCOV version 1.13