LLVM  7.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"
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 
107  if (!DL)
108  return;
109  Filename = DL->getFilename();
110  Line = DL->getLine();
111  Column = DL->getColumn();
112 }
113 
115  if (!SP)
116  return;
117  Filename = SP->getFilename();
118  Line = SP->getScopeLine();
119  Column = 0;
120 }
121 
123  unsigned *Line,
124  unsigned *Column) const {
125  *Filename = Loc.getFilename();
126  *Line = Loc.getLine();
127  *Column = Loc.getColumn();
128 }
129 
131  StringRef Filename("<unknown>");
132  unsigned Line = 0;
133  unsigned Column = 0;
134  if (isLocationAvailable())
135  getLocation(&Filename, &Line, &Column);
136  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
137 }
138 
140  : Key(Key) {
141  if (auto *F = dyn_cast<Function>(V)) {
142  if (DISubprogram *SP = F->getSubprogram())
143  Loc = SP;
144  }
145  else if (auto *I = dyn_cast<Instruction>(V))
146  Loc = I->getDebugLoc();
147 
148  // Only include names that correspond to user variables. FIXME: We should use
149  // debug info if available to get the name of the user variable.
150  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
152  else if (isa<Constant>(V)) {
154  V->printAsOperand(OS, /*PrintType=*/false);
155  } else if (auto *I = dyn_cast<Instruction>(V))
156  Val = I->getOpcodeName();
157 }
158 
160  : Key(Key) {
162  OS << *T;
163 }
164 
166  : Key(Key), Val(S.str()) {}
167 
169  : Key(Key), Val(itostr(N)) {}
170 
172  : Key(Key), Val(llvm::to_string(N)) {}
173 
175  : Key(Key), Val(itostr(N)) {}
176 
178  : Key(Key), Val(itostr(N)) {}
179 
181  : Key(Key), Val(utostr(N)) {}
182 
184  unsigned long N)
185  : Key(Key), Val(utostr(N)) {}
186 
188  unsigned long long N)
189  : Key(Key), Val(utostr(N)) {}
190 
192  : Key(Key), Loc(Loc) {
193  if (Loc) {
194  Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
195  Twine(Loc.getCol())).str();
196  } else {
197  Val = "<UNKNOWN LOCATION>";
198  }
199 }
200 
202  DP << getLocationStr() << ": " << getMsg();
203  if (Hotness)
204  DP << " (hotness: " << *Hotness << ")";
205 }
206 
209  const DiagnosticLocation &Loc,
210  const Value *CodeRegion)
212  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
213  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
214 
217  const Instruction *Inst)
219  RemarkName, *Inst->getParent()->getParent(),
220  Inst->getDebugLoc(), Inst->getParent()) {}
221 
222 // Helper to allow for an assert before attempting to return an invalid
223 // reference.
224 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
225  assert(!Func->empty() && "Function does not have a body");
226  return Func->front();
227 }
228 
231  const Function *Func)
233  RemarkName, *Func, Func->getSubprogram(),
234  &getFirstFunctionBlock(Func)) {}
235 
237  const Function &Fn = getFunction();
238  LLVMContext &Ctx = Fn.getContext();
240 }
241 
243  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
244  const Value *CodeRegion)
246  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
247  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
248 
251  const Instruction *Inst)
253  PassName, RemarkName,
254  *Inst->getParent()->getParent(),
255  Inst->getDebugLoc(), Inst->getParent()) {}
256 
258  const Function &Fn = getFunction();
259  LLVMContext &Ctx = Fn.getContext();
261 }
262 
264  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
265  const Value *CodeRegion)
267  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
268  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
269 
272  const Instruction *Inst)
274  PassName, RemarkName,
275  *Inst->getParent()->getParent(),
276  Inst->getDebugLoc(), Inst->getParent()) {}
277 
279  enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
280  const DiagnosticLocation &Loc, const Value *CodeRegion)
281  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
282  *cast<BasicBlock>(CodeRegion)->getParent(),
283  Loc, CodeRegion) {}
284 
286  const Function &Fn = getFunction();
287  LLVMContext &Ctx = Fn.getContext();
290 }
291 
293  DP << Diagnostic;
294 }
295 
297  const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
298  const Value *CodeRegion)
300  DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
301  *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
302 
304  // Only print warnings.
305  return getSeverity() == DS_Warning;
306 }
307 
309  std::string Str;
310  raw_string_ostream OS(Str);
311 
312  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
313  << *getFunction().getFunctionType() << ": " << Msg << '\n';
314  OS.flush();
315  DP << Str;
316 }
317 
319  DP << "Instruction selection used fallback path for " << getFunction();
320 }
321 
323  Args.emplace_back(S);
324 }
325 
327  Args.push_back(std::move(A));
328 }
329 
331  IsVerbose = true;
332 }
333 
335  FirstExtraArgIndex = Args.size();
336 }
337 
339  std::string Str;
340  raw_string_ostream OS(Str);
342  make_range(Args.begin(), FirstExtraArgIndex == -1
343  ? Args.end()
344  : Args.begin() + FirstExtraArgIndex))
345  OS << Arg.Val;
346  return OS.str();
347 }
348 
349 namespace llvm {
350 namespace yaml {
351 
352 void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
353  IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
354  assert(io.outputting() && "input not yet implemented");
355 
356  if (io.mapTag("!Passed",
357  (OptDiag->getKind() == DK_OptimizationRemark ||
358  OptDiag->getKind() == DK_MachineOptimizationRemark)))
359  ;
360  else if (io.mapTag(
361  "!Missed",
362  (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
364  ;
365  else if (io.mapTag(
366  "!Analysis",
367  (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
369  ;
370  else if (io.mapTag("!AnalysisFPCommute",
371  OptDiag->getKind() ==
373  ;
374  else if (io.mapTag("!AnalysisAliasing",
375  OptDiag->getKind() ==
377  ;
378  else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
379  ;
380  else
381  llvm_unreachable("Unknown remark type");
382 
383  // These are read-only for now.
384  DiagnosticLocation DL = OptDiag->getLocation();
385  StringRef FN =
387 
388  StringRef PassName(OptDiag->PassName);
389  io.mapRequired("Pass", PassName);
390  io.mapRequired("Name", OptDiag->RemarkName);
391  if (!io.outputting() || DL.isValid())
392  io.mapOptional("DebugLoc", DL);
393  io.mapRequired("Function", FN);
394  io.mapOptional("Hotness", OptDiag->Hotness);
395  io.mapOptional("Args", OptDiag->Args);
396 }
397 
398 template <> struct MappingTraits<DiagnosticLocation> {
399  static void mapping(IO &io, DiagnosticLocation &DL) {
400  assert(io.outputting() && "input not yet implemented");
401 
402  StringRef File = DL.getFilename();
403  unsigned Line = DL.getLine();
404  unsigned Col = DL.getColumn();
405 
406  io.mapRequired("File", File);
407  io.mapRequired("Line", Line);
408  io.mapRequired("Column", Col);
409  }
410 
411  static const bool flow = true;
412 };
413 
414 // Implement this as a mapping for now to get proper quotation for the value.
417  assert(io.outputting() && "input not yet implemented");
418  io.mapRequired(A.Key.data(), A.Val);
419  if (A.Loc.isValid())
420  io.mapOptional("DebugLoc", A.Loc);
421  }
422 };
423 
424 } // end namespace yaml
425 } // end namespace llvm
426 
427 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:643
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:25
A debug info location.
Definition: DebugLoc.h:34
Metadata node.
Definition: Metadata.h:862
F(f)
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.
std::string itostr(int64_t X)
Definition: StringExtras.h:208
#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:195
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: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:713
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:3616
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:483
#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:193
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:471
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:224
#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:30
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:644
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:467
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.
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.