LLVM  8.0.1
DiagnosticInfo.cpp
Go to the documentation of this file.
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"
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/DerivedTypes.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"
36 #include "llvm/Support/Path.h"
37 #include "llvm/Support/Regex.h"
40 #include <atomic>
41 #include <cassert>
42 #include <memory>
43 #include <string>
44 
45 using namespace llvm;
46 
48  static std::atomic<int> PluginKindID(DK_FirstPluginKind);
49  return ++PluginKindID;
50 }
51 
53 
55  const Twine &MsgStr,
56  DiagnosticSeverity Severity)
57  : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
58  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
59  if (SrcLoc->getNumOperands() != 0)
60  if (const auto *CI =
61  mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
62  LocCookie = CI->getZExtValue();
63  }
64 }
65 
67  DP << getMsgStr();
68  if (getLocCookie())
69  DP << " at line " << getLocCookie();
70 }
71 
73  DP << getResourceName() << " limit";
74 
75  if (getResourceLimit() != 0)
76  DP << " of " << getResourceLimit();
77 
78  DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
79 }
80 
82  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
83  << ") in " << getModule();
84 }
85 
87  DiagnosticPrinter &DP) const {
88  DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
89 }
90 
92  if (!FileName.empty()) {
93  DP << getFileName();
94  if (LineNum > 0)
95  DP << ":" << getLineNum();
96  DP << ": ";
97  }
98  DP << getMsg();
99 }
100 
102  if (getFileName())
103  DP << getFileName() << ": ";
104  DP << getMsg();
105 }
106 
107 void DiagnosticInfo::anchor() {}
108 void DiagnosticInfoStackSize::anchor() {}
109 void DiagnosticInfoWithLocationBase::anchor() {}
110 void DiagnosticInfoIROptimization::anchor() {}
111 
113  if (!DL)
114  return;
115  File = DL->getFile();
116  Line = DL->getLine();
117  Column = DL->getColumn();
118 }
119 
121  if (!SP)
122  return;
123 
124  File = SP->getFile();
125  Line = SP->getScopeLine();
126  Column = 0;
127 }
128 
130  return File->getFilename();
131 }
132 
134  StringRef Name = File->getFilename();
135  if (sys::path::is_absolute(Name))
136  return Name;
137 
138  SmallString<128> Path;
139  sys::path::append(Path, File->getDirectory(), Name);
141 }
142 
144  return Loc.getAbsolutePath();
145 }
146 
148  unsigned &Line,
149  unsigned &Column) const {
150  RelativePath = Loc.getRelativePath();
151  Line = Loc.getLine();
152  Column = Loc.getColumn();
153 }
154 
156  StringRef Filename("<unknown>");
157  unsigned Line = 0;
158  unsigned Column = 0;
159  if (isLocationAvailable())
160  getLocation(Filename, Line, Column);
161  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
162 }
163 
165  : Key(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))
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(Key) {
187  OS << *T;
188 }
189 
191  : Key(Key), Val(S.str()) {}
192 
194  : Key(Key), Val(itostr(N)) {}
195 
197  : Key(Key), Val(llvm::to_string(N)) {}
198 
200  : Key(Key), Val(itostr(N)) {}
201 
203  : Key(Key), Val(itostr(N)) {}
204 
206  : Key(Key), Val(utostr(N)) {}
207 
209  unsigned long N)
210  : Key(Key), Val(utostr(N)) {}
211 
213  unsigned long long N)
214  : Key(Key), Val(utostr(N)) {}
215 
217  : Key(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 // Helper to allow for an assert before attempting to return an invalid
248 // reference.
249 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
250  assert(!Func->empty() && "Function does not have a body");
251  return Func->front();
252 }
253 
256  const Function *Func)
258  RemarkName, *Func, Func->getSubprogram(),
259  &getFirstFunctionBlock(Func)) {}
260 
262  const Function &Fn = getFunction();
263  LLVMContext &Ctx = Fn.getContext();
265 }
266 
268  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
269  const Value *CodeRegion)
271  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
272  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
273 
276  const Instruction *Inst)
278  PassName, RemarkName,
279  *Inst->getParent()->getParent(),
280  Inst->getDebugLoc(), Inst->getParent()) {}
281 
283  const Function &Fn = getFunction();
284  LLVMContext &Ctx = Fn.getContext();
286 }
287 
289  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
290  const Value *CodeRegion)
292  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
293  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
294 
297  const Instruction *Inst)
299  PassName, RemarkName,
300  *Inst->getParent()->getParent(),
301  Inst->getDebugLoc(), Inst->getParent()) {}
302 
304  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
305  const DiagnosticLocation &Loc, const Value *CodeRegion)
306  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
307  *cast<BasicBlock>(CodeRegion)->getParent(),
308  Loc, CodeRegion) {}
309 
311  const Function &Fn = getFunction();
312  LLVMContext &Ctx = Fn.getContext();
315 }
316 
318  DP << Diagnostic;
319 }
320 
322  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
323  const Value *CodeRegion)
325  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
326  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
327 
329  // Only print warnings.
330  return getSeverity() == DS_Warning;
331 }
332 
334  std::string Str;
335  raw_string_ostream OS(Str);
336 
337  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
338  << *getFunction().getFunctionType() << ": " << Msg << '\n';
339  OS.flush();
340  DP << Str;
341 }
342 
344  DP << "Instruction selection used fallback path for " << getFunction();
345 }
346 
348  Args.emplace_back(S);
349 }
350 
352  Args.push_back(std::move(A));
353 }
354 
356  IsVerbose = true;
357 }
358 
360  FirstExtraArgIndex = Args.size();
361 }
362 
364  std::string Str;
365  raw_string_ostream OS(Str);
367  make_range(Args.begin(), FirstExtraArgIndex == -1
368  ? Args.end()
369  : Args.begin() + FirstExtraArgIndex))
370  OS << Arg.Val;
371  return OS.str();
372 }
373 
374 void OptimizationRemarkAnalysisFPCommute::anchor() {}
375 void OptimizationRemarkAnalysisAliasing::anchor() {}
376 
377 namespace llvm {
378 namespace yaml {
379 
380 void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
381  IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
382  assert(io.outputting() && "input not yet implemented");
383 
384  if (io.mapTag("!Passed",
385  (OptDiag->getKind() == DK_OptimizationRemark ||
386  OptDiag->getKind() == DK_MachineOptimizationRemark)))
387  ;
388  else if (io.mapTag(
389  "!Missed",
390  (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
392  ;
393  else if (io.mapTag(
394  "!Analysis",
395  (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
397  ;
398  else if (io.mapTag("!AnalysisFPCommute",
399  OptDiag->getKind() ==
401  ;
402  else if (io.mapTag("!AnalysisAliasing",
403  OptDiag->getKind() ==
405  ;
406  else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
407  ;
408  else
409  llvm_unreachable("Unknown remark type");
410 
411  // These are read-only for now.
412  DiagnosticLocation DL = OptDiag->getLocation();
413  StringRef FN =
415 
416  StringRef PassName(OptDiag->PassName);
417  io.mapRequired("Pass", PassName);
418  io.mapRequired("Name", OptDiag->RemarkName);
419  if (!io.outputting() || DL.isValid())
420  io.mapOptional("DebugLoc", DL);
421  io.mapRequired("Function", FN);
422  io.mapOptional("Hotness", OptDiag->Hotness);
423  io.mapOptional("Args", OptDiag->Args);
424 }
425 
426 template <> struct MappingTraits<DiagnosticLocation> {
427  static void mapping(IO &io, DiagnosticLocation &DL) {
428  assert(io.outputting() && "input not yet implemented");
429 
431  unsigned Line = DL.getLine();
432  unsigned Col = DL.getColumn();
433 
434  io.mapRequired("File", File);
435  io.mapRequired("Line", Line);
436  io.mapRequired("Column", Col);
437  }
438 
439  static const bool flow = true;
440 };
441 
442 // Implement this as a mapping for now to get proper quotation for the value.
445  assert(io.outputting() && "input not yet implemented");
446  io.mapRequired(A.Key.data(), A.Val);
447  if (A.Loc.isValid())
448  io.mapOptional("DebugLoc", A.Loc);
449  }
450 };
451 
452 } // end namespace yaml
453 } // end namespace llvm
454 
455 LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument)
const char * PassName
Name of the pass that triggers this report.
static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A)
DiagnosticKind
Defines the different supported kind of a diagnostic.
bool empty() const
Definition: Function.h:662
std::string getAbsolutePath() const
Return the absolute path tot the file.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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
unsigned getLine() const
Definition: DebugLoc.cpp:26
A debug info location.
Definition: DebugLoc.h:34
Metadata node.
Definition: Metadata.h:864
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:703
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:480
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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:81
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:688
Interface for custom diagnostic printing.
Subprogram description.
Key
PAL metadata keys.
std::string itostr(int64_t X)
Definition: StringExtras.h:239
#define T
void print(DiagnosticPrinter &DP) const override
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:221
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
static Function * getFunction(Constant *C)
Definition: Evaluator.cpp:221
std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
Definition: Casting.h:240
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:69
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...
static const BasicBlock & getFirstFunctionBlock(const Function *Func)
void getLocation(StringRef &RelativePath, unsigned &Line, unsigned &Column) const
Return location information for this diagnostic in three parts: the relative source file path...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
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:746
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:4225
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:499
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void mapping(IO &io, DiagnosticLocation &DL)
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.
Common features for diagnostics dealing with optimization remarks that are used by both IR and MIR pa...
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:224
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:164
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:472
int getNextAvailablePluginDiagnosticKind()
Get the next available kind ID for a plugin diagnostic.
void print(DiagnosticPrinter &DP) const override
amdgpu Simplify well known AMD library false Value Value * Arg
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:214
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
DiagnosticSeverity getSeverity() const
void print(DiagnosticPrinter &DP) const override
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:62
unsigned getCol() const
Definition: DebugLoc.cpp:31
const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
static MemoryLocation getLocation(Instruction *I, AliasAnalysis *AA)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const BasicBlock & front() const
Definition: Function.h:663
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
LLVM Value Representation.
Definition: Value.h:73
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:49
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.
unsigned getColumn() const
DiagnosticInfoOptimizationFailure(const Function &Fn, const DiagnosticLocation &Loc, const Twine &Msg)
Fn is the function where the diagnostic is being emitted.