Line data Source code
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 "llvm/IR/DiagnosticInfo.h"
16 : #include "LLVMContextImpl.h"
17 : #include "llvm/ADT/StringExtras.h"
18 : #include "llvm/ADT/Twine.h"
19 : #include "llvm/ADT/iterator_range.h"
20 : #include "llvm/IR/BasicBlock.h"
21 : #include "llvm/IR/Constants.h"
22 : #include "llvm/IR/DebugInfoMetadata.h"
23 : #include "llvm/IR/DerivedTypes.h"
24 : #include "llvm/IR/DiagnosticPrinter.h"
25 : #include "llvm/IR/Function.h"
26 : #include "llvm/IR/GlobalValue.h"
27 : #include "llvm/IR/Instruction.h"
28 : #include "llvm/IR/LLVMContext.h"
29 : #include "llvm/IR/Metadata.h"
30 : #include "llvm/IR/Module.h"
31 : #include "llvm/IR/Type.h"
32 : #include "llvm/IR/Value.h"
33 : #include "llvm/Support/Casting.h"
34 : #include "llvm/Support/CommandLine.h"
35 : #include "llvm/Support/ErrorHandling.h"
36 : #include "llvm/Support/Regex.h"
37 : #include "llvm/Support/raw_ostream.h"
38 : #include "llvm/Support/ScopedPrinter.h"
39 : #include <atomic>
40 : #include <cassert>
41 : #include <memory>
42 : #include <string>
43 :
44 : using namespace llvm;
45 :
46 58828 : int llvm::getNextAvailablePluginDiagnosticKind() {
47 : static std::atomic<int> PluginKindID(DK_FirstPluginKind);
48 58828 : return ++PluginKindID;
49 : }
50 :
51 : const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
52 :
53 85 : DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
54 : const Twine &MsgStr,
55 85 : DiagnosticSeverity Severity)
56 85 : : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
57 85 : if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
58 12 : if (SrcLoc->getNumOperands() != 0)
59 : if (const auto *CI =
60 : mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
61 12 : LocCookie = CI->getZExtValue();
62 : }
63 85 : }
64 :
65 263 : void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
66 263 : DP << getMsgStr();
67 263 : if (getLocCookie())
68 8 : DP << " at line " << getLocCookie();
69 263 : }
70 :
71 14 : void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
72 14 : DP << getResourceName() << " limit";
73 :
74 14 : if (getResourceLimit() != 0)
75 5 : DP << " of " << getResourceLimit();
76 :
77 14 : DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
78 14 : }
79 :
80 50 : void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
81 50 : DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
82 50 : << ") in " << getModule();
83 50 : }
84 :
85 50 : void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
86 : DiagnosticPrinter &DP) const {
87 50 : DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
88 50 : }
89 :
90 26 : void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
91 26 : if (!FileName.empty()) {
92 20 : DP << getFileName();
93 20 : if (LineNum > 0)
94 16 : DP << ":" << getLineNum();
95 20 : DP << ": ";
96 : }
97 26 : DP << getMsg();
98 26 : }
99 :
100 8 : void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
101 8 : if (getFileName())
102 8 : DP << getFileName() << ": ";
103 8 : DP << getMsg();
104 8 : }
105 :
106 2572814 : DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
107 1286407 : if (!DL)
108 : return;
109 98919 : Filename = DL->getFilename();
110 98919 : Line = DL->getLine();
111 197838 : Column = DL->getColumn();
112 : }
113 :
114 424661 : DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
115 424661 : if (!SP)
116 : return;
117 10058 : Filename = SP->getFilename();
118 10058 : Line = SP->getScopeLine();
119 10058 : Column = 0;
120 : }
121 :
122 403 : void DiagnosticInfoWithLocationBase::getLocation(StringRef *Filename,
123 : unsigned *Line,
124 : unsigned *Column) const {
125 403 : *Filename = Loc.getFilename();
126 403 : *Line = Loc.getLine();
127 403 : *Column = Loc.getColumn();
128 403 : }
129 :
130 1317 : const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
131 : StringRef Filename("<unknown>");
132 1317 : unsigned Line = 0;
133 2634 : unsigned Column = 0;
134 1317 : if (isLocationAvailable())
135 375 : getLocation(&Filename, &Line, &Column);
136 3951 : return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
137 : }
138 :
139 728 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V)
140 728 : : Key(Key) {
141 : if (auto *F = dyn_cast<Function>(V)) {
142 582 : if (DISubprogram *SP = F->getSubprogram())
143 186 : Loc = SP;
144 : }
145 : else if (auto *I = dyn_cast<Instruction>(V))
146 136 : Loc = I->getDebugLoc();
147 :
148 : // Only include names that correspond to user variables. FIXME: We should use
149 : // debug info if available to get the name of the user variable.
150 728 : if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
151 1758 : Val = GlobalValue::dropLLVMManglingEscape(V->getName());
152 142 : else if (isa<Constant>(V)) {
153 4 : raw_string_ostream OS(Val);
154 4 : V->printAsOperand(OS, /*PrintType=*/false);
155 : } else if (auto *I = dyn_cast<Instruction>(V))
156 : Val = I->getOpcodeName();
157 728 : }
158 :
159 18169 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
160 18169 : : Key(Key) {
161 18169 : raw_string_ostream OS(Val);
162 : OS << *T;
163 18169 : }
164 :
165 2914224 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
166 2914224 : : Key(Key), Val(S.str()) {}
167 :
168 677183 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
169 677183 : : Key(Key), Val(itostr(N)) {}
170 :
171 0 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
172 0 : : Key(Key), Val(llvm::to_string(N)) {}
173 :
174 41 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
175 41 : : Key(Key), Val(itostr(N)) {}
176 :
177 0 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
178 0 : : Key(Key), Val(itostr(N)) {}
179 :
180 95886 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
181 95886 : : Key(Key), Val(utostr(N)) {}
182 :
183 386 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
184 386 : unsigned long N)
185 386 : : Key(Key), Val(utostr(N)) {}
186 :
187 0 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
188 0 : unsigned long long N)
189 0 : : Key(Key), Val(utostr(N)) {}
190 :
191 126 : DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
192 252 : : Key(Key), Loc(Loc) {
193 126 : if (Loc) {
194 38 : Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
195 57 : Twine(Loc.getCol())).str();
196 : } else {
197 : Val = "<UNKNOWN LOCATION>";
198 : }
199 126 : }
200 :
201 1150 : void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
202 2300 : DP << getLocationStr() << ": " << getMsg();
203 1150 : if (Hotness)
204 46 : DP << " (hotness: " << *Hotness << ")";
205 1150 : }
206 :
207 348557 : OptimizationRemark::OptimizationRemark(const char *PassName,
208 : StringRef RemarkName,
209 : const DiagnosticLocation &Loc,
210 348557 : const Value *CodeRegion)
211 : : DiagnosticInfoIROptimization(
212 : DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
213 697114 : *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
214 :
215 95827 : OptimizationRemark::OptimizationRemark(const char *PassName,
216 : StringRef RemarkName,
217 95827 : const Instruction *Inst)
218 : : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
219 95827 : RemarkName, *Inst->getParent()->getParent(),
220 191654 : Inst->getDebugLoc(), Inst->getParent()) {}
221 :
222 : // Helper to allow for an assert before attempting to return an invalid
223 : // reference.
224 : static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
225 : assert(!Func->empty() && "Function does not have a body");
226 : return Func->front();
227 : }
228 :
229 16 : OptimizationRemark::OptimizationRemark(const char *PassName,
230 : StringRef RemarkName,
231 16 : const Function *Func)
232 : : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
233 16 : RemarkName, *Func, Func->getSubprogram(),
234 16 : &getFirstFunctionBlock(Func)) {}
235 :
236 350754 : bool OptimizationRemark::isEnabled() const {
237 350754 : const Function &Fn = getFunction();
238 350754 : LLVMContext &Ctx = Fn.getContext();
239 701508 : return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
240 : }
241 :
242 844269 : OptimizationRemarkMissed::OptimizationRemarkMissed(
243 : const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
244 844269 : const Value *CodeRegion)
245 : : DiagnosticInfoIROptimization(
246 : DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
247 1688538 : *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
248 :
249 235 : OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
250 : StringRef RemarkName,
251 235 : const Instruction *Inst)
252 : : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
253 : PassName, RemarkName,
254 235 : *Inst->getParent()->getParent(),
255 470 : Inst->getDebugLoc(), Inst->getParent()) {}
256 :
257 842935 : bool OptimizationRemarkMissed::isEnabled() const {
258 842935 : const Function &Fn = getFunction();
259 842935 : LLVMContext &Ctx = Fn.getContext();
260 1685870 : return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
261 : }
262 :
263 12334 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
264 : const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
265 12334 : const Value *CodeRegion)
266 : : DiagnosticInfoIROptimization(
267 : DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
268 24668 : *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
269 :
270 2825 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
271 : StringRef RemarkName,
272 2825 : const Instruction *Inst)
273 : : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
274 : PassName, RemarkName,
275 2825 : *Inst->getParent()->getParent(),
276 5650 : Inst->getDebugLoc(), Inst->getParent()) {}
277 :
278 9 : OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
279 : enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
280 9 : const DiagnosticLocation &Loc, const Value *CodeRegion)
281 : : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
282 9 : *cast<BasicBlock>(CodeRegion)->getParent(),
283 9 : Loc, CodeRegion) {}
284 :
285 9168 : bool OptimizationRemarkAnalysis::isEnabled() const {
286 9168 : const Function &Fn = getFunction();
287 9168 : LLVMContext &Ctx = Fn.getContext();
288 18336 : return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
289 8758 : shouldAlwaysPrint();
290 : }
291 :
292 120 : void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
293 120 : DP << Diagnostic;
294 120 : }
295 :
296 13 : DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
297 : const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
298 13 : const Value *CodeRegion)
299 : : DiagnosticInfoIROptimization(
300 : DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
301 26 : *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
302 :
303 17 : bool DiagnosticInfoOptimizationFailure::isEnabled() const {
304 : // Only print warnings.
305 17 : return getSeverity() == DS_Warning;
306 : }
307 :
308 167 : void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
309 : std::string Str;
310 167 : raw_string_ostream OS(Str);
311 :
312 501 : OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
313 334 : << *getFunction().getFunctionType() << ": " << Msg << '\n';
314 : OS.flush();
315 167 : DP << Str;
316 167 : }
317 :
318 103 : void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
319 103 : DP << "Instruction selection used fallback path for " << getFunction();
320 103 : }
321 :
322 2303282 : void DiagnosticInfoOptimizationBase::insert(StringRef S) {
323 2303282 : Args.emplace_back(S);
324 2303282 : }
325 :
326 617239 : void DiagnosticInfoOptimizationBase::insert(Argument A) {
327 617239 : Args.push_back(std::move(A));
328 617239 : }
329 :
330 44 : void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
331 44 : IsVerbose = true;
332 44 : }
333 :
334 27 : void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
335 27 : FirstExtraArgIndex = Args.size();
336 27 : }
337 :
338 1230 : std::string DiagnosticInfoOptimizationBase::getMsg() const {
339 : std::string Str;
340 1230 : raw_string_ostream OS(Str);
341 3117 : for (const DiagnosticInfoOptimizationBase::Argument &Arg :
342 1230 : make_range(Args.begin(), FirstExtraArgIndex == -1
343 : ? Args.end()
344 5577 : : Args.begin() + FirstExtraArgIndex))
345 : OS << Arg.Val;
346 1230 : return OS.str();
347 : }
348 :
349 : namespace llvm {
350 : namespace yaml {
351 :
352 418 : void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
353 : IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
354 : assert(io.outputting() && "input not yet implemented");
355 :
356 836 : if (io.mapTag("!Passed",
357 313 : (OptDiag->getKind() == DK_OptimizationRemark ||
358 418 : OptDiag->getKind() == DK_MachineOptimizationRemark)))
359 : ;
360 622 : else if (io.mapTag(
361 : "!Missed",
362 208 : (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
363 311 : OptDiag->getKind() == DK_MachineOptimizationRemarkMissed)))
364 : ;
365 380 : else if (io.mapTag(
366 : "!Analysis",
367 144 : (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
368 190 : OptDiag->getKind() == DK_MachineOptimizationRemarkAnalysis)))
369 : ;
370 3 : else if (io.mapTag("!AnalysisFPCommute",
371 3 : OptDiag->getKind() ==
372 3 : DK_OptimizationRemarkAnalysisFPCommute))
373 : ;
374 3 : else if (io.mapTag("!AnalysisAliasing",
375 3 : OptDiag->getKind() ==
376 3 : DK_OptimizationRemarkAnalysisAliasing))
377 : ;
378 4 : else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
379 : ;
380 : else
381 0 : llvm_unreachable("Unknown remark type");
382 :
383 : // These are read-only for now.
384 418 : DiagnosticLocation DL = OptDiag->getLocation();
385 : StringRef FN =
386 418 : GlobalValue::dropLLVMManglingEscape(OptDiag->getFunction().getName());
387 :
388 418 : StringRef PassName(OptDiag->PassName);
389 : io.mapRequired("Pass", PassName);
390 418 : io.mapRequired("Name", OptDiag->RemarkName);
391 418 : if (!io.outputting() || DL.isValid())
392 : io.mapOptional("DebugLoc", DL);
393 : io.mapRequired("Function", FN);
394 418 : io.mapOptional("Hotness", OptDiag->Hotness);
395 418 : io.mapOptional("Args", OptDiag->Args);
396 418 : }
397 :
398 : template <> struct MappingTraits<DiagnosticLocation> {
399 176 : static void mapping(IO &io, DiagnosticLocation &DL) {
400 : assert(io.outputting() && "input not yet implemented");
401 :
402 176 : StringRef File = DL.getFilename();
403 176 : unsigned Line = DL.getLine();
404 176 : unsigned Col = DL.getColumn();
405 :
406 : io.mapRequired("File", File);
407 : io.mapRequired("Line", Line);
408 : io.mapRequired("Column", Col);
409 176 : }
410 :
411 : static const bool flow = true;
412 : };
413 :
414 : // Implement this as a mapping for now to get proper quotation for the value.
415 : template <> struct MappingTraits<DiagnosticInfoOptimizationBase::Argument> {
416 1487 : static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A) {
417 : assert(io.outputting() && "input not yet implemented");
418 1487 : io.mapRequired(A.Key.data(), A.Val);
419 1487 : if (A.Loc.isValid())
420 54 : io.mapOptional("DebugLoc", A.Loc);
421 1487 : }
422 : };
423 :
424 : } // end namespace yaml
425 : } // end namespace llvm
426 :
427 : LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument)
|