LLVM API Documentation
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 }