LLVM  4.0.0
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"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DebugInfo.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instruction.h"
24 #include "llvm/IR/Metadata.h"
25 #include "llvm/IR/Module.h"
27 #include "llvm/Support/Regex.h"
28 #include <atomic>
29 #include <string>
30 
31 using namespace llvm;
32 
33 namespace {
34 
35 /// \brief Regular expression corresponding to the value given in one of the
36 /// -pass-remarks* command line flags. Passes whose name matches this regexp
37 /// will emit a diagnostic when calling the associated diagnostic function
38 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
39 /// emitOptimizationRemarkAnalysis).
40 struct PassRemarksOpt {
41  std::shared_ptr<Regex> Pattern;
42 
43  void operator=(const std::string &Val) {
44  // Create a regexp object to match pass names for emitOptimizationRemark.
45  if (!Val.empty()) {
46  Pattern = std::make_shared<Regex>(Val);
47  std::string RegexError;
48  if (!Pattern->isValid(RegexError))
49  report_fatal_error("Invalid regular expression '" + Val +
50  "' in -pass-remarks: " + RegexError,
51  false);
52  }
53  }
54 };
55 
56 static PassRemarksOpt PassRemarksOptLoc;
57 static PassRemarksOpt PassRemarksMissedOptLoc;
58 static PassRemarksOpt PassRemarksAnalysisOptLoc;
59 
60 // -pass-remarks
61 // Command line flag to enable emitOptimizationRemark()
63 PassRemarks("pass-remarks", cl::value_desc("pattern"),
64  cl::desc("Enable optimization remarks from passes whose name match "
65  "the given regular expression"),
66  cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
68 
69 // -pass-remarks-missed
70 // Command line flag to enable emitOptimizationRemarkMissed()
72  "pass-remarks-missed", cl::value_desc("pattern"),
73  cl::desc("Enable missed optimization remarks from passes whose name match "
74  "the given regular expression"),
75  cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
77 
78 // -pass-remarks-analysis
79 // Command line flag to enable emitOptimizationRemarkAnalysis()
81 PassRemarksAnalysis(
82  "pass-remarks-analysis", cl::value_desc("pattern"),
83  cl::desc(
84  "Enable optimization analysis remarks from passes whose name match "
85  "the given regular expression"),
86  cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
88 }
89 
91  static std::atomic<int> PluginKindID(DK_FirstPluginKind);
92  return ++PluginKindID;
93 }
94 
96 
98  const Twine &MsgStr,
99  DiagnosticSeverity Severity)
100  : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
101  Instr(&I) {
102  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
103  if (SrcLoc->getNumOperands() != 0)
104  if (const auto *CI =
105  mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
106  LocCookie = CI->getZExtValue();
107  }
108 }
109 
111  DP << getMsgStr();
112  if (getLocCookie())
113  DP << " at line " << getLocCookie();
114 }
115 
117  DP << getResourceName() << " limit";
118 
119  if (getResourceLimit() != 0)
120  DP << " of " << getResourceLimit();
121 
122  DP << " exceeded (" << getResourceSize() << ") in " << getFunction();
123 }
124 
126  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
127  << ") in " << getModule();
128 }
129 
131  DiagnosticPrinter &DP) const {
132  DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
133 }
134 
136  if (!FileName.empty()) {
137  DP << getFileName();
138  if (LineNum > 0)
139  DP << ":" << getLineNum();
140  DP << ": ";
141  }
142  DP << getMsg();
143 }
144 
146  if (getFileName())
147  DP << getFileName() << ": ";
148  DP << getMsg();
149 }
150 
152  return getDebugLoc();
153 }
154 
156  unsigned *Line,
157  unsigned *Column) const {
158  DILocation *L = getDebugLoc();
159  assert(L != nullptr && "debug location is invalid");
160  *Filename = L->getFilename();
161  *Line = L->getLine();
162  *Column = L->getColumn();
163 }
164 
166  StringRef Filename("<unknown>");
167  unsigned Line = 0;
168  unsigned Column = 0;
169  if (isLocationAvailable())
170  getLocation(&Filename, &Line, &Column);
171  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
172 }
173 
175  : Key(Key) {
176  if (auto *F = dyn_cast<Function>(V)) {
177  if (DISubprogram *SP = F->getSubprogram())
178  DLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
179  }
180  else if (auto *I = dyn_cast<Instruction>(V))
181  DLoc = I->getDebugLoc();
182 
183  // Only include names that correspond to user variables. FIXME: we should use
184  // debug info if available to get the name of the user variable.
185  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
187  else if (isa<Constant>(V)) {
188  raw_string_ostream OS(Val);
189  V->printAsOperand(OS, /*PrintType=*/false);
190  } else if (auto *I = dyn_cast<Instruction>(V))
191  Val = I->getOpcodeName();
192 }
193 
195  : Key(Key) {
196  raw_string_ostream OS(Val);
197  OS << *T;
198 }
199 
201  : Key(Key), Val(itostr(N)) {}
202 
204  : Key(Key), Val(utostr(N)) {}
205 
207  DP << getLocationStr() << ": " << getMsg();
208  if (Hotness)
209  DP << " (hotness: " << *Hotness << ")";
210 }
211 
213  StringRef RemarkName,
214  const DebugLoc &DLoc, Value *CodeRegion)
216  DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
217  *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
218 
220  StringRef RemarkName, Instruction *Inst)
222  RemarkName,
223  *Inst->getParent()->getParent(),
224  Inst->getDebugLoc(), Inst->getParent()) {}
225 
227  return PassRemarksOptLoc.Pattern &&
228  PassRemarksOptLoc.Pattern->match(getPassName());
229 }
230 
232  StringRef RemarkName,
233  const DebugLoc &DLoc,
234  Value *CodeRegion)
236  DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
237  *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
238 
240  StringRef RemarkName,
241  Instruction *Inst)
243  PassName, RemarkName,
244  *Inst->getParent()->getParent(),
245  Inst->getDebugLoc(), Inst->getParent()) {}
246 
248  return PassRemarksMissedOptLoc.Pattern &&
249  PassRemarksMissedOptLoc.Pattern->match(getPassName());
250 }
251 
253  StringRef RemarkName,
254  const DebugLoc &DLoc,
255  Value *CodeRegion)
257  DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
258  *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
259 
261  StringRef RemarkName,
262  Instruction *Inst)
264  PassName, RemarkName,
265  *Inst->getParent()->getParent(),
266  Inst->getDebugLoc(), Inst->getParent()) {}
267 
269  const char *PassName,
270  StringRef RemarkName,
271  const DebugLoc &DLoc,
272  Value *CodeRegion)
273  : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
274  *cast<BasicBlock>(CodeRegion)->getParent(),
275  DLoc, CodeRegion) {}
276 
278  return shouldAlwaysPrint() ||
279  (PassRemarksAnalysisOptLoc.Pattern &&
280  PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
281 }
282 
284  DP << Diagnostic;
285 }
286 
287 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
288  const Function &Fn, const DebugLoc &DLoc,
289  const Twine &Msg) {
290  Ctx.diagnose(OptimizationRemark(PassName, Fn, DLoc, Msg));
291 }
292 
293 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
294  const Function &Fn,
295  const DebugLoc &DLoc,
296  const Twine &Msg) {
297  Ctx.diagnose(OptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
298 }
299 
301  const char *PassName,
302  const Function &Fn,
303  const DebugLoc &DLoc,
304  const Twine &Msg) {
305  Ctx.diagnose(OptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
306 }
307 
309  const char *PassName,
310  const Function &Fn,
311  const DebugLoc &DLoc,
312  const Twine &Msg) {
313  Ctx.diagnose(OptimizationRemarkAnalysisFPCommute(PassName, Fn, DLoc, Msg));
314 }
315 
317  const char *PassName,
318  const Function &Fn,
319  const DebugLoc &DLoc,
320  const Twine &Msg) {
321  Ctx.diagnose(OptimizationRemarkAnalysisAliasing(PassName, Fn, DLoc, Msg));
322 }
323 
325  // Only print warnings.
326  return getSeverity() == DS_Warning;
327 }
328 
330  std::string Str;
331  raw_string_ostream OS(Str);
332 
333  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
334  << *getFunction().getFunctionType() << ": " << Msg << '\n';
335  OS.flush();
336  DP << Str;
337 }
338 
340  const DebugLoc &DLoc, const Twine &Msg) {
342  Fn, DLoc, Twine("loop not vectorized: " + Msg)));
343 }
344 
346  const DebugLoc &DLoc, const Twine &Msg) {
348  Fn, DLoc, Twine("loop not interleaved: " + Msg)));
349 }
350 
352  DP << "Instruction selection used fallback path for " << getFunction();
353 }
354 
357  Args.emplace_back(S);
358  return *this;
359 }
360 
363  Args.push_back(std::move(A));
364  return *this;
365 }
366 
369  IsVerbose = true;
370  return *this;
371 }
372 
375  FirstExtraArgIndex = Args.size();
376  return *this;
377 }
378 
380  std::string Str;
381  raw_string_ostream OS(Str);
383  make_range(Args.begin(), FirstExtraArgIndex == -1
384  ? Args.end()
385  : Args.begin() + FirstExtraArgIndex))
386  OS << Arg.Val;
387  return OS.str();
388 }
MachineLoop * L
DiagnosticKind
Defines the different supported kind of a diagnostic.
Diagnostic information for missed-optimization remarks.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
const Function & getFunction() const
bool isLocationAvailable() const
Return true if location information is available for this diagnostic.
OptimizationRemarkMissed(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional< uint64_t > Hotness=None)
PassName is the name of the pass emitting this diagnostic.
DiagnosticInfoInlineAsm(const Twine &MsgStr, DiagnosticSeverity Severity=DS_Error)
MsgStr is the message to be reported to the frontend.
DiagnosticInfoOptimizationBase & operator<<(StringRef S)
void print(DiagnosticPrinter &DP) const override
This file contains the declarations for metadata subclasses.
Used to set IsVerbose via the stream interface.
A debug info location.
Definition: DebugLoc.h:34
Metadata node.
Definition: Metadata.h:830
const DebugLoc & getDebugLoc() const
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-applied message.
When an instance of this is inserted into the stream, the arguments following will not appear in the ...
const Function & getFunction() const
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization analysis remark message.
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:21
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Diagnostic information for optimization failures.
Diagnostic information for optimization analysis remarks.
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.
Interface for custom diagnostic printing.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:193
Subprogram description.
#define F(x, y, z)
Definition: MD5.cpp:51
void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-missed message.
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:3473
#define T
void print(DiagnosticPrinter &DP) const override
static std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:79
DiagnosticSeverity getSeverity() const
Diagnostic information for optimization analysis remarks related to pointer aliasing.
Debug location.
std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
Definition: Casting.h:221
This is the base abstract class for diagnostic reporting in the backend.
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
const Twine & getMsg() const
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Diagnostic information for applied optimization remarks.
const Twine & getMsg() const
const char * getFileName() const
Used in the streaming interface as the general argument type.
static std::string itostr(int64_t X)
Definition: StringExtras.h:95
bool isEnabled() const override
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:479
void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit a warning when loop vectorization is specified but fails.
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.
void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit a warning when loop interleaving is specified but fails.
bool isEnabled() const override
unsigned getLocCookie() const
Diagnostic information for optimization analysis remarks related to floating-point non-commutativity...
Common features for diagnostics dealing with optimization remarks.
Module.h This file contains the declarations for the Module class.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:175
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
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.
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
Definition: GlobalValue.h:444
const char * getResourceName() const
void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization analysis remark related to messages about floating-point non-commutativity.
void print(DiagnosticPrinter &DP) const override
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.cpp:230
const std::string getLocationStr() const
Return a string with the location information for this diagnostic in the format "file:line:col".
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void print(DiagnosticPrinter &DP) const override
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Twine & getMsgStr() const
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:463
LLVM Value Representation.
Definition: Value.h:71
const Function & getFunction() const
OptimizationRemarkAnalysis(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional< uint64_t > Hotness=None)
PassName is the name of the pass emitting this diagnostic.
void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization analysis remark related to messages about pointer aliasing.
static const Function * getParent(const Value *V)
void print(DiagnosticPrinter &DP) const override
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
OptimizationRemark(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional< uint64_t > Hotness=None)
PassName is the name of the pass emitting this diagnostic.
void print(DiagnosticPrinter &DP) const override
void print(DiagnosticPrinter &DP) const override
Print using the given DP a user-friendly message.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:411