]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/IR/DiagnosticInfo.cpp
MFV r318942: 8166 zpool scrub thinks it repaired offline device
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / IR / DiagnosticInfo.cpp
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"
21 #include "llvm/IR/DiagnosticPrinter.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"
26 #include "llvm/Support/CommandLine.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()
62 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
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,
67             cl::ZeroOrMore);
68
69 // -pass-remarks-missed
70 //    Command line flag to enable emitOptimizationRemarkMissed()
71 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
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,
76     cl::ZeroOrMore);
77
78 // -pass-remarks-analysis
79 //    Command line flag to enable emitOptimizationRemarkAnalysis()
80 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
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,
87     cl::ZeroOrMore);
88 }
89
90 int llvm::getNextAvailablePluginDiagnosticKind() {
91   static std::atomic<int> PluginKindID(DK_FirstPluginKind);
92   return ++PluginKindID;
93 }
94
95 const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
96
97 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
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
110 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
111   DP << getMsgStr();
112   if (getLocCookie())
113     DP << " at line " << getLocCookie();
114 }
115
116 void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
117   DP << getResourceName() << " limit";
118
119   if (getResourceLimit() != 0)
120     DP << " of " << getResourceLimit();
121
122   DP << " exceeded (" <<  getResourceSize() << ") in " << getFunction();
123 }
124
125 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
126   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
127      << ") in " << getModule();
128 }
129
130 void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
131     DiagnosticPrinter &DP) const {
132   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
133 }
134
135 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
136   if (!FileName.empty()) {
137     DP << getFileName();
138     if (LineNum > 0)
139       DP << ":" << getLineNum();
140     DP << ": ";
141   }
142   DP << getMsg();
143 }
144
145 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
146   if (getFileName())
147     DP << getFileName() << ": ";
148   DP << getMsg();
149 }
150
151 bool DiagnosticInfoWithDebugLocBase::isLocationAvailable() const {
152   return getDebugLoc();
153 }
154
155 void DiagnosticInfoWithDebugLocBase::getLocation(StringRef *Filename,
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
165 const std::string DiagnosticInfoWithDebugLocBase::getLocationStr() const {
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
174 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Value *V)
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))
186     Val = GlobalValue::getRealLinkageName(V->getName());
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
194 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Type *T)
195     : Key(Key) {
196   raw_string_ostream OS(Val);
197   OS << *T;
198 }
199
200 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
201     : Key(Key), Val(itostr(N)) {}
202
203 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
204     : Key(Key), Val(utostr(N)) {}
205
206 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
207   DP << getLocationStr() << ": " << getMsg();
208   if (Hotness)
209     DP << " (hotness: " << *Hotness << ")";
210 }
211
212 OptimizationRemark::OptimizationRemark(const char *PassName,
213                                        StringRef RemarkName,
214                                        const DebugLoc &DLoc, Value *CodeRegion)
215     : DiagnosticInfoOptimizationBase(
216           DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
217           *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
218
219 OptimizationRemark::OptimizationRemark(const char *PassName,
220                                        StringRef RemarkName, Instruction *Inst)
221     : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, PassName,
222                                      RemarkName,
223                                      *Inst->getParent()->getParent(),
224                                      Inst->getDebugLoc(), Inst->getParent()) {}
225
226 bool OptimizationRemark::isEnabled() const {
227   return PassRemarksOptLoc.Pattern &&
228          PassRemarksOptLoc.Pattern->match(getPassName());
229 }
230
231 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
232                                                    StringRef RemarkName,
233                                                    const DebugLoc &DLoc,
234                                                    Value *CodeRegion)
235     : DiagnosticInfoOptimizationBase(
236           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
237           *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
238
239 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
240                                                    StringRef RemarkName,
241                                                    Instruction *Inst)
242     : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
243                                      PassName, RemarkName,
244                                      *Inst->getParent()->getParent(),
245                                      Inst->getDebugLoc(), Inst->getParent()) {}
246
247 bool OptimizationRemarkMissed::isEnabled() const {
248   return PassRemarksMissedOptLoc.Pattern &&
249          PassRemarksMissedOptLoc.Pattern->match(getPassName());
250 }
251
252 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
253                                                        StringRef RemarkName,
254                                                        const DebugLoc &DLoc,
255                                                        Value *CodeRegion)
256     : DiagnosticInfoOptimizationBase(
257           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
258           *cast<BasicBlock>(CodeRegion)->getParent(), DLoc, CodeRegion) {}
259
260 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
261                                                        StringRef RemarkName,
262                                                        Instruction *Inst)
263     : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
264                                      PassName, RemarkName,
265                                      *Inst->getParent()->getParent(),
266                                      Inst->getDebugLoc(), Inst->getParent()) {}
267
268 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(enum DiagnosticKind Kind,
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
277 bool OptimizationRemarkAnalysis::isEnabled() const {
278   return shouldAlwaysPrint() ||
279          (PassRemarksAnalysisOptLoc.Pattern &&
280           PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
281 }
282
283 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
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
300 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
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
308 void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
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
316 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
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
324 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
325   // Only print warnings.
326   return getSeverity() == DS_Warning;
327 }
328
329 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
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
339 void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
340                                     const DebugLoc &DLoc, const Twine &Msg) {
341   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
342       Fn, DLoc, Twine("loop not vectorized: " + Msg)));
343 }
344
345 void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
346                                      const DebugLoc &DLoc, const Twine &Msg) {
347   Ctx.diagnose(DiagnosticInfoOptimizationFailure(
348       Fn, DLoc, Twine("loop not interleaved: " + Msg)));
349 }
350
351 void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
352   DP << "Instruction selection used fallback path for " << getFunction();
353 }
354
355 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
356 operator<<(StringRef S) {
357   Args.emplace_back(S);
358   return *this;
359 }
360
361 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
362 operator<<(Argument A) {
363   Args.push_back(std::move(A));
364   return *this;
365 }
366
367 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
368 operator<<(setIsVerbose V) {
369   IsVerbose = true;
370   return *this;
371 }
372
373 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
374 operator<<(setExtraArgs EA) {
375   FirstExtraArgIndex = Args.size();
376   return *this;
377 }
378
379 std::string DiagnosticInfoOptimizationBase::getMsg() const {
380   std::string Str;
381   raw_string_ostream OS(Str);
382   for (const DiagnosticInfoOptimizationBase::Argument &Arg :
383        make_range(Args.begin(), FirstExtraArgIndex == -1
384                                     ? Args.end()
385                                     : Args.begin() + FirstExtraArgIndex))
386     OS << Arg.Val;
387   return OS.str();
388 }