LLVM  8.0.0svn
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 
108  if (!DL)
109  return;
110  File = DL->getFile();
111  Line = DL->getLine();
112  Column = DL->getColumn();
113 }
114 
116  if (!SP)
117  return;
118 
119  File = SP->getFile();
120  Line = SP->getScopeLine();
121  Column = 0;
122 }
123 
125  return File->getFilename();
126 }
127 
129  StringRef Name = File->getFilename();
130  if (sys::path::is_absolute(Name))
131  return Name;
132 
133  SmallString<128> Path;
134  sys::path::append(Path, File->getDirectory(), Name);
136 }
137 
139  return Loc.getAbsolutePath();
140 }
141 
143  unsigned &Line,
144  unsigned &Column) const {
145  RelativePath = Loc.getRelativePath();
146  Line = Loc.getLine();
147  Column = Loc.getColumn();
148 }
149 
151  StringRef Filename("<unknown>");
152  unsigned Line = 0;
153  unsigned Column = 0;
154  if (isLocationAvailable())
155  getLocation(Filename, Line, Column);
156  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
157 }
158 
160  : Key(Key) {
161  if (auto *F = dyn_cast<Function>(V)) {
162  if (DISubprogram *SP = F->getSubprogram())
163  Loc = SP;
164  }
165  else if (auto *I = dyn_cast<Instruction>(V))
166  Loc = I->getDebugLoc();
167 
168  // Only include names that correspond to user variables. FIXME: We should use
169  // debug info if available to get the name of the user variable.
170  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
172  else if (isa<Constant>(V)) {
174  V->printAsOperand(OS, /*PrintType=*/false);
175  } else if (auto *I = dyn_cast<Instruction>(V))
176  Val = I->getOpcodeName();
177 }
178 
180  : Key(Key) {
182  OS << *T;
183 }
184 
186  : Key(Key), Val(S.str()) {}
187 
189  : Key(Key), Val(itostr(N)) {}
190 
192  : Key(Key), Val(llvm::to_string(N)) {}
193 
195  : Key(Key), Val(itostr(N)) {}
196 
198  : Key(Key), Val(itostr(N)) {}
199 
201  : Key(Key), Val(utostr(N)) {}
202 
204  unsigned long N)
205  : Key(Key), Val(utostr(N)) {}
206 
208  unsigned long long N)
209  : Key(Key), Val(utostr(N)) {}
210 
212  : Key(Key), Loc(Loc) {
213  if (Loc) {
214  Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
215  Twine(Loc.getCol())).str();
216  } else {
217  Val = "<UNKNOWN LOCATION>";
218  }
219 }
220 
222  DP << getLocationStr() << ": " << getMsg();
223  if (Hotness)
224  DP << " (hotness: " << *Hotness << ")";
225 }
226 
229  const DiagnosticLocation &Loc,
230  const Value *CodeRegion)
232  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
233  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
234 
237  const Instruction *Inst)
239  RemarkName, *Inst->getParent()->getParent(),
240  Inst->getDebugLoc(), Inst->getParent()) {}
241 
242 // Helper to allow for an assert before attempting to return an invalid
243 // reference.
244 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
245  assert(!Func->empty() && "Function does not have a body");
246  return Func->front();
247 }
248 
251  const Function *Func)
253  RemarkName, *Func, Func->getSubprogram(),
254  &getFirstFunctionBlock(Func)) {}
255 
257  const Function &Fn = getFunction();
258  LLVMContext &Ctx = Fn.getContext();
260 }
261 
263  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
264  const Value *CodeRegion)
266  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
267  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
268 
271  const Instruction *Inst)
273  PassName, RemarkName,
274  *Inst->getParent()->getParent(),
275  Inst->getDebugLoc(), Inst->getParent()) {}
276 
278  const Function &Fn = getFunction();
279  LLVMContext &Ctx = Fn.getContext();
281 }
282 
284  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
285  const Value *CodeRegion)
287  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
288  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
289 
292  const Instruction *Inst)
294  PassName, RemarkName,
295  *Inst->getParent()->getParent(),
296  Inst->getDebugLoc(), Inst->getParent()) {}
297 
299  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
300  const DiagnosticLocation &Loc, const Value *CodeRegion)
301  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
302  *cast<BasicBlock>(CodeRegion)->getParent(),
303  Loc, CodeRegion) {}
304 
306  const Function &Fn = getFunction();
307  LLVMContext &Ctx = Fn.getContext();
310 }
311 
313  DP << Diagnostic;
314 }
315 
317  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
318  const Value *CodeRegion)
320  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
321  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
322 
324  // Only print warnings.
325  return getSeverity() == DS_Warning;
326 }
327 
329  std::string Str;
330  raw_string_ostream OS(Str);
331 
332  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
333  << *getFunction().getFunctionType() << ": " << Msg << '\n';
334  OS.flush();
335  DP << Str;
336 }
337 
339  DP << "Instruction selection used fallback path for " << getFunction();
340 }
341 
343  Args.emplace_back(S);
344 }
345 
347  Args.push_back(std::move(A));
348 }
349 
351  IsVerbose = true;
352 }
353 
355  FirstExtraArgIndex = Args.size();
356 }
357 
359  std::string Str;
360  raw_string_ostream OS(Str);
362  make_range(Args.begin(), FirstExtraArgIndex == -1
363  ? Args.end()
364  : Args.begin() + FirstExtraArgIndex))
365  OS << Arg.Val;
366  return OS.str();
367 }
368 
369 namespace llvm {
370 namespace yaml {
371 
372 void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
373  IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
374  assert(io.outputting() && "input not yet implemented");
375 
376  if (io.mapTag("!Passed",
377  (OptDiag->getKind() == DK_OptimizationRemark ||
378  OptDiag->getKind() == DK_MachineOptimizationRemark)))
379  ;
380  else if (io.mapTag(
381  "!Missed",
382  (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
384  ;
385  else if (io.mapTag(
386  "!Analysis",
387  (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
389  ;
390  else if (io.mapTag("!AnalysisFPCommute",
391  OptDiag->getKind() ==
393  ;
394  else if (io.mapTag("!AnalysisAliasing",
395  OptDiag->getKind() ==
397  ;
398  else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
399  ;
400  else
401  llvm_unreachable("Unknown remark type");
402 
403  // These are read-only for now.
404  DiagnosticLocation DL = OptDiag->getLocation();
405  StringRef FN =
407 
408  StringRef PassName(OptDiag->PassName);
409  io.mapRequired("Pass", PassName);
410  io.mapRequired("Name", OptDiag->RemarkName);
411  if (!io.outputting() || DL.isValid())
412  io.mapOptional("DebugLoc", DL);
413  io.mapRequired("Function", FN);
414  io.mapOptional("Hotness", OptDiag->Hotness);
415  io.mapOptional("Args", OptDiag->Args);
416 }
417 
418 template <> struct MappingTraits<DiagnosticLocation> {
419  static void mapping(IO &io, DiagnosticLocation &DL) {
420  assert(io.outputting() && "input not yet implemented");
421 
423  unsigned Line = DL.getLine();
424  unsigned Col = DL.getColumn();
425 
426  io.mapRequired("File", File);
427  io.mapRequired("Line", Line);
428  io.mapRequired("Column", Col);
429  }
430 
431  static const bool flow = true;
432 };
433 
434 // Implement this as a mapping for now to get proper quotation for the value.
437  assert(io.outputting() && "input not yet implemented");
438  io.mapRequired(A.Key.data(), A.Val);
439  if (A.Loc.isValid())
440  io.mapOptional("DebugLoc", A.Loc);
441  }
442 };
443 
444 } // end namespace yaml
445 } // end namespace llvm
446 
447 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:194
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:4222
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:215
#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.