LLVM API Documentation

DiagnosticInfo.cpp
Go to the documentation of this file.
00001 //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the different classes involved in low level diagnostics.
00011 //
00012 // Diagnostics reporting is still done as part of the LLVMContext.
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "LLVMContextImpl.h"
00016 #include "llvm/ADT/Twine.h"
00017 #include "llvm/IR/Constants.h"
00018 #include "llvm/IR/DebugInfo.h"
00019 #include "llvm/IR/DiagnosticInfo.h"
00020 #include "llvm/IR/DiagnosticPrinter.h"
00021 #include "llvm/IR/Function.h"
00022 #include "llvm/IR/Instruction.h"
00023 #include "llvm/IR/Metadata.h"
00024 #include "llvm/IR/Module.h"
00025 #include "llvm/Support/Atomic.h"
00026 #include "llvm/Support/CommandLine.h"
00027 #include "llvm/Support/Regex.h"
00028 #include <string>
00029 
00030 using namespace llvm;
00031 
00032 namespace {
00033 
00034 /// \brief Regular expression corresponding to the value given in one of the
00035 /// -pass-remarks* command line flags. Passes whose name matches this regexp
00036 /// will emit a diagnostic when calling the associated diagnostic function
00037 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
00038 /// emitOptimizationRemarkAnalysis).
00039 struct PassRemarksOpt {
00040   std::shared_ptr<Regex> Pattern;
00041 
00042   void operator=(const std::string &Val) {
00043     // Create a regexp object to match pass names for emitOptimizationRemark.
00044     if (!Val.empty()) {
00045       Pattern = std::make_shared<Regex>(Val);
00046       std::string RegexError;
00047       if (!Pattern->isValid(RegexError))
00048         report_fatal_error("Invalid regular expression '" + Val +
00049                                "' in -pass-remarks: " + RegexError,
00050                            false);
00051     }
00052   };
00053 };
00054 
00055 static PassRemarksOpt PassRemarksOptLoc;
00056 static PassRemarksOpt PassRemarksMissedOptLoc;
00057 static PassRemarksOpt PassRemarksAnalysisOptLoc;
00058 
00059 // -pass-remarks
00060 //    Command line flag to enable emitOptimizationRemark()
00061 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
00062 PassRemarks("pass-remarks", cl::value_desc("pattern"),
00063             cl::desc("Enable optimization remarks from passes whose name match "
00064                      "the given regular expression"),
00065             cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
00066             cl::ZeroOrMore);
00067 
00068 // -pass-remarks-missed
00069 //    Command line flag to enable emitOptimizationRemarkMissed()
00070 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
00071     "pass-remarks-missed", cl::value_desc("pattern"),
00072     cl::desc("Enable missed optimization remarks from passes whose name match "
00073              "the given regular expression"),
00074     cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
00075     cl::ZeroOrMore);
00076 
00077 // -pass-remarks-analysis
00078 //    Command line flag to enable emitOptimizationRemarkAnalysis()
00079 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
00080 PassRemarksAnalysis(
00081     "pass-remarks-analysis", cl::value_desc("pattern"),
00082     cl::desc(
00083         "Enable optimization analysis remarks from passes whose name match "
00084         "the given regular expression"),
00085     cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
00086     cl::ZeroOrMore);
00087 }
00088 
00089 int llvm::getNextAvailablePluginDiagnosticKind() {
00090   static sys::cas_flag PluginKindID = DK_FirstPluginKind;
00091   return (int)sys::AtomicIncrement(&PluginKindID);
00092 }
00093 
00094 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
00095                                                  const Twine &MsgStr,
00096                                                  DiagnosticSeverity Severity)
00097     : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
00098       Instr(&I) {
00099   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
00100     if (SrcLoc->getNumOperands() != 0)
00101       if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
00102         LocCookie = CI->getZExtValue();
00103   }
00104 }
00105 
00106 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
00107   DP << getMsgStr();
00108   if (getLocCookie())
00109     DP << " at line " << getLocCookie();
00110 }
00111 
00112 void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {
00113   DP << "stack size limit exceeded (" << getStackSize() << ") in "
00114      << getFunction();
00115 }
00116 
00117 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
00118   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
00119      << ") in " << getModule();
00120 }
00121 
00122 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
00123   if (getFileName() && getLineNum() > 0)
00124     DP << getFileName() << ":" << getLineNum() << ": ";
00125   else if (getFileName())
00126     DP << getFileName() << ": ";
00127   DP << getMsg();
00128 }
00129 
00130 bool DiagnosticInfoOptimizationBase::isLocationAvailable() const {
00131   return getDebugLoc().isUnknown() == false;
00132 }
00133 
00134 void DiagnosticInfoOptimizationBase::getLocation(StringRef *Filename,
00135                                                  unsigned *Line,
00136                                                  unsigned *Column) const {
00137   DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext()));
00138   *Filename = DIL.getFilename();
00139   *Line = DIL.getLineNumber();
00140   *Column = DIL.getColumnNumber();
00141 }
00142 
00143 const std::string DiagnosticInfoOptimizationBase::getLocationStr() const {
00144   StringRef Filename("<unknown>");
00145   unsigned Line = 0;
00146   unsigned Column = 0;
00147   if (isLocationAvailable())
00148     getLocation(&Filename, &Line, &Column);
00149   return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
00150 }
00151 
00152 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
00153   DP << getLocationStr() << ": " << getMsg();
00154 }
00155 
00156 bool DiagnosticInfoOptimizationRemark::isEnabled() const {
00157   return PassRemarksOptLoc.Pattern &&
00158          PassRemarksOptLoc.Pattern->match(getPassName());
00159 }
00160 
00161 bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
00162   return PassRemarksMissedOptLoc.Pattern &&
00163          PassRemarksMissedOptLoc.Pattern->match(getPassName());
00164 }
00165 
00166 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
00167   return PassRemarksAnalysisOptLoc.Pattern &&
00168          PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
00169 }
00170 
00171 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
00172                                   const Function &Fn, const DebugLoc &DLoc,
00173                                   const Twine &Msg) {
00174   Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
00175 }
00176 
00177 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
00178                                         const Function &Fn,
00179                                         const DebugLoc &DLoc,
00180                                         const Twine &Msg) {
00181   Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
00182 }
00183 
00184 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
00185                                           const char *PassName,
00186                                           const Function &Fn,
00187                                           const DebugLoc &DLoc,
00188                                           const Twine &Msg) {
00189   Ctx.diagnose(
00190       DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
00191 }
00192 
00193 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
00194   // Only print warnings.
00195   return getSeverity() == DS_Warning;
00196 }
00197 
00198 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
00199                                     const DebugLoc &DLoc, const Twine &Msg) {
00200   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
00201       Fn, DLoc, Twine("loop not vectorized: " + Msg)));
00202 }
00203 
00204 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
00205                                      const DebugLoc &DLoc, const Twine &Msg) {
00206   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
00207       Fn, DLoc, Twine("loop not interleaved: " + Msg)));
00208 }