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/CommandLine.h" 26 #include "llvm/Support/Regex.h" 27 #include <atomic> 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 std::atomic<int> PluginKindID(DK_FirstPluginKind); 91 return ++PluginKindID; 92 } 93 94 const char *DiagnosticInfoOptimizationRemarkAnalysis::AlwaysPrint = ""; 95 96 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I, 97 const Twine &MsgStr, 98 DiagnosticSeverity Severity) 99 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), 100 Instr(&I) { 101 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) { 102 if (SrcLoc->getNumOperands() != 0) 103 if (const auto *CI = 104 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0))) 105 LocCookie = CI->getZExtValue(); 106 } 107 } 108 109 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const { 110 DP << getMsgStr(); 111 if (getLocCookie()) 112 DP << " at line " << getLocCookie(); 113 } 114 115 void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const { 116 DP << getResourceName() << " limit"; 117 118 if (getResourceLimit() != 0) 119 DP << " of " << getResourceLimit(); 120 121 DP << " exceeded (" << getResourceSize() << ") in " << getFunction(); 122 } 123 124 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const { 125 DP << "ignoring debug info with an invalid version (" << getMetadataVersion() 126 << ") in " << getModule(); 127 } 128 129 void DiagnosticInfoIgnoringInvalidDebugMetadata::print( 130 DiagnosticPrinter &DP) const { 131 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier(); 132 } 133 134 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const { 135 if (!FileName.empty()) { 136 DP << getFileName(); 137 if (LineNum > 0) 138 DP << ":" << getLineNum(); 139 DP << ": "; 140 } 141 DP << getMsg(); 142 } 143 144 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const { 145 if (getFileName()) 146 DP << getFileName() << ": "; 147 DP << getMsg(); 148 } 149 150 bool DiagnosticInfoWithDebugLocBase::isLocationAvailable() const { 151 return getDebugLoc(); 152 } 153 154 void DiagnosticInfoWithDebugLocBase::getLocation(StringRef *Filename, 155 unsigned *Line, 156 unsigned *Column) const { 157 DILocation *L = getDebugLoc(); 158 assert(L != nullptr && "debug location is invalid"); 159 *Filename = L->getFilename(); 160 *Line = L->getLine(); 161 *Column = L->getColumn(); 162 } 163 164 const std::string DiagnosticInfoWithDebugLocBase::getLocationStr() const { 165 StringRef Filename("<unknown>"); 166 unsigned Line = 0; 167 unsigned Column = 0; 168 if (isLocationAvailable()) 169 getLocation(&Filename, &Line, &Column); 170 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str(); 171 } 172 173 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const { 174 DP << getLocationStr() << ": " << getMsg(); 175 } 176 177 bool DiagnosticInfoOptimizationRemark::isEnabled() const { 178 return PassRemarksOptLoc.Pattern && 179 PassRemarksOptLoc.Pattern->match(getPassName()); 180 } 181 182 bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const { 183 return PassRemarksMissedOptLoc.Pattern && 184 PassRemarksMissedOptLoc.Pattern->match(getPassName()); 185 } 186 187 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const { 188 return shouldAlwaysPrint() || 189 (PassRemarksAnalysisOptLoc.Pattern && 190 PassRemarksAnalysisOptLoc.Pattern->match(getPassName())); 191 } 192 193 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const { 194 DP << Diagnostic; 195 } 196 197 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, 198 const Function &Fn, const DebugLoc &DLoc, 199 const Twine &Msg) { 200 Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg)); 201 } 202 203 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, 204 const Function &Fn, 205 const DebugLoc &DLoc, 206 const Twine &Msg) { 207 Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg)); 208 } 209 210 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx, 211 const char *PassName, 212 const Function &Fn, 213 const DebugLoc &DLoc, 214 const Twine &Msg) { 215 Ctx.diagnose( 216 DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg)); 217 } 218 219 void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, 220 const char *PassName, 221 const Function &Fn, 222 const DebugLoc &DLoc, 223 const Twine &Msg) { 224 Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisFPCommute(PassName, Fn, 225 DLoc, Msg)); 226 } 227 228 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, 229 const char *PassName, 230 const Function &Fn, 231 const DebugLoc &DLoc, 232 const Twine &Msg) { 233 Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisAliasing(PassName, Fn, 234 DLoc, Msg)); 235 } 236 237 bool DiagnosticInfoOptimizationFailure::isEnabled() const { 238 // Only print warnings. 239 return getSeverity() == DS_Warning; 240 } 241 242 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const { 243 std::string Str; 244 raw_string_ostream OS(Str); 245 246 OS << getLocationStr() << ": in function " << getFunction().getName() << ' ' 247 << *getFunction().getFunctionType() << ": " << Msg << '\n'; 248 OS.flush(); 249 DP << Str; 250 } 251 252 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, 253 const DebugLoc &DLoc, const Twine &Msg) { 254 Ctx.diagnose(DiagnosticInfoOptimizationFailure( 255 Fn, DLoc, Twine("loop not vectorized: " + Msg))); 256 } 257 258 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, 259 const DebugLoc &DLoc, const Twine &Msg) { 260 Ctx.diagnose(DiagnosticInfoOptimizationFailure( 261 Fn, DLoc, Twine("loop not interleaved: " + Msg))); 262 } 263