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  : Key(std::string(Key)), Loc(Loc) {
218  if (Loc) {
219  Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
220  Twine(Loc.getCol())).str();
221  } else {
222  Val = "<UNKNOWN LOCATION>";
223  }
224 }
225 
227  DP << getLocationStr() << ": " << getMsg();
228  if (Hotness)
229  DP << " (hotness: " << *Hotness << ")";
230 }
231 
234  const DiagnosticLocation &Loc,
235  const Value *CodeRegion)
237  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
238  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
239 
242  const Instruction *Inst)
244  RemarkName, *Inst->getParent()->getParent(),
245  Inst->getDebugLoc(), Inst->getParent()) {}
246 
247 static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
248  return Func->empty() ? nullptr : &Func->front();
249 }
250 
253  const Function *Func)
255  RemarkName, *Func, Func->getSubprogram(),
256  getFirstFunctionBlock(Func)) {}
257 
259  const Function &Fn = getFunction();
260  LLVMContext &Ctx = Fn.getContext();
262 }
263 
265  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
266  const Value *CodeRegion)
268  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
269  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
270 
273  const Instruction *Inst)
275  PassName, RemarkName,
276  *Inst->getParent()->getParent(),
277  Inst->getDebugLoc(), Inst->getParent()) {}
278 
280  const Function &Fn = getFunction();
281  LLVMContext &Ctx = Fn.getContext();
283 }
284 
286  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
287  const Value *CodeRegion)
289  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
290  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
291 
294  const Instruction *Inst)
296  PassName, RemarkName,
297  *Inst->getParent()->getParent(),
298  Inst->getDebugLoc(), Inst->getParent()) {}
299 
301  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
302  const DiagnosticLocation &Loc, const Value *CodeRegion)
303  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
304  *cast<BasicBlock>(CodeRegion)->getParent(),
305  Loc, CodeRegion) {}
306 
308  const Function &Fn = getFunction();
309  LLVMContext &Ctx = Fn.getContext();
312 }
313 
315  DP << Diagnostic;
316 }
317 
319  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
320  const Value *CodeRegion)
322  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
323  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
324 
326  // Only print warnings.
327  return getSeverity() == DS_Warning;
328 }
329 
331  std::string Str;
332  raw_string_ostream OS(Str);
333 
334  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
335  << *getFunction().getFunctionType() << ": " << Msg << '\n';
336  OS.flush();
337  DP << Str;
338 }
339 
341  DP << "Instruction selection used fallback path for " << getFunction();
342 }
343 
345  Args.emplace_back(S);
346 }
347 
349  Args.push_back(std::move(A));
350 }
351 
353  IsVerbose = true;
354 }
355 
357  FirstExtraArgIndex = Args.size();
358 }
359 
361  std::string Str;
362  raw_string_ostream OS(Str);
364  make_range(Args.begin(), FirstExtraArgIndex == -1
365  ? Args.end()
366  : Args.begin() + FirstExtraArgIndex))
367  OS << Arg.Val;
368  return OS.str();
369 }
370 
372  Twine &Msg)
374  *Inst->getParent()->getParent(),
375  Inst->getDebugLoc()),
376  Msg(Msg) {}
377 
379  DP << getLocationStr() << ": " << getMsg();
380 }
381 
382 void OptimizationRemarkAnalysisFPCommute::anchor() {}
383 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:711
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.
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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:690
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
const Twine & getMsg() const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:455
Definition: BitVector.h:959
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
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:675
Common features for diagnostics with an associated location.
Interface for custom diagnostic printing.
DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg)
Subprogram description.
Key
PAL metadata keys.
std::string itostr(int64_t X)
Definition: StringExtras.h:246
void print(DiagnosticPrinter &DP) const override
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:279
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
void print(DiagnosticPrinter &DP) const override
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:252
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:762
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:4537
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:539
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:231
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:270
#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.
static MemoryLocation getLocation(Instruction *I, AliasAnalysis *AA)
const BasicBlock & front() const
Definition: Function.h:712
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:521
LLVM Value Representation.
Definition: Value.h:74
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".
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.
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.