LLVM  6.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/Regex.h"
38 #include <atomic>
39 #include <cassert>
40 #include <memory>
41 #include <string>
42 
43 using namespace llvm;
44 
46  static std::atomic<int> PluginKindID(DK_FirstPluginKind);
47  return ++PluginKindID;
48 }
49 
51 
53  const Twine &MsgStr,
54  DiagnosticSeverity Severity)
55  : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
56  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
57  if (SrcLoc->getNumOperands() != 0)
58  if (const auto *CI =
59  mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
60  LocCookie = CI->getZExtValue();
61  }
62 }
63 
65  DP << getMsgStr();
66  if (getLocCookie())
67  DP << " at line " << getLocCookie();
68 }
69 
71  DP << getResourceName() << " limit";
72 
73  if (getResourceLimit() != 0)
74  DP << " of " << getResourceLimit();
75 
76  DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
77 }
78 
80  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
81  << ") in " << getModule();
82 }
83 
85  DiagnosticPrinter &DP) const {
86  DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
87 }
88 
90  if (!FileName.empty()) {
91  DP << getFileName();
92  if (LineNum > 0)
93  DP << ":" << getLineNum();
94  DP << ": ";
95  }
96  DP << getMsg();
97 }
98 
100  if (getFileName())
101  DP << getFileName() << ": ";
102  DP << getMsg();
103 }
104 
106  if (!DL)
107  return;
108  Filename = DL->getFilename();
109  Line = DL->getLine();
110  Column = DL->getColumn();
111 }
112 
114  if (!SP)
115  return;
116  Filename = SP->getFilename();
117  Line = SP->getScopeLine();
118  Column = 0;
119 }
120 
122  unsigned *Line,
123  unsigned *Column) const {
124  *Filename = Loc.getFilename();
125  *Line = Loc.getLine();
126  *Column = Loc.getColumn();
127 }
128 
130  StringRef Filename("<unknown>");
131  unsigned Line = 0;
132  unsigned Column = 0;
133  if (isLocationAvailable())
134  getLocation(&Filename, &Line, &Column);
135  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
136 }
137 
139  : Key(Key) {
140  if (auto *F = dyn_cast<Function>(V)) {
141  if (DISubprogram *SP = F->getSubprogram())
142  Loc = SP;
143  }
144  else if (auto *I = dyn_cast<Instruction>(V))
145  Loc = I->getDebugLoc();
146 
147  // Only include names that correspond to user variables. FIXME: we should use
148  // debug info if available to get the name of the user variable.
149  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
151  else if (isa<Constant>(V)) {
153  V->printAsOperand(OS, /*PrintType=*/false);
154  } else if (auto *I = dyn_cast<Instruction>(V))
155  Val = I->getOpcodeName();
156 }
157 
159  : Key(Key) {
161  OS << *T;
162 }
163 
165  : Key(Key), Val(S.str()) {}
166 
168  : Key(Key), Val(itostr(N)) {}
169 
171  : Key(Key), Val(itostr(N)) {}
172 
174  : Key(Key), Val(itostr(N)) {}
175 
177  : Key(Key), Val(utostr(N)) {}
178 
180  unsigned long N)
181  : Key(Key), Val(utostr(N)) {}
182 
184  unsigned long long N)
185  : Key(Key), Val(utostr(N)) {}
186 
188  : Key(Key), Loc(Loc) {
189  if (Loc) {
190  Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
191  Twine(Loc.getCol())).str();
192  } else {
193  Val = "<UNKNOWN LOCATION>";
194  }
195 }
196 
198  DP << getLocationStr() << ": " << getMsg();
199  if (Hotness)
200  DP << " (hotness: " << *Hotness << ")";
201 }
202 
205  const DiagnosticLocation &Loc,
206  const Value *CodeRegion)
208  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
209  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
210 
213  const Instruction *Inst)
215  RemarkName, *Inst->getParent()->getParent(),
216  Inst->getDebugLoc(), Inst->getParent()) {}
217 
218 // Helper to allow for an assert before attempting to return an invalid
219 // reference.
220 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
221  assert(!Func->empty() && "Function does not have a body");
222  return Func->front();
223 }
224 
227  const Function *Func)
229  RemarkName, *Func, Func->getSubprogram(),
230  &getFirstFunctionBlock(Func)) {}
231 
233  const Function &Fn = getFunction();
234  LLVMContext &Ctx = Fn.getContext();
236 }
237 
239  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
240  const Value *CodeRegion)
242  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
243  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
244 
247  const Instruction *Inst)
249  PassName, RemarkName,
250  *Inst->getParent()->getParent(),
251  Inst->getDebugLoc(), Inst->getParent()) {}
252 
254  const Function &Fn = getFunction();
255  LLVMContext &Ctx = Fn.getContext();
257 }
258 
260  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
261  const Value *CodeRegion)
263  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
264  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
265 
268  const Instruction *Inst)
270  PassName, RemarkName,
271  *Inst->getParent()->getParent(),
272  Inst->getDebugLoc(), Inst->getParent()) {}
273 
275  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
276  const DiagnosticLocation &Loc, const Value *CodeRegion)
277  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
278  *cast<BasicBlock>(CodeRegion)->getParent(),
279  Loc, CodeRegion) {}
280 
282  const Function &Fn = getFunction();
283  LLVMContext &Ctx = Fn.getContext();
286 }
287 
289  DP << Diagnostic;
290 }
291 
293  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
294  const Value *CodeRegion)
296  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
297  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
298 
300  // Only print warnings.
301  return getSeverity() == DS_Warning;
302 }
303 
305  std::string Str;
306  raw_string_ostream OS(Str);
307 
308  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
309  << *getFunction().getFunctionType() << ": " << Msg << '\n';
310  OS.flush();
311  DP << Str;
312 }
313 
315  DP << "Instruction selection used fallback path for " << getFunction();
316 }
317 
319  Args.emplace_back(S);
320 }
321 
323  Args.push_back(std::move(A));
324 }
325 
327  IsVerbose = true;
328 }
329 
331  FirstExtraArgIndex = Args.size();
332 }
333 
335  std::string Str;
336  raw_string_ostream OS(Str);
338  make_range(Args.begin(), FirstExtraArgIndex == -1
339  ? Args.end()
340  : Args.begin() + FirstExtraArgIndex))
341  OS << Arg.Val;
342  return OS.str();
343 }
344 
345 namespace llvm {
346 namespace yaml {
347 
348 void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
349  IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
350  assert(io.outputting() && "input not yet implemented");
351 
352  if (io.mapTag("!Passed",
353  (OptDiag->getKind() == DK_OptimizationRemark ||
354  OptDiag->getKind() == DK_MachineOptimizationRemark)))
355  ;
356  else if (io.mapTag(
357  "!Missed",
358  (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
360  ;
361  else if (io.mapTag(
362  "!Analysis",
363  (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
365  ;
366  else if (io.mapTag("!AnalysisFPCommute",
367  OptDiag->getKind() ==
369  ;
370  else if (io.mapTag("!AnalysisAliasing",
371  OptDiag->getKind() ==
373  ;
374  else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
375  ;
376  else
377  llvm_unreachable("Unknown remark type");
378 
379  // These are read-only for now.
380  DiagnosticLocation DL = OptDiag->getLocation();
381  StringRef FN =
383 
384  StringRef PassName(OptDiag->PassName);
385  io.mapRequired("Pass", PassName);
386  io.mapRequired("Name", OptDiag->RemarkName);
387  if (!io.outputting() || DL.isValid())
388  io.mapOptional("DebugLoc", DL);
389  io.mapRequired("Function", FN);
390  io.mapOptional("Hotness", OptDiag->Hotness);
391  io.mapOptional("Args", OptDiag->Args);
392 }
393 
394 template <> struct MappingTraits<DiagnosticLocation> {
395  static void mapping(IO &io, DiagnosticLocation &DL) {
396  assert(io.outputting() && "input not yet implemented");
397 
398  StringRef File = DL.getFilename();
399  unsigned Line = DL.getLine();
400  unsigned Col = DL.getColumn();
401 
402  io.mapRequired("File", File);
403  io.mapRequired("Line", Line);
404  io.mapRequired("Column", Col);
405  }
406 
407  static const bool flow = true;
408 };
409 
410 // Implement this as a mapping for now to get proper quotation for the value.
413  assert(io.outputting() && "input not yet implemented");
414  io.mapRequired(A.Key.data(), A.Val);
415  if (A.Loc.isValid())
416  io.mapOptional("DebugLoc", A.Loc);
417  }
418 };
419 
420 } // end namespace yaml
421 } // end namespace llvm
422 
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:594
void mapOptional(const char *Key, T &Val)
Definition: YAMLTraits.h:656
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
Compute iterated dominance frontiers using a linear time algorithm.
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.
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
void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const
Return location information for this diagnostic in three parts: the source file name, line number and column.
unsigned getLine() const
Definition: DebugLoc.cpp:26
A debug info location.
Definition: DebugLoc.h:34
Metadata node.
Definition: Metadata.h:862
F(f)
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence...
Definition: YAMLTraits.h:1643
int FirstExtraArgIndex
If positive, the index of the first argument that only appear in the optimization records and not in ...
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
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
Interface for custom diagnostic printing.
StringRef getFilename() const
Subprogram description.
Key
PAL metadata keys.
This class should be specialized by any type that needs to be converted to/from a YAML mapping...
std::string itostr(int64_t X)
Definition: StringExtras.h:189
#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:194
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
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:59
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)
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:680
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:3573
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:478
#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.
std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:174
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:145
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:462
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.
void print(DiagnosticPrinter &DP) const override
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:220
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
DiagnosticSeverity getSeverity() const
void print(DiagnosticPrinter &DP) const override
virtual bool outputting()=0
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:595
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:462
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 mapRequired(const char *Key, T &Val)
Definition: YAMLTraits.h:646
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
unsigned getColumn() const
StringRef getFilename() const
DiagnosticInfoOptimizationFailure(const Function &Fn, const DiagnosticLocation &Loc, const Twine &Msg)
Fn is the function where the diagnostic is being emitted.