OSDN Git Service

Sort the remaining #include lines in include/... and lib/....
[android-x86/external-llvm.git] / 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 "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/IR/BasicBlock.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DebugInfoMetadata.h"
22 #include "llvm/IR/DerivedTypes.h"
23 #include "llvm/IR/DiagnosticPrinter.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/GlobalValue.h"
26 #include "llvm/IR/Instruction.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/IR/Metadata.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/IR/Value.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/Regex.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <atomic>
38 #include <cassert>
39 #include <memory>
40 #include <string>
41
42 using namespace llvm;
43
44 namespace {
45
46 /// \brief Regular expression corresponding to the value given in one of the
47 /// -pass-remarks* command line flags. Passes whose name matches this regexp
48 /// will emit a diagnostic when calling the associated diagnostic function
49 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
50 /// emitOptimizationRemarkAnalysis).
51 struct PassRemarksOpt {
52   std::shared_ptr<Regex> Pattern;
53
54   void operator=(const std::string &Val) {
55     // Create a regexp object to match pass names for emitOptimizationRemark.
56     if (!Val.empty()) {
57       Pattern = std::make_shared<Regex>(Val);
58       std::string RegexError;
59       if (!Pattern->isValid(RegexError))
60         report_fatal_error("Invalid regular expression '" + Val +
61                                "' in -pass-remarks: " + RegexError,
62                            false);
63     }
64   }
65 };
66
67 } // end anonymous namespace
68
69 static PassRemarksOpt PassRemarksOptLoc;
70 static PassRemarksOpt PassRemarksMissedOptLoc;
71 static PassRemarksOpt PassRemarksAnalysisOptLoc;
72
73 // -pass-remarks
74 //    Command line flag to enable emitOptimizationRemark()
75 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
76 PassRemarks("pass-remarks", cl::value_desc("pattern"),
77             cl::desc("Enable optimization remarks from passes whose name match "
78                      "the given regular expression"),
79             cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
80             cl::ZeroOrMore);
81
82 // -pass-remarks-missed
83 //    Command line flag to enable emitOptimizationRemarkMissed()
84 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
85     "pass-remarks-missed", cl::value_desc("pattern"),
86     cl::desc("Enable missed optimization remarks from passes whose name match "
87              "the given regular expression"),
88     cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
89     cl::ZeroOrMore);
90
91 // -pass-remarks-analysis
92 //    Command line flag to enable emitOptimizationRemarkAnalysis()
93 static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
94 PassRemarksAnalysis(
95     "pass-remarks-analysis", cl::value_desc("pattern"),
96     cl::desc(
97         "Enable optimization analysis remarks from passes whose name match "
98         "the given regular expression"),
99     cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
100     cl::ZeroOrMore);
101
102 int llvm::getNextAvailablePluginDiagnosticKind() {
103   static std::atomic<int> PluginKindID(DK_FirstPluginKind);
104   return ++PluginKindID;
105 }
106
107 const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
108
109 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
110                                                  const Twine &MsgStr,
111                                                  DiagnosticSeverity Severity)
112     : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
113   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
114     if (SrcLoc->getNumOperands() != 0)
115       if (const auto *CI =
116               mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
117         LocCookie = CI->getZExtValue();
118   }
119 }
120
121 void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
122   DP << getMsgStr();
123   if (getLocCookie())
124     DP << " at line " << getLocCookie();
125 }
126
127 void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
128   DP << getResourceName() << " limit";
129
130   if (getResourceLimit() != 0)
131     DP << " of " << getResourceLimit();
132
133   DP << " exceeded (" <<  getResourceSize() << ") in " << getFunction();
134 }
135
136 void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
137   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
138      << ") in " << getModule();
139 }
140
141 void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
142     DiagnosticPrinter &DP) const {
143   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
144 }
145
146 void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
147   if (!FileName.empty()) {
148     DP << getFileName();
149     if (LineNum > 0)
150       DP << ":" << getLineNum();
151     DP << ": ";
152   }
153   DP << getMsg();
154 }
155
156 void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
157   if (getFileName())
158     DP << getFileName() << ": ";
159   DP << getMsg();
160 }
161
162 DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
163   if (!DL)
164     return;
165   Filename = DL->getFilename();
166   Line = DL->getLine();
167   Column = DL->getColumn();
168 }
169
170 DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
171   if (!SP)
172     return;
173   Filename = SP->getFilename();
174   Line = SP->getScopeLine();
175   Column = 0;
176 }
177
178 void DiagnosticInfoWithLocationBase::getLocation(StringRef *Filename,
179                                                  unsigned *Line,
180                                                  unsigned *Column) const {
181   *Filename = Loc.getFilename();
182   *Line = Loc.getLine();
183   *Column = Loc.getColumn();
184 }
185
186 const std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
187   StringRef Filename("<unknown>");
188   unsigned Line = 0;
189   unsigned Column = 0;
190   if (isLocationAvailable())
191     getLocation(&Filename, &Line, &Column);
192   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
193 }
194
195 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Value *V)
196     : Key(Key) {
197   if (auto *F = dyn_cast<Function>(V)) {
198     if (DISubprogram *SP = F->getSubprogram())
199       Loc = SP;
200   }
201   else if (auto *I = dyn_cast<Instruction>(V))
202     Loc = I->getDebugLoc();
203
204   // Only include names that correspond to user variables.  FIXME: we should use
205   // debug info if available to get the name of the user variable.
206   if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
207     Val = GlobalValue::dropLLVMManglingEscape(V->getName());
208   else if (isa<Constant>(V)) {
209     raw_string_ostream OS(Val);
210     V->printAsOperand(OS, /*PrintType=*/false);
211   } else if (auto *I = dyn_cast<Instruction>(V))
212     Val = I->getOpcodeName();
213 }
214
215 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
216     : Key(Key) {
217   raw_string_ostream OS(Val);
218   OS << *T;
219 }
220
221 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
222     : Key(Key), Val(itostr(N)) {}
223
224 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
225     : Key(Key), Val(utostr(N)) {}
226
227 void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
228   DP << getLocationStr() << ": " << getMsg();
229   if (Hotness)
230     DP << " (hotness: " << *Hotness << ")";
231 }
232
233 OptimizationRemark::OptimizationRemark(const char *PassName,
234                                        StringRef RemarkName,
235                                        const DiagnosticLocation &Loc,
236                                        const Value *CodeRegion)
237     : DiagnosticInfoIROptimization(
238           DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
239           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
240
241 OptimizationRemark::OptimizationRemark(const char *PassName,
242                                        StringRef RemarkName,
243                                        const Instruction *Inst)
244     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
245                                    RemarkName, *Inst->getParent()->getParent(),
246                                    Inst->getDebugLoc(), Inst->getParent()) {}
247
248 // Helper to allow for an assert before attempting to return an invalid
249 // reference.
250 static const BasicBlock &getFirstFunctionBlock(const Function *Func) {
251   assert(!Func->empty() && "Function does not have a body");
252   return Func->front();
253 }
254
255 OptimizationRemark::OptimizationRemark(const char *PassName,
256                                        StringRef RemarkName,
257                                        const Function *Func)
258     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
259                                    RemarkName, *Func, Func->getSubprogram(),
260                                    &getFirstFunctionBlock(Func)) {}
261
262 bool OptimizationRemark::isEnabled(StringRef PassName) {
263   return PassRemarksOptLoc.Pattern &&
264          PassRemarksOptLoc.Pattern->match(PassName);
265 }
266
267 OptimizationRemarkMissed::OptimizationRemarkMissed(
268     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
269     const Value *CodeRegion)
270     : DiagnosticInfoIROptimization(
271           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
272           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
273
274 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
275                                                    StringRef RemarkName,
276                                                    const Instruction *Inst)
277     : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
278                                    PassName, RemarkName,
279                                    *Inst->getParent()->getParent(),
280                                    Inst->getDebugLoc(), Inst->getParent()) {}
281
282 bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
283   return PassRemarksMissedOptLoc.Pattern &&
284          PassRemarksMissedOptLoc.Pattern->match(PassName);
285 }
286
287 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
288     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
289     const Value *CodeRegion)
290     : DiagnosticInfoIROptimization(
291           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
292           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
293
294 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
295                                                        StringRef RemarkName,
296                                                        const Instruction *Inst)
297     : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
298                                    PassName, RemarkName,
299                                    *Inst->getParent()->getParent(),
300                                    Inst->getDebugLoc(), Inst->getParent()) {}
301
302 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
303     enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
304     const DiagnosticLocation &Loc, const Value *CodeRegion)
305     : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
306                                    *cast<BasicBlock>(CodeRegion)->getParent(),
307                                    Loc, CodeRegion) {}
308
309 bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
310   return PassRemarksAnalysisOptLoc.Pattern &&
311          PassRemarksAnalysisOptLoc.Pattern->match(PassName);
312 }
313
314 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
315   DP << Diagnostic;
316 }
317
318 void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
319                                   const Function &Fn,
320                                   const DiagnosticLocation &Loc,
321                                   const Twine &Msg) {
322   Ctx.diagnose(OptimizationRemark(PassName, Fn, Loc, Msg));
323 }
324
325 void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
326                                         const Function &Fn,
327                                         const DiagnosticLocation &Loc,
328                                         const Twine &Msg) {
329   Ctx.diagnose(OptimizationRemarkMissed(PassName, Fn, Loc, Msg));
330 }
331
332 void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
333                                           const char *PassName,
334                                           const Function &Fn,
335                                           const DiagnosticLocation &Loc,
336                                           const Twine &Msg) {
337   Ctx.diagnose(OptimizationRemarkAnalysis(PassName, Fn, Loc, Msg));
338 }
339
340 void llvm::emitOptimizationRemarkAnalysisFPCommute(
341     LLVMContext &Ctx, const char *PassName, const Function &Fn,
342     const DiagnosticLocation &Loc, const Twine &Msg) {
343   Ctx.diagnose(OptimizationRemarkAnalysisFPCommute(PassName, Fn, Loc, Msg));
344 }
345
346 void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
347                                                   const char *PassName,
348                                                   const Function &Fn,
349                                                   const DiagnosticLocation &Loc,
350                                                   const Twine &Msg) {
351   Ctx.diagnose(OptimizationRemarkAnalysisAliasing(PassName, Fn, Loc, Msg));
352 }
353
354 DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
355     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
356     const Value *CodeRegion)
357     : DiagnosticInfoIROptimization(
358           DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
359           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
360
361 bool DiagnosticInfoOptimizationFailure::isEnabled() const {
362   // Only print warnings.
363   return getSeverity() == DS_Warning;
364 }
365
366 void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
367   std::string Str;
368   raw_string_ostream OS(Str);
369
370   OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
371      << *getFunction().getFunctionType() << ": " << Msg << '\n';
372   OS.flush();
373   DP << Str;
374 }
375
376 void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
377   DP << "Instruction selection used fallback path for " << getFunction();
378 }
379
380 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
381 operator<<(StringRef S) {
382   Args.emplace_back(S);
383   return *this;
384 }
385
386 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
387 operator<<(Argument A) {
388   Args.push_back(std::move(A));
389   return *this;
390 }
391
392 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
393 operator<<(setIsVerbose V) {
394   IsVerbose = true;
395   return *this;
396 }
397
398 DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase::
399 operator<<(setExtraArgs EA) {
400   FirstExtraArgIndex = Args.size();
401   return *this;
402 }
403
404 std::string DiagnosticInfoOptimizationBase::getMsg() const {
405   std::string Str;
406   raw_string_ostream OS(Str);
407   for (const DiagnosticInfoOptimizationBase::Argument &Arg :
408        make_range(Args.begin(), FirstExtraArgIndex == -1
409                                     ? Args.end()
410                                     : Args.begin() + FirstExtraArgIndex))
411     OS << Arg.Val;
412   return OS.str();
413 }