1 //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the different classes involved in low level diagnostics.
12 // Diagnostics reporting is still done as part of the LLVMContext.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "LLVMContextImpl.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/DiagnosticPrinter.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instruction.h"
24 #include "llvm/IR/Metadata.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Regex.h"
35 /// \brief Regular expression corresponding to the value given in one of the
36 /// -pass-remarks* command line flags. Passes whose name matches this regexp
37 /// will emit a diagnostic when calling the associated diagnostic function
38 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
39 /// emitOptimizationRemarkAnalysis).
40 struct PassRemarksOpt {
41 std::shared_ptr<Regex> Pattern;
43 void operator=(const std::string &Val) {
44 // Create a regexp object to match pass names for emitOptimizationRemark.
46 Pattern = std::make_shared<Regex>(Val);
47 std::string RegexError;
48 if (!Pattern->isValid(RegexError))
49 report_fatal_error("Invalid regular expression '" + Val +
50 "' in -pass-remarks: " + RegexError,
56 static PassRemarksOpt PassRemarksOptLoc;
57 static PassRemarksOpt PassRemarksMissedOptLoc;
58 static PassRemarksOpt PassRemarksAnalysisOptLoc;
61 // Command line flag to enable emitOptimizationRemark()
62 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
63 PassRemarks("pass-remarks", cl::value_desc("pattern"),
64 cl::desc("Enable optimization remarks from passes whose name match "
65 "the given regular expression"),
66 cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
69 // -pass-remarks-missed
70 // Command line flag to enable emitOptimizationRemarkMissed()
71 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
72 "pass-remarks-missed", cl::value_desc("pattern"),
73 cl::desc("Enable missed optimization remarks from passes whose name match "
74 "the given regular expression"),
75 cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
78 // -pass-remarks-analysis
79 // Command line flag to enable emitOptimizationRemarkAnalysis()
80 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
82 "pass-remarks-analysis", cl::value_desc("pattern"),
84 "Enable optimization analysis remarks from passes whose name match "
85 "the given regular expression"),
86 cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
90 int llvm::getNextAvailablePluginDiagnosticKind() {
91 static std::atomic<int> PluginKindID(DK_FirstPluginKind);
92 return ++PluginKindID;
95 const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
97 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
99 DiagnosticSeverity Severity)
100 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
102 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
103 if (SrcLoc->getNumOperands() != 0)
105 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
106 LocCookie = CI->getZExtValue();
110 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
113 DP << " at line " << getLocCookie();
116 void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
117 DP << getResourceName() << " limit";
119 if (getResourceLimit() != 0)
120 DP << " of " << getResourceLimit();
122 DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
125 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
126 DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
127 << ") in " << getModule();
130 void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
131 DiagnosticPrinter &DP) const {
132 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
135 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
136 if (!FileName.empty()) {
139 DP << ":" << getLineNum();
145 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
147 DP << getFileName() << ": ";
151 bool DiagnosticInfoWithDebugLocBase::isLocationAvailable() const {
152 return getDebugLoc();
155 void DiagnosticInfoWithDebugLocBase::getLocation(StringRef *Filename,
157 unsigned *Column) const {
158 DILocation *L = getDebugLoc();
159 assert(L != nullptr && "debug location is invalid");
160 *Filename = L->getFilename();
161 *Line = L->getLine();
162 *Column = L->getColumn();
165 const std::string DiagnosticInfoWithDebugLocBase::getLocationStr() const {
166 StringRef Filename("<unknown>");
169 if (isLocationAvailable())
170 getLocation(&Filename, &Line, &Column);
171 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
174 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Value *V)
176 if (auto *F = dyn_cast<Function>(V)) {
177 if (DISubprogram *SP = F->getSubprogram())
178 DLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
180 else if (auto *I = dyn_cast<Instruction>(V))
181 DLoc = I->getDebugLoc();
183 // Only include names that correspond to user variables. FIXME: we should use
184 // debug info if available to get the name of the user variable.
185 if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
186 Val = GlobalValue::getRealLinkageName(V->getName());
187 else if (isa<Constant>(V)) {
188 raw_string_ostream OS(Val);
189 V->printAsOperand(OS, /*PrintType=*/false);
190 } else if (auto *I = dyn_cast<Instruction>(V))
191 Val = I->getOpcodeName();
194 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Type *T)
196 raw_string_ostream OS(Val);
200 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
201 : Key(Key), Val(itostr(N)) {}
203 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
204 : Key(Key), Val(utostr(N)) {}
206 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
207 DP << getLocationStr() << ": " << getMsg();
209 DP << " (hotness: " << *Hotness << ")";
212 OptimizationRemark::OptimizationRemark(const char *PassName,
213 StringRef RemarkName,
214 const DebugLoc &DLoc, Value *CodeRegion)
215 : DiagnosticInfoOptimizationBase(
216 DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
217 *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
219 OptimizationRemark::OptimizationRemark(const char *PassName,
220 StringRef RemarkName, Instruction *Inst)
221 : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, PassName,
223 *Inst->getParent()->getParent(),
224 Inst->getDebugLoc(), Inst->getParent()) {}
226 bool OptimizationRemark::isEnabled() const {
227 return PassRemarksOptLoc.Pattern &&
228 PassRemarksOptLoc.Pattern->match(getPassName());
231 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
232 StringRef RemarkName,
233 const DebugLoc &DLoc,
235 : DiagnosticInfoOptimizationBase(
236 DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
237 *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
239 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
240 StringRef RemarkName,
242 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
243 PassName, RemarkName,
244 *Inst->getParent()->getParent(),
245 Inst->getDebugLoc(), Inst->getParent()) {}
247 bool OptimizationRemarkMissed::isEnabled() const {
248 return PassRemarksMissedOptLoc.Pattern &&
249 PassRemarksMissedOptLoc.Pattern->match(getPassName());
252 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
253 StringRef RemarkName,
254 const DebugLoc &DLoc,
256 : DiagnosticInfoOptimizationBase(
257 DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
258 *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
260 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
261 StringRef RemarkName,
263 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
264 PassName, RemarkName,
265 *Inst->getParent()->getParent(),
266 Inst->getDebugLoc(), Inst->getParent()) {}
268 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(enum DiagnosticKind Kind,
269 const char *PassName,
270 StringRef RemarkName,
271 const DebugLoc &DLoc,
273 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
274 *cast<BasicBlock>(CodeRegion)->getParent(),
277 bool OptimizationRemarkAnalysis::isEnabled() const {
278 return shouldAlwaysPrint() ||
279 (PassRemarksAnalysisOptLoc.Pattern &&
280 PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
283 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
287 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
288 const Function &Fn, const DebugLoc &DLoc,
290 Ctx.diagnose(OptimizationRemark(PassName, Fn, DLoc, Msg));
293 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
295 const DebugLoc &DLoc,
297 Ctx.diagnose(OptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
300 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
301 const char *PassName,
303 const DebugLoc &DLoc,
305 Ctx.diagnose(OptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
308 void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
309 const char *PassName,
311 const DebugLoc &DLoc,
313 Ctx.diagnose(OptimizationRemarkAnalysisFPCommute(PassName, Fn, DLoc, Msg));
316 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
317 const char *PassName,
319 const DebugLoc &DLoc,
321 Ctx.diagnose(OptimizationRemarkAnalysisAliasing(PassName, Fn, DLoc, Msg));
324 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
325 // Only print warnings.
326 return getSeverity() == DS_Warning;
329 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
331 raw_string_ostream OS(Str);
333 OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
334 << *getFunction().getFunctionType() << ": " << Msg << '\n';
339 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
340 const DebugLoc &DLoc, const Twine &Msg) {
341 Ctx.diagnose(DiagnosticInfoOptimizationFailure(
342 Fn, DLoc, Twine("loop not vectorized: " + Msg)));
345 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
346 const DebugLoc &DLoc, const Twine &Msg) {
347 Ctx.diagnose(DiagnosticInfoOptimizationFailure(
348 Fn, DLoc, Twine("loop not interleaved: " + Msg)));
351 void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
352 DP << "Instruction selection used fallback path for " << getFunction();
355 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
356 operator<<(StringRef S) {
357 Args.emplace_back(S);
361 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
362 operator<<(Argument A) {
363 Args.push_back(std::move(A));
367 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
368 operator<<(setIsVerbose V) {
373 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
374 operator<<(setExtraArgs EA) {
375 FirstExtraArgIndex = Args.size();
379 std::string DiagnosticInfoOptimizationBase::getMsg() const {
381 raw_string_ostream OS(Str);
382 for (const DiagnosticInfoOptimizationBase::Argument &Arg :
383 make_range(Args.begin(), FirstExtraArgIndex == -1
385 : Args.begin() + FirstExtraArgIndex))