LLVM  12.0.0git
DiagnosticInfo.cpp
Go to the documentation of this file.
1 //===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the different classes involved in low level diagnostics.
10 //
11 // Diagnostics reporting is still done as part of the LLVMContext.
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/DiagnosticInfo.h"
15 #include "LLVMContextImpl.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/Twine.h"
19 #include "llvm/IR/BasicBlock.h"
20 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/DerivedTypes.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"
35 #include "llvm/Support/Path.h"
36 #include "llvm/Support/Regex.h"
39 #include <atomic>
40 #include <cassert>
41 #include <memory>
42 #include <string>
43 
44 using namespace llvm;
45 
47  static std::atomic<int> PluginKindID(DK_FirstPluginKind);
48  return ++PluginKindID;
49 }
50 
52 
54  const Twine &MsgStr,
55  DiagnosticSeverity Severity)
56  : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
57  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
58  if (SrcLoc->getNumOperands() != 0)
59  if (const auto *CI =
60  mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
61  LocCookie = CI->getZExtValue();
62  }
63 }
64 
66  DP << getMsgStr();
67  if (getLocCookie())
68  DP << " at line " << getLocCookie();
69 }
70 
72  DP << getResourceName() << " limit";
73 
74  if (getResourceLimit() != 0)
75  DP << " of " << getResourceLimit();
76 
77  DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
78 }
79 
81  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
82  << ") in " << getModule();
83 }
84 
86  DiagnosticPrinter &DP) const {
87  DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
88 }
89 
91  if (!FileName.empty()) {
92  DP << getFileName();
93  if (LineNum > 0)
94  DP << ":" << getLineNum();
95  DP << ": ";
96  }
97  DP << getMsg();
98 }
99 
101  if (getFileName())
102  DP << getFileName() << ": ";
103  DP << getMsg();
104 }
105 
106 void DiagnosticInfo::anchor() {}
107 void DiagnosticInfoStackSize::anchor() {}
108 void DiagnosticInfoWithLocationBase::anchor() {}
109 void DiagnosticInfoIROptimization::anchor() {}
110 
112  if (!DL)
113  return;
114  File = DL->getFile();
115  Line = DL->getLine();
116  Column = DL->getColumn();
117 }
118 
120  if (!SP)
121  return;
122 
123  File = SP->getFile();
124  Line = SP->getScopeLine();
125  Column = 0;
126 }
127 
129  return File->getFilename();
130 }
131 
133  StringRef Name = File->getFilename();
134  if (sys::path::is_absolute(Name))
135  return std::string(Name);
136 
137  SmallString<128> Path;
138  sys::path::append(Path, File->getDirectory(), Name);
140 }
141 
143  return Loc.getAbsolutePath();
144 }
145 
147  unsigned &Line,
148  unsigned &Column) const {
149  RelativePath = Loc.getRelativePath();
150  Line = Loc.getLine();
151  Column = Loc.getColumn();
152 }
153 
155  StringRef Filename("<unknown>");
156  unsigned Line = 0;
157  unsigned Column = 0;
158  if (isLocationAvailable())
159  getLocation(Filename, Line, Column);
160  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
161 }
162 
164  const Value *V)
165  : Key(std::string(Key)) {
166  if (auto *F = dyn_cast<Function>(V)) {
167  if (DISubprogram *SP = F->getSubprogram())
168  Loc = SP;
169  }
170  else if (auto *I = dyn_cast<Instruction>(V))
171  Loc = I->getDebugLoc();
172 
173  // Only include names that correspond to user variables. FIXME: We should use
174  // debug info if available to get the name of the user variable.
175  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
176  Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
177  else if (isa<Constant>(V)) {
179  V->printAsOperand(OS, /*PrintType=*/false);
180  } else if (auto *I = dyn_cast<Instruction>(V))
181  Val = I->getOpcodeName();
182 }
183 
185  : Key(std::string(Key)) {
187  OS << *T;
188 }
189 
191  : Key(std::string(Key)), Val(S.str()) {}
192 
194  : Key(std::string(Key)), Val(itostr(N)) {}
195 
197  : Key(std::string(Key)), Val(llvm::to_string(N)) {}
198 
200  : Key(std::string(Key)), Val(itostr(N)) {}
201 
203  : Key(std::string(Key)), Val(itostr(N)) {}
204 
206  : Key(std::string(Key)), Val(utostr(N)) {}
207 
209  unsigned long N)
210  : Key(std::string(Key)), Val(utostr(N)) {}
211 
213  unsigned long long N)
214  : Key(std::string(Key)), Val(utostr(N)) {}
215 
217  ElementCount EC)
218  : Key(std::string(Key)) {
220  EC.print(OS);
221 }
222 
224  : Key(std::string(Key)), Loc(Loc) {
225  if (Loc) {
226  Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
227  Twine(Loc.getCol())).str();
228  } else {
229  Val = "<UNKNOWN LOCATION>";
230  }
231 }
232 
234  DP << getLocationStr() << ": " << getMsg();
235  if (Hotness)
236  DP << " (hotness: " << *Hotness << ")";
237 }
238 
241  const DiagnosticLocation &Loc,
242  const Value *CodeRegion)
244  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
245  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
246 
249  const Instruction *Inst)
251  RemarkName, *Inst->getParent()->getParent(),
252  Inst->getDebugLoc(), Inst->getParent()) {}
253 
254 static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
255  return Func->empty() ? nullptr : &Func->front();
256 }
257 
260  const Function *Func)
262  RemarkName, *Func, Func->getSubprogram(),
263  getFirstFunctionBlock(Func)) {}
264 
266  const Function &Fn = getFunction();
267  LLVMContext &Ctx = Fn.getContext();
269 }
270 
272  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
273  const Value *CodeRegion)
275  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
276  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
277 
280  const Instruction *Inst)
282  PassName, RemarkName,
283  *Inst->getParent()->getParent(),
284  Inst->getDebugLoc(), Inst->getParent()) {}
285 
287  const Function &Fn = getFunction();
288  LLVMContext &Ctx = Fn.getContext();
290 }
291 
293  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
294  const Value *CodeRegion)
296  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
297  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
298 
301  const Instruction *Inst)
303  PassName, RemarkName,
304  *Inst->getParent()->getParent(),
305  Inst->getDebugLoc(), Inst->getParent()) {}
306 
308  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
309  const DiagnosticLocation &Loc, const Value *CodeRegion)
310  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
311  *cast<BasicBlock>(CodeRegion)->getParent(),
312  Loc, CodeRegion) {}
313 
315  const Function &Fn = getFunction();
316  LLVMContext &Ctx = Fn.getContext();
319 }
320 
322  DP << Diagnostic;
323 }
324 
326  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
327  const Value *CodeRegion)
329  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
330  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
331 
333  // Only print warnings.
334  return getSeverity() == DS_Warning;
335 }
336 
338  std::string Str;
339  raw_string_ostream OS(Str);
340 
341  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
342  << *getFunction().getFunctionType() << ": " << Msg << '\n';
343  OS.flush();
344  DP << Str;
345 }
346 
348  DP << "Instruction selection used fallback path for " << getFunction();
349 }
350 
352  Args.emplace_back(S);
353 }
354 
356  Args.push_back(std::move(A));
357 }
358 
360  IsVerbose = true;
361 }
362 
364  FirstExtraArgIndex = Args.size();
365 }
366 
368  std::string Str;
369  raw_string_ostream OS(Str);
371  make_range(Args.begin(), FirstExtraArgIndex == -1
372  ? Args.end()
373  : Args.begin() + FirstExtraArgIndex))
374  OS << Arg.Val;
375  return OS.str();
376 }
377 
378 void OptimizationRemarkAnalysisFPCommute::anchor() {}
379 void OptimizationRemarkAnalysisAliasing::anchor() {}
const char * PassName
Name of the pass that triggers this report.
DiagnosticKind
Defines the different supported kind of a diagnostic.
bool empty() const
Definition: Function.h:740
std::string getAbsolutePath() const
Return the absolute path tot the file.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:248
This class represents lattice values for constants.
Definition: AllocatorList.h:23
DiagnosticInfoInlineAsm(const Twine &MsgStr, DiagnosticSeverity Severity=DS_Error)
MsgStr is the message to be reported to the frontend.
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
DIFile * getFile() const
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
void print(DiagnosticPrinter &DP) const override
This file contains the declarations for metadata subclasses.
Used to set IsVerbose via the stream interface.
unsigned getLine() const
Definition: DebugLoc.cpp:25
A debug info location.
Definition: DebugLoc.h:33
Metadata node.
Definition: Metadata.h:870
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition: Casting.h:254
F(f)
int FirstExtraArgIndex
If positive, the index of the first argument that only appear in the optimization records and not in ...
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
Definition: Path.cpp:702
When an instance of this is inserted into the stream, the arguments following will not appear in the ...
const Twine & getMsgStr() const
DiagnosticLocation getLocation() const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:454
Definition: BitVector.h:941
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
static MemoryLocation getLocation(Instruction *I, AAResults *AA)
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:669
Interface for custom diagnostic printing.
Subprogram description.
Key
PAL metadata keys.
std::string itostr(int64_t X)
Definition: StringExtras.h:292
void print(DiagnosticPrinter &DP) const override
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:277
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
static Function * getFunction(Constant *C)
Definition: Evaluator.cpp:256
SmallVector< Argument, 4 > Args
Arguments collected via the streaming interface.
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
This is the base abstract class for diagnostic reporting in the backend.
const Function & getFunction() const
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
Instrumentation for Order File
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Common features for diagnostics dealing with optimization remarks that are used by IR passes...
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:296
Used in the streaming interface as the general argument type.
virtual bool isMissedOptRemarkEnabled(StringRef PassName) const
Return true if missed optimization remarks are enabled, override to provide different implementation...
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&... Args)
Definition: DIBuilder.cpp:792
OptimizationRemark(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
bool isEnabled() const override
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:4647
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:625
bool IsVerbose
The remark is expected to be noisy.
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isEnabled() const override
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, const Value *CodeRegion)
PassName is the name of the pass emitting this diagnostic.
virtual bool isPassedOptRemarkEnabled(StringRef PassName) const
Return true if passed optimization remarks are enabled, override to provide different implementation...
Module.h This file contains the declarations for the Module class.
StringRef getRelativePath() const
Return the file name relative to the compilation directory.
std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:277
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:165
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character &#39;\1&#39;, drop it.
Definition: GlobalValue.h:482
int getNextAvailablePluginDiagnosticKind()
Get the next available kind ID for a plugin diagnostic.
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
virtual bool isAnalysisRemarkEnabled(StringRef PassName) const
Return true if analysis remarks are enabled, override to provide different implementation.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
void print(DiagnosticPrinter &DP) const override
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:295
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
DiagnosticSeverity getSeverity() const
void print(DiagnosticPrinter &DP) const override
static const BasicBlock * getFirstFunctionBlock(const Function *Func)
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
unsigned getCol() const
Definition: DebugLoc.cpp:30
const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
const BasicBlock & front() const
Definition: Function.h:741
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:607
LLVM Value Representation.
Definition: Value.h:75
Optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
static const Function * getParent(const Value *V)
void print(DiagnosticPrinter &DP) const override
const std::string getLocationStr() const
Return a string with the location information for this diagnostic in the format "file:line:col".
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1556
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
std::string getAbsolutePath() const
Return the full path to the file.
void print(raw_ostream &OS) const
Printing function.
Definition: TypeSize.h:369
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
DiagnosticInfoOptimizationFailure(const Function &Fn, const DiagnosticLocation &Loc, const Twine &Msg)
Fn is the function where the diagnostic is being emitted.