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 "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"
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 when calling the associated diagnostic function
49 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
50 /// emitOptimizationRemarkAnalysis).
51 struct PassRemarksOpt {
52 std::shared_ptr<Regex> Pattern;
54 void operator=(const std::string &Val) {
55 // Create a regexp object to match pass names for emitOptimizationRemark.
57 Pattern = std::make_shared<Regex>(Val);
58 std::string RegexError;
59 if (!Pattern->isValid(RegexError))
60 report_fatal_error("Invalid regular expression '" + Val +
61 "' in -pass-remarks: " + RegexError,
67 } // end anonymous namespace
69 static PassRemarksOpt PassRemarksOptLoc;
70 static PassRemarksOpt PassRemarksMissedOptLoc;
71 static PassRemarksOpt PassRemarksAnalysisOptLoc;
74 // Command line flag to enable emitOptimizationRemark()
75 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
76 PassRemarks("pass-remarks", cl::value_desc("pattern"),
77 cl::desc("Enable optimization remarks from passes whose name match "
78 "the given regular expression"),
79 cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
82 // -pass-remarks-missed
83 // Command line flag to enable emitOptimizationRemarkMissed()
84 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
85 "pass-remarks-missed", cl::value_desc("pattern"),
86 cl::desc("Enable missed optimization remarks from passes whose name match "
87 "the given regular expression"),
88 cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
91 // -pass-remarks-analysis
92 // Command line flag to enable emitOptimizationRemarkAnalysis()
93 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
95 "pass-remarks-analysis", cl::value_desc("pattern"),
97 "Enable optimization analysis remarks from passes whose name match "
98 "the given regular expression"),
99 cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
102 int llvm::getNextAvailablePluginDiagnosticKind() {
103 static std::atomic<int> PluginKindID(DK_FirstPluginKind);
104 return ++PluginKindID;
107 const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
109 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
111 DiagnosticSeverity Severity)
112 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
113 if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
114 if (SrcLoc->getNumOperands() != 0)
116 mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
117 LocCookie = CI->getZExtValue();
121 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
124 DP << " at line " << getLocCookie();
127 void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
128 DP << getResourceName() << " limit";
130 if (getResourceLimit() != 0)
131 DP << " of " << getResourceLimit();
133 DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
136 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
137 DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
138 << ") in " << getModule();
141 void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
142 DiagnosticPrinter &DP) const {
143 DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
146 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
147 if (!FileName.empty()) {
150 DP << ":" << getLineNum();
156 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
158 DP << getFileName() << ": ";
162 DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
165 Filename = DL->getFilename();
166 Line = DL->getLine();
167 Column = DL->getColumn();
170 DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
173 Filename = SP->getFilename();
174 Line = SP->getScopeLine();
178 void DiagnosticInfoWithLocationBase::getLocation(StringRef *Filename,
180 unsigned *Column) const {
181 *Filename = Loc.getFilename();
182 *Line = Loc.getLine();
183 *Column = Loc.getColumn();
186 const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
187 StringRef Filename("<unknown>");
190 if (isLocationAvailable())
191 getLocation(&Filename, &Line, &Column);
192 return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
195 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V)
197 if (auto *F = dyn_cast<Function>(V)) {
198 if (DISubprogram *SP = F->getSubprogram())
201 else if (auto *I = dyn_cast<Instruction>(V))
202 Loc = I->getDebugLoc();
204 // Only include names that correspond to user variables. FIXME: we should use
205 // debug info if available to get the name of the user variable.
206 if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
207 Val = GlobalValue::dropLLVMManglingEscape(V->getName());
208 else if (isa<Constant>(V)) {
209 raw_string_ostream OS(Val);
210 V->printAsOperand(OS, /*PrintType=*/false);
211 } else if (auto *I = dyn_cast<Instruction>(V))
212 Val = I->getOpcodeName();
215 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
217 raw_string_ostream OS(Val);
221 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
222 : Key(Key), Val(itostr(N)) {}
224 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
225 : Key(Key), Val(utostr(N)) {}
227 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
228 DP << getLocationStr() << ": " << getMsg();
230 DP << " (hotness: " << *Hotness << ")";
233 OptimizationRemark::OptimizationRemark(const char *PassName,
234 StringRef RemarkName,
235 const DiagnosticLocation &Loc,
236 const Value *CodeRegion)
237 : DiagnosticInfoIROptimization(
238 DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
239 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
241 OptimizationRemark::OptimizationRemark(const char *PassName,
242 StringRef RemarkName,
243 const Instruction *Inst)
244 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
245 RemarkName, *Inst->getParent()->getParent(),
246 Inst->getDebugLoc(), Inst->getParent()) {}
248 // Helper to allow for an assert before attempting to return an invalid
250 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
251 assert(!Func->empty() && "Function does not have a body");
252 return Func->front();
255 OptimizationRemark::OptimizationRemark(const char *PassName,
256 StringRef RemarkName,
257 const Function *Func)
258 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
259 RemarkName, *Func, Func->getSubprogram(),
260 &getFirstFunctionBlock(Func)) {}
262 bool OptimizationRemark::isEnabled(StringRef PassName) {
263 return PassRemarksOptLoc.Pattern &&
264 PassRemarksOptLoc.Pattern->match(PassName);
267 OptimizationRemarkMissed::OptimizationRemarkMissed(
268 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
269 const Value *CodeRegion)
270 : DiagnosticInfoIROptimization(
271 DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
272 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
274 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
275 StringRef RemarkName,
276 const Instruction *Inst)
277 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
278 PassName, RemarkName,
279 *Inst->getParent()->getParent(),
280 Inst->getDebugLoc(), Inst->getParent()) {}
282 bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
283 return PassRemarksMissedOptLoc.Pattern &&
284 PassRemarksMissedOptLoc.Pattern->match(PassName);
287 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
288 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
289 const Value *CodeRegion)
290 : DiagnosticInfoIROptimization(
291 DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
292 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
294 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
295 StringRef RemarkName,
296 const Instruction *Inst)
297 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
298 PassName, RemarkName,
299 *Inst->getParent()->getParent(),
300 Inst->getDebugLoc(), Inst->getParent()) {}
302 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
303 enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
304 const DiagnosticLocation &Loc, const Value *CodeRegion)
305 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
306 *cast<BasicBlock>(CodeRegion)->getParent(),
309 bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
310 return PassRemarksAnalysisOptLoc.Pattern &&
311 PassRemarksAnalysisOptLoc.Pattern->match(PassName);
314 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
318 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
320 const DiagnosticLocation &Loc,
322 Ctx.diagnose(OptimizationRemark(PassName, Fn, Loc, Msg));
325 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
327 const DiagnosticLocation &Loc,
329 Ctx.diagnose(OptimizationRemarkMissed(PassName, Fn, Loc, Msg));
332 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
333 const char *PassName,
335 const DiagnosticLocation &Loc,
337 Ctx.diagnose(OptimizationRemarkAnalysis(PassName, Fn, Loc, Msg));
340 void llvm::emitOptimizationRemarkAnalysisFPCommute(
341 LLVMContext &Ctx, const char *PassName, const Function &Fn,
342 const DiagnosticLocation &Loc, const Twine &Msg) {
343 Ctx.diagnose(OptimizationRemarkAnalysisFPCommute(PassName, Fn, Loc, Msg));
346 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
347 const char *PassName,
349 const DiagnosticLocation &Loc,
351 Ctx.diagnose(OptimizationRemarkAnalysisAliasing(PassName, Fn, Loc, Msg));
354 DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
355 const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
356 const Value *CodeRegion)
357 : DiagnosticInfoIROptimization(
358 DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
359 *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
361 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
362 // Only print warnings.
363 return getSeverity() == DS_Warning;
366 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
368 raw_string_ostream OS(Str);
370 OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
371 << *getFunction().getFunctionType() << ": " << Msg << '\n';
376 void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
377 DP << "Instruction selection used fallback path for " << getFunction();
380 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
381 operator<<(StringRef S) {
382 Args.emplace_back(S);
386 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
387 operator<<(Argument A) {
388 Args.push_back(std::move(A));
392 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
393 operator<<(setIsVerbose V) {
398 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
399 operator<<(setExtraArgs EA) {
400 FirstExtraArgIndex = Args.size();
404 std::string DiagnosticInfoOptimizationBase::getMsg() const {
406 raw_string_ostream OS(Str);
407 for (const DiagnosticInfoOptimizationBase::Argument &Arg :
408 make_range(Args.begin(), FirstExtraArgIndex == -1
410 : Args.begin() + FirstExtraArgIndex))