llvm.org GIT mirror llvm / 4abccff
This reverts r313381 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313387 91177308-0d34-0410-b5e6-96231b3b80d8 Vivek Pandya 2 years ago
23 changed file(s) with 253 addition(s) and 422 deletion(s). Raw diff Collapse all Expand all
7777 /// use the extra analysis (1) to filter trivial false positives or (2) to
7878 /// provide more context so that non-trivial false positives can be quickly
7979 /// detected by the user.
80 bool allowExtraAnalysis(StringRef PassName) const {
81 return (F->getContext().getDiagnosticsOutputFile() ||
82 F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
80 bool allowExtraAnalysis() const {
81 // For now, only allow this with -fsave-optimization-record since the -Rpass
82 // options are handled in the front-end.
83 return F->getContext().getDiagnosticsOutputFile();
8384 }
8485
8586 private:
7272
7373 /// \see DiagnosticInfoOptimizationBase::isEnabled.
7474 bool isEnabled() const override {
75 const Function &Fn = getFunction();
76 LLVMContext &Ctx = Fn.getContext();
77 return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
75 return OptimizationRemark::isEnabled(getPassName());
7876 }
7977 };
8078
9896
9997 /// \see DiagnosticInfoOptimizationBase::isEnabled.
10098 bool isEnabled() const override {
101 const Function &Fn = getFunction();
102 LLVMContext &Ctx = Fn.getContext();
103 return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
99 return OptimizationRemarkMissed::isEnabled(getPassName());
104100 }
105101 };
106102
124120
125121 /// \see DiagnosticInfoOptimizationBase::isEnabled.
126122 bool isEnabled() const override {
127 const Function &Fn = getFunction();
128 LLVMContext &Ctx = Fn.getContext();
129 return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
123 return OptimizationRemarkAnalysis::isEnabled(getPassName());
130124 }
131125 };
132126
157151 /// that are normally too noisy. In this mode, we can use the extra analysis
158152 /// (1) to filter trivial false positives or (2) to provide more context so
159153 /// that non-trivial false positives can be quickly detected by the user.
160 bool allowExtraAnalysis(StringRef PassName) const {
161 return (MF.getFunction()->getContext().getDiagnosticsOutputFile() ||
162 MF.getFunction()->getContext()
163 .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
154 bool allowExtraAnalysis() const {
155 // For now, only allow this with -fsave-optimization-record since the -Rpass
156 // options are handled in the front-end.
157 return MF.getFunction()->getContext().getDiagnosticsOutputFile();
164158 }
165159
166160 private:
+0
-67
include/llvm/IR/DiagnosticHandler.h less more
None //===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -*- C++ ---*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Base DiagnosticHandler class declaration. Derive from this class to provide
9 // custom diagnostic reporting.
10 //===----------------------------------------------------------------------===//
11
12 #include "llvm/ADT/StringRef.h"
13
14 namespace llvm {
15 class DiagnosticInfo;
16
17 /// \brief This is the base class for diagnostic handling in LLVM.
18 /// The handleDiagnostics method must be overriden by the subclasses to handle
19 /// diagnostic. The *RemarkEnabled methods can be overriden to control
20 /// which remarks are enabled.
21 struct DiagnosticHandler {
22 void *DiagnosticContext = nullptr;
23 DiagnosticHandler(void *DiagContext = nullptr)
24 : DiagnosticContext(DiagContext) {}
25 virtual ~DiagnosticHandler() = default;
26
27 using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
28
29 /// DiagHandlerCallback is settable from the C API and base implementation
30 /// of DiagnosticHandler will call it from handleDiagnostics(). Any derived
31 /// class of DiagnosticHandler should not use callback but
32 /// implement handleDiagnostics().
33 DiagnosticHandlerTy DiagHandlerCallback = nullptr;
34
35 /// Override handleDiagnostics to provide custom implementation.
36 /// Return true if it handles diagnostics reporting properly otherwise
37 /// return false to make LLVMContext::diagnose() to print the message
38 /// with a prefix based on the severity.
39 virtual bool handleDiagnostics(const DiagnosticInfo &DI) {
40 if (DiagHandlerCallback) {
41 DiagHandlerCallback(DI, DiagnosticContext);
42 return true;
43 }
44 return false;
45 }
46
47 /// Return true if analysis remarks are enabled, override
48 /// to provide different implementation.
49 virtual bool isAnalysisRemarkEnabled(StringRef PassName) const;
50
51 /// Return true if missed optimization remarks are enabled, override
52 /// to provide different implementation.
53 virtual bool isMissedOptRemarkEnabled(StringRef PassName) const;
54
55 /// Return true if passed optimization remarks are enabled, override
56 /// to provide different implementation.
57 virtual bool isPassedOptRemarkEnabled(StringRef PassName) const;
58
59 /// Return true if any type of remarks are enabled.
60 bool isAnyRemarkEnabled(StringRef PassName) const {
61 return (isMissedOptRemarkEnabled(PassName) ||
62 isPassedOptRemarkEnabled(PassName) ||
63 isAnalysisRemarkEnabled(PassName));
64 }
65 };
66 }
603603 return DI->getKind() == DK_OptimizationRemark;
604604 }
605605
606 static bool isEnabled(StringRef PassName);
607
606608 /// \see DiagnosticInfoOptimizationBase::isEnabled.
607 bool isEnabled() const override;
609 bool isEnabled() const override { return isEnabled(getPassName()); }
608610
609611 private:
610612 /// This is deprecated now and only used by the function API below.
644646 return DI->getKind() == DK_OptimizationRemarkMissed;
645647 }
646648
649 static bool isEnabled(StringRef PassName);
650
647651 /// \see DiagnosticInfoOptimizationBase::isEnabled.
648 bool isEnabled() const override;
652 bool isEnabled() const override { return isEnabled(getPassName()); }
649653
650654 private:
651655 /// This is deprecated now and only used by the function API below.
696700 return DI->getKind() == DK_OptimizationRemarkAnalysis;
697701 }
698702
703 static bool isEnabled(StringRef PassName);
704
699705 /// \see DiagnosticInfoOptimizationBase::isEnabled.
700 bool isEnabled() const override;
706 bool isEnabled() const override {
707 return shouldAlwaysPrint() || isEnabled(getPassName());
708 }
701709
702710 static const char *AlwaysPrint;
703711
1515 #define LLVM_IR_LLVMCONTEXT_H
1616
1717 #include "llvm-c/Types.h"
18 #include "llvm/IR/DiagnosticHandler.h"
1918 #include "llvm/Support/CBindingWrapping.h"
2019 #include "llvm/Support/Options.h"
2120 #include
167166 using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context,
168167 unsigned LocCookie);
169168
169 /// Defines the type of a diagnostic handler.
170 /// \see LLVMContext::setDiagnosticHandler.
171 /// \see LLVMContext::diagnose.
172 using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
173
170174 /// Defines the type of a yield callback.
171175 /// \see LLVMContext::setYieldCallback.
172176 using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
189193 /// setInlineAsmDiagnosticHandler.
190194 void *getInlineAsmDiagnosticContext() const;
191195
192 /// setDiagnosticHandlerCallBack - This method sets a handler call back
193 /// that is invoked when the backend needs to report anything to the user.
194 /// The first argument is a function pointer and the second is a context pointer
195 /// that gets passed into the DiagHandler. The third argument should be set to
196 /// setDiagnosticHandler - This method sets a handler that is invoked
197 /// when the backend needs to report anything to the user. The first
198 /// argument is a function pointer and the second is a context pointer that
199 /// gets passed into the DiagHandler. The third argument should be set to
196200 /// true if the handler only expects enabled diagnostics.
197201 ///
198202 /// LLVMContext doesn't take ownership or interpret either of these
199203 /// pointers.
200 void setDiagnosticHandlerCallBack(
201 DiagnosticHandler::DiagnosticHandlerTy DiagHandler,
202 void *DiagContext = nullptr, bool RespectFilters = false);
203
204 /// setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler
205 /// to provide custom diagnostic handling. The first argument is unique_ptr of object
206 /// of type DiagnosticHandler or a derived of that. The third argument should be
207 /// set to true if the handler only expects enabled diagnostics.
208 ///
209 /// Ownership of this pointer is moved to LLVMContextImpl.
210 void setDiagnosticHandler(std::unique_ptr &&DH,
204 void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,
205 void *DiagContext = nullptr,
211206 bool RespectFilters = false);
212207
213 /// getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by
214 /// setDiagnosticHandlerCallBack.
215 DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const;
208 /// getDiagnosticHandler - Return the diagnostic handler set by
209 /// setDiagnosticHandler.
210 DiagnosticHandlerTy getDiagnosticHandler() const;
216211
217212 /// getDiagnosticContext - Return the diagnostic context set by
218213 /// setDiagnosticContext.
219214 void *getDiagnosticContext() const;
220
221 /// getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by
222 /// setDiagnosticHandler.
223 const DiagnosticHandler *getDiagHandlerPtr() const;
224
225 /// getDiagnosticHandler - transfers owenership of DiagnosticHandler unique_ptr
226 /// to caller.
227 std::unique_ptr getDiagnosticHandler();
228215
229216 /// \brief Return if a code hotness metric should be included in optimization
230217 /// diagnostics.
170170 bool UseInputModulePath = false);
171171 };
172172
173 struct LTOLLVMDiagnosticHandler : public DiagnosticHandler {
174 DiagnosticHandlerFunction *Fn;
175 LTOLLVMDiagnosticHandler(DiagnosticHandlerFunction *DiagHandlerFn)
176 : Fn(DiagHandlerFn) {}
177 bool handleDiagnostics(const DiagnosticInfo &DI) override {
178 (*Fn)(DI);
179 return true;
180 }
181 };
182173 /// A derived class of LLVMContext that initializes itself according to a given
183174 /// Config object. The purpose of this class is to tie ownership of the
184175 /// diagnostic handler to the context, as opposed to the Config object (which
185176 /// may be ephemeral).
186 // FIXME: This should not be required as diagnostic handler is not callback.
187177 struct LTOLLVMContext : LLVMContext {
178 static void funcDiagHandler(const DiagnosticInfo &DI, void *Context) {
179 auto *Fn = static_cast(Context);
180 (*Fn)(DI);
181 }
188182
189183 LTOLLVMContext(const Config &C) : DiagHandler(C.DiagHandler) {
190184 setDiscardValueNames(C.ShouldDiscardValueNames);
191185 enableDebugTypeODRUniquing();
192 setDiagnosticHandler(
193 llvm::make_unique(&DiagHandler), true);
186 setDiagnosticHandler(funcDiagHandler, &DiagHandler, true);
194187 }
195188 DiagnosticHandlerFunction DiagHandler;
196189 };
183183 LLVMContext &getContext() { return Context; }
184184
185185 void resetMergedModule() { MergedModule.reset(); }
186 void DiagnosticHandler(const DiagnosticInfo &DI);
187186
188187 private:
189188 void initializeLTOPasses();
203202
204203 bool determineTarget();
205204 std::unique_ptr createTargetMachine();
205
206 static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);
207
208 void DiagnosticHandler2(const DiagnosticInfo &DI);
206209
207210 void emitError(const std::string &ErrMsg);
208211 void emitWarning(const std::string &ErrMsg);
1616 DebugInfo.cpp
1717 DebugInfoMetadata.cpp
1818 DebugLoc.cpp
19 DiagnosticHandler.cpp
2019 DiagnosticInfo.cpp
2120 DiagnosticPrinter.cpp
2221 Dominators.cpp
8484 void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
8585 LLVMDiagnosticHandler Handler,
8686 void *DiagnosticContext) {
87 unwrap(C)->setDiagnosticHandlerCallBack(
88 LLVM_EXTENSION reinterpret_cast(
87 unwrap(C)->setDiagnosticHandler(
88 LLVM_EXTENSION reinterpret_cast(
8989 Handler),
9090 DiagnosticContext);
9191 }
9292
9393 LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C) {
9494 return LLVM_EXTENSION reinterpret_cast(
95 unwrap(C)->getDiagnosticHandlerCallBack());
95 unwrap(C)->getDiagnosticHandler());
9696 }
9797
9898 void *LLVMContextGetDiagnosticContext(LLVMContextRef C) {
+0
-86
lib/IR/DiagnosticHandler.cpp less more
None //===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11 #include "llvm/IR/DiagnosticHandler.h"
12 #include "llvm/Support/CommandLine.h"
13 #include "llvm/Support/RegEx.h"
14
15 using namespace llvm;
16
17 namespace {
18
19 /// \brief Regular expression corresponding to the value given in one of the
20 /// -pass-remarks* command line flags. Passes whose name matches this regexp
21 /// will emit a diagnostic when calling the associated diagnostic function
22 /// (emitOptimizationRemark, emitOptimizationRemarkMissed or
23 /// emitOptimizationRemarkAnalysis).
24 struct PassRemarksOpt {
25 std::shared_ptr Pattern;
26
27 void operator=(const std::string &Val) {
28 // Create a regexp object to match pass names for emitOptimizationRemark.
29 if (!Val.empty()) {
30 Pattern = std::make_shared(Val);
31 std::string RegexError;
32 if (!Pattern->isValid(RegexError))
33 report_fatal_error("Invalid regular expression '" + Val +
34 "' in -pass-remarks: " + RegexError,
35 false);
36 }
37 }
38 };
39
40 static PassRemarksOpt PassRemarksPassedOptLoc;
41 static PassRemarksOpt PassRemarksMissedOptLoc;
42 static PassRemarksOpt PassRemarksAnalysisOptLoc;
43
44 // -pass-remarks
45 // Command line flag to enable emitOptimizationRemark()
46 static cl::opt> PassRemarks(
47 "pass-remarks", cl::value_desc("pattern"),
48 cl::desc("Enable optimization remarks from passes whose name match "
49 "the given regular expression"),
50 cl::Hidden, cl::location(PassRemarksPassedOptLoc), cl::ValueRequired,
51 cl::ZeroOrMore);
52
53 // -pass-remarks-missed
54 // Command line flag to enable emitOptimizationRemarkMissed()
55 static cl::opt> PassRemarksMissed(
56 "pass-remarks-missed", cl::value_desc("pattern"),
57 cl::desc("Enable missed optimization remarks from passes whose name match "
58 "the given regular expression"),
59 cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
60 cl::ZeroOrMore);
61
62 // -pass-remarks-analysis
63 // Command line flag to enable emitOptimizationRemarkAnalysis()
64 static cl::opt>
65 PassRemarksAnalysis(
66 "pass-remarks-analysis", cl::value_desc("pattern"),
67 cl::desc(
68 "Enable optimization analysis remarks from passes whose name match "
69 "the given regular expression"),
70 cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
71 cl::ZeroOrMore);
72 }
73
74 bool DiagnosticHandler::isAnalysisRemarkEnabled(StringRef PassName) const {
75 return (PassRemarksAnalysisOptLoc.Pattern &&
76 PassRemarksAnalysisOptLoc.Pattern->match(PassName));
77 }
78 bool DiagnosticHandler::isMissedOptRemarkEnabled(StringRef PassName) const {
79 return (PassRemarksMissedOptLoc.Pattern &&
80 PassRemarksMissedOptLoc.Pattern->match(PassName));
81 }
82 bool DiagnosticHandler::isPassedOptRemarkEnabled(StringRef PassName) const {
83 return (PassRemarksPassedOptLoc.Pattern &&
84 PassRemarksPassedOptLoc.Pattern->match(PassName));
85 }
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "llvm/IR/DiagnosticInfo.h"
15 #include "LLVMContextImpl.h"
1615 #include "llvm/ADT/StringExtras.h"
1716 #include "llvm/ADT/Twine.h"
1817 #include "llvm/ADT/iterator_range.h"
4140
4241 using namespace llvm;
4342
43 namespace {
44
45 /// \brief Regular expression corresponding to the value given in one of the
46 /// -pass-remarks* command line flags. Passes whose name matches this regexp
47 /// will emit a diagnostic via ORE->emit(...);
48 struct PassRemarksOpt {
49 std::shared_ptr Pattern;
50
51 void operator=(const std::string &Val) {
52 if (!Val.empty()) {
53 Pattern = std::make_shared(Val);
54 std::string RegexError;
55 if (!Pattern->isValid(RegexError))
56 report_fatal_error("Invalid regular expression '" + Val +
57 "' in -pass-remarks: " + RegexError,
58 false);
59 }
60 }
61 };
62
63 } // end anonymous namespace
64
65 static PassRemarksOpt PassRemarksOptLoc;
66 static PassRemarksOpt PassRemarksMissedOptLoc;
67 static PassRemarksOpt PassRemarksAnalysisOptLoc;
68
69 // -pass-remarks
70 // Command line flag to enable optimization remarks
71 static cl::opt>
72 PassRemarks("pass-remarks", cl::value_desc("pattern"),
73 cl::desc("Enable optimization remarks from passes whose name match "
74 "the given regular expression"),
75 cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
76 cl::ZeroOrMore);
77
78 // -pass-remarks-missed
79 // Command line flag to enable missed optimization remarks
80 static cl::opt> PassRemarksMissed(
81 "pass-remarks-missed", cl::value_desc("pattern"),
82 cl::desc("Enable missed optimization remarks from passes whose name match "
83 "the given regular expression"),
84 cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
85 cl::ZeroOrMore);
86
87 // -pass-remarks-analysis
88 // Command line flag to enable optimization analysis remarks
89 static cl::opt>
90 PassRemarksAnalysis(
91 "pass-remarks-analysis", cl::value_desc("pattern"),
92 cl::desc(
93 "Enable optimization analysis remarks from passes whose name match "
94 "the given regular expression"),
95 cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
96 cl::ZeroOrMore);
97
4498 int llvm::getNextAvailablePluginDiagnosticKind() {
4599 static std::atomic PluginKindID(DK_FirstPluginKind);
46100 return ++PluginKindID;
228282 RemarkName, *Func, Func->getSubprogram(),
229283 &getFirstFunctionBlock(Func)) {}
230284
231 bool OptimizationRemark::isEnabled() const {
232 const Function &Fn = getFunction();
233 LLVMContext &Ctx = Fn.getContext();
234 return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
285 bool OptimizationRemark::isEnabled(StringRef PassName) {
286 return PassRemarksOptLoc.Pattern &&
287 PassRemarksOptLoc.Pattern->match(PassName);
235288 }
236289
237290 OptimizationRemarkMissed::OptimizationRemarkMissed(
249302 *Inst->getParent()->getParent(),
250303 Inst->getDebugLoc(), Inst->getParent()) {}
251304
252 bool OptimizationRemarkMissed::isEnabled() const {
253 const Function &Fn = getFunction();
254 LLVMContext &Ctx = Fn.getContext();
255 return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
305 bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
306 return PassRemarksMissedOptLoc.Pattern &&
307 PassRemarksMissedOptLoc.Pattern->match(PassName);
256308 }
257309
258310 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
277329 *cast(CodeRegion)->getParent(),
278330 Loc, CodeRegion) {}
279331
280 bool OptimizationRemarkAnalysis::isEnabled() const {
281 const Function &Fn = getFunction();
282 LLVMContext &Ctx = Fn.getContext();
283 return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
284 shouldAlwaysPrint();
332 bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
333 return PassRemarksAnalysisOptLoc.Pattern &&
334 PassRemarksAnalysisOptLoc.Pattern->match(PassName);
285335 }
286336
287337 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
128128 return pImpl->InlineAsmDiagContext;
129129 }
130130
131 void LLVMContext::setDiagnosticHandlerCallBack(
132 DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
133 void *DiagnosticContext, bool RespectFilters) {
134 pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
135 pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
136 pImpl->RespectDiagnosticFilters = RespectFilters;
137 }
138
139 void LLVMContext::setDiagnosticHandler(std::unique_ptr &&DH,
140 bool RespectFilters) {
141 pImpl->DiagHandler = std::move(DH);
131 void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
132 void *DiagnosticContext,
133 bool RespectFilters) {
134 pImpl->DiagnosticHandler = DiagnosticHandler;
135 pImpl->DiagnosticContext = DiagnosticContext;
142136 pImpl->RespectDiagnosticFilters = RespectFilters;
143137 }
144138
164158 pImpl->DiagnosticsOutputFile = std::move(F);
165159 }
166160
167 DiagnosticHandler::DiagnosticHandlerTy
168 LLVMContext::getDiagnosticHandlerCallBack() const {
169 return pImpl->DiagHandler->DiagHandlerCallback;
161 LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
162 return pImpl->DiagnosticHandler;
170163 }
171164
172165 void *LLVMContext::getDiagnosticContext() const {
173 return pImpl->DiagHandler->DiagnosticContext;
166 return pImpl->DiagnosticContext;
174167 }
175168
176169 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
221214
222215 void LLVMContext::diagnose(const DiagnosticInfo &DI) {
223216 // If there is a report handler, use it.
224 if (pImpl->DiagHandler &&
225 (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
226 pImpl->DiagHandler->handleDiagnostics(DI))
217 if (pImpl->DiagnosticHandler) {
218 if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI))
219 pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
227220 return;
221 }
228222
229223 if (!isDiagnosticEnabled(DI))
230224 return;
320314 OptBisect &LLVMContext::getOptBisect() {
321315 return pImpl->getOptBisect();
322316 }
323
324 const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
325 return pImpl->DiagHandler.get();
326 }
327
328 std::unique_ptr LLVMContext::getDiagnosticHandler() {
329 return std::move(pImpl->DiagHandler);
330 }
2121 using namespace llvm;
2222
2323 LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
24 : DiagHandler(llvm::make_unique()),
25 VoidTy(C, Type::VoidTyID),
24 : VoidTy(C, Type::VoidTyID),
2625 LabelTy(C, Type::LabelTyID),
2726 HalfTy(C, Type::HalfTyID),
2827 FloatTy(C, Type::FloatTyID),
11671167 LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr;
11681168 void *InlineAsmDiagContext = nullptr;
11691169
1170 std::unique_ptr DiagHandler;
1170 LLVMContext::DiagnosticHandlerTy DiagnosticHandler = nullptr;
1171 void *DiagnosticContext = nullptr;
11711172 bool RespectDiagnosticFilters = false;
11721173 bool DiagnosticsHotnessRequested = false;
11731174 uint64_t DiagnosticsHotnessThreshold = 0;
621621 }
622622 }
623623
624
625 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
624 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
625 void *Context) {
626 ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
627 }
628
629 void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
626630 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
627631 lto_codegen_diagnostic_severity_t Severity;
628632 switch (DI.getSeverity()) {
652656 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
653657 }
654658
655 namespace {
656 struct LTODiagnosticHandler : public DiagnosticHandler {
657 LTOCodeGenerator *CodeGenerator;
658 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
659 : CodeGenerator(CodeGenPtr) {}
660 bool handleDiagnostics(const DiagnosticInfo &DI) override {
661 CodeGenerator->DiagnosticHandler(DI);
662 return true;
663 }
664 };
665 }
666
667659 void
668660 LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
669661 void *Ctxt) {
670662 this->DiagHandler = DiagHandler;
671663 this->DiagContext = Ctxt;
672664 if (!DiagHandler)
673 return Context.setDiagnosticHandler(nullptr);
665 return Context.setDiagnosticHandler(nullptr, nullptr);
674666 // Register the LTOCodeGenerator stub in the LLVMContext to forward the
675667 // diagnostic to the external DiagHandler.
676 Context.setDiagnosticHandler(llvm::make_unique(this),
677 true);
668 Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this,
669 /* RespectFilters */ true);
678670 }
679671
680672 namespace {
919919 Instruction *I = DepInfo.getInst();
920920 dbgs() << " is clobbered by " << *I << '\n';
921921 );
922 if (ORE->allowExtraAnalysis(DEBUG_TYPE))
922
923 if (ORE->allowExtraAnalysis())
923924 reportMayClobberedLoad(LI, DepInfo, DT, ORE);
924925
925926 return false;
49564956 // Store the result and return it at the end instead of exiting early, in case
49574957 // allowExtraAnalysis is used to report multiple reasons for not vectorizing.
49584958 bool Result = true;
4959
4960 bool DoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
4961 if (DoExtraAnalysis)
49624959 // We must have a loop in canonical form. Loops with indirectbr in them cannot
49634960 // be canonicalized.
49644961 if (!TheLoop->getLoopPreheader()) {
49654962 ORE->emit(createMissedAnalysis("CFGNotUnderstood")
49664963 << "loop control flow is not understood by vectorizer");
4967 if (DoExtraAnalysis)
4964 if (ORE->allowExtraAnalysis())
49684965 Result = false;
49694966 else
49704967 return false;
49774974 if (!TheLoop->empty()) {
49784975 ORE->emit(createMissedAnalysis("NotInnermostLoop")
49794976 << "loop is not the innermost loop");
4980 if (DoExtraAnalysis)
4977 if (ORE->allowExtraAnalysis())
49814978 Result = false;
49824979 else
49834980 return false;
49874984 if (TheLoop->getNumBackEdges() != 1) {
49884985 ORE->emit(createMissedAnalysis("CFGNotUnderstood")
49894986 << "loop control flow is not understood by vectorizer");
4990 if (DoExtraAnalysis)
4987 if (ORE->allowExtraAnalysis())
49914988 Result = false;
49924989 else
49934990 return false;
49974994 if (!TheLoop->getExitingBlock()) {
49984995 ORE->emit(createMissedAnalysis("CFGNotUnderstood")
49994996 << "loop control flow is not understood by vectorizer");
5000 if (DoExtraAnalysis)
4997 if (ORE->allowExtraAnalysis())
50014998 Result = false;
50024999 else
50035000 return false;
50095006 if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
50105007 ORE->emit(createMissedAnalysis("CFGNotUnderstood")
50115008 << "loop control flow is not understood by vectorizer");
5012 if (DoExtraAnalysis)
5009 if (ORE->allowExtraAnalysis())
50135010 Result = false;
50145011 else
50155012 return false;
50235020 unsigned NumBlocks = TheLoop->getNumBlocks();
50245021 if (NumBlocks != 1 && !canVectorizeWithIfConvert()) {
50255022 DEBUG(dbgs() << "LV: Can't if-convert the loop.\n");
5026 if (DoExtraAnalysis)
5023 if (ORE->allowExtraAnalysis())
50275024 Result = false;
50285025 else
50295026 return false;
50325029 // Check if we can vectorize the instructions and CFG in this loop.
50335030 if (!canVectorizeInstrs()) {
50345031 DEBUG(dbgs() << "LV: Can't vectorize the instructions or CFG\n");
5035 if (DoExtraAnalysis)
5032 if (ORE->allowExtraAnalysis())
50365033 Result = false;
50375034 else
50385035 return false;
50415038 // Go over each instruction and look at memory deps.
50425039 if (!canVectorizeMemory()) {
50435040 DEBUG(dbgs() << "LV: Can't vectorize due to memory conflicts\n");
5044 if (DoExtraAnalysis)
5041 if (ORE->allowExtraAnalysis())
50455042 Result = false;
50465043 else
50475044 return false;
50725069 << "Too many SCEV assumptions need to be made and checked "
50735070 << "at runtime");
50745071 DEBUG(dbgs() << "LV: Too many SCEV checks needed.\n");
5075 if (DoExtraAnalysis)
5072 if (ORE->allowExtraAnalysis())
50765073 Result = false;
50775074 else
50785075 return false;
1010 ; CHECK: remark: :0:0: load of type i32 eliminated{{$}}
1111 ; CHECK-NEXT: remark: :0:0: load of type i32 eliminated{{$}}
1212 ; CHECK-NEXT: remark: :0:0: load of type i32 eliminated{{$}}
13 ; CHECK-NEXT: remark: /tmp/s.c:3:3: load of type i32 not eliminated
13 ; CHECK-NOT: remark:
1414
1515 ; YAML: --- !Passed
1616 ; YAML-NEXT: Pass: gvn
234234 return FDOut;
235235 }
236236
237 struct LLCDiagnosticHandler : public DiagnosticHandler {
238 bool *HasError;
239 LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
240 bool handleDiagnostics(const DiagnosticInfo &DI) override {
241 if (DI.getSeverity() == DS_Error)
242 *HasError = true;
243
244 if (auto *Remark = dyn_cast(&DI))
245 if (!Remark->isEnabled())
246 return true;
247
248 DiagnosticPrinterRawOStream DP(errs());
249 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
250 DI.print(DP);
251 errs() << "\n";
252 return true;
253 }
254 };
237 static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
238 bool *HasError = static_cast(Context);
239 if (DI.getSeverity() == DS_Error)
240 *HasError = true;
241
242 if (auto *Remark = dyn_cast(&DI))
243 if (!Remark->isEnabled())
244 return;
245
246 DiagnosticPrinterRawOStream DP(errs());
247 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
248 DI.print(DP);
249 errs() << "\n";
250 }
255251
256252 static void InlineAsmDiagHandler(const SMDiagnostic &SMD, void *Context,
257253 unsigned LocCookie) {
311307
312308 // Set a diagnostic handler that doesn't exit on the first error
313309 bool HasError = false;
314 Context.setDiagnosticHandler(
315 llvm::make_unique(&HasError));
310 Context.setDiagnosticHandler(DiagnosticHandler, &HasError);
316311 Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
317312
318313 if (PassRemarksWithHotness)
568563
569564 PM.run(*M);
570565
571 auto HasError =
572 ((const LLCDiagnosticHandler *)(Context.getDiagHandlerPtr()))->HasError;
573 if (*HasError)
566 auto HasError = *static_cast(Context.getDiagnosticContext());
567 if (HasError)
574568 return 1;
575569
576570 // Compare the two outputs and make sure they're the same
121121 }
122122 };
123123
124 struct LLVMDisDiagnosticHandler : public DiagnosticHandler {
125 char *Prefix;
126 LLVMDisDiagnosticHandler(char *PrefixPtr) : Prefix(PrefixPtr) {}
127 bool handleDiagnostics(const DiagnosticInfo &DI) override {
128 raw_ostream &OS = errs();
129 OS << Prefix << ": ";
130 switch (DI.getSeverity()) {
131 case DS_Error: OS << "error: "; break;
132 case DS_Warning: OS << "warning: "; break;
133 case DS_Remark: OS << "remark: "; break;
134 case DS_Note: OS << "note: "; break;
135 }
136
137 DiagnosticPrinterRawOStream DP(OS);
138 DI.print(DP);
139 OS << '\n';
140
141 if (DI.getSeverity() == DS_Error)
142 exit(1);
143 return true;
144 }
145 };
146124 } // end anon namespace
125
126 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
127 raw_ostream &OS = errs();
128 OS << (char *)Context << ": ";
129 switch (DI.getSeverity()) {
130 case DS_Error: OS << "error: "; break;
131 case DS_Warning: OS << "warning: "; break;
132 case DS_Remark: OS << "remark: "; break;
133 case DS_Note: OS << "note: "; break;
134 }
135
136 DiagnosticPrinterRawOStream DP(OS);
137 DI.print(DP);
138 OS << '\n';
139
140 if (DI.getSeverity() == DS_Error)
141 exit(1);
142 }
147143
148144 static ExitOnError ExitOnErr;
149145
169165
170166 LLVMContext Context;
171167 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
172 Context.setDiagnosticHandler(
173 llvm::make_unique(argv[0]));
168
169 Context.setDiagnosticHandler(diagnosticHandler, argv[0]);
170
174171 cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
175172
176173 std::unique_ptr M = openInputFile(Context);
181181 }
182182 } // anonymous namespace
183183
184 namespace {
185 struct LLVMLinkDiagnosticHandler : public DiagnosticHandler {
186 bool handleDiagnostics(const DiagnosticInfo &DI) override {
187 unsigned Severity = DI.getSeverity();
188 switch (Severity) {
189 case DS_Error:
190 errs() << "ERROR: ";
191 break;
192 case DS_Warning:
193 if (SuppressWarnings)
194 return true;
195 errs() << "WARNING: ";
196 break;
197 case DS_Remark:
198 case DS_Note:
199 llvm_unreachable("Only expecting warnings and errors");
200 }
201
202 DiagnosticPrinterRawOStream DP(errs());
203 DI.print(DP);
204 errs() << '\n';
205 return true;
206 }
207 };
184 static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
185 unsigned Severity = DI.getSeverity();
186 switch (Severity) {
187 case DS_Error:
188 errs() << "ERROR: ";
189 break;
190 case DS_Warning:
191 if (SuppressWarnings)
192 return;
193 errs() << "WARNING: ";
194 break;
195 case DS_Remark:
196 case DS_Note:
197 llvm_unreachable("Only expecting warnings and errors");
198 }
199
200 DiagnosticPrinterRawOStream DP(errs());
201 DI.print(DP);
202 errs() << '\n';
208203 }
209204
210205 /// Import any functions requested via the -import option.
351346 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
352347
353348 LLVMContext Context;
354 Context.setDiagnosticHandler(
355 llvm::make_unique(), true);
349 Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);
350
356351 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
357352 cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
358353
234234 }
235235
236236 static std::string CurrentActivity;
237
238 namespace {
239 struct LLVMLTODiagnosticHandler : public DiagnosticHandler {
240 bool handleDiagnostics(const DiagnosticInfo &DI) override {
241 raw_ostream &OS = errs();
242 OS << "llvm-lto: ";
243 switch (DI.getSeverity()) {
244 case DS_Error:
245 OS << "error";
246 break;
247 case DS_Warning:
248 OS << "warning";
249 break;
250 case DS_Remark:
251 OS << "remark";
252 break;
253 case DS_Note:
254 OS << "note";
255 break;
256 }
257 if (!CurrentActivity.empty())
258 OS << ' ' << CurrentActivity;
259 OS << ": ";
260
261 DiagnosticPrinterRawOStream DP(OS);
262 DI.print(DP);
263 OS << '\n';
264
265 if (DI.getSeverity() == DS_Error)
266 exit(1);
267 return true;
268 }
269 };
270 }
237 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
238 raw_ostream &OS = errs();
239 OS << "llvm-lto: ";
240 switch (DI.getSeverity()) {
241 case DS_Error:
242 OS << "error";
243 break;
244 case DS_Warning:
245 OS << "warning";
246 break;
247 case DS_Remark:
248 OS << "remark";
249 break;
250 case DS_Note:
251 OS << "note";
252 break;
253 }
254 if (!CurrentActivity.empty())
255 OS << ' ' << CurrentActivity;
256 OS << ": ";
257
258 DiagnosticPrinterRawOStream DP(OS);
259 DI.print(DP);
260 OS << '\n';
261
262 if (DI.getSeverity() == DS_Error)
263 exit(1);
264 }
271265
272266 static void error(const Twine &Msg) {
273267 errs() << "llvm-lto: " << Msg << '\n';
298292 Buffer = std::move(BufferOrErr.get());
299293 CurrentActivity = ("loading file '" + Path + "'").str();
300294 std::unique_ptr Context = llvm::make_unique();
301 Context->setDiagnosticHandler(llvm::make_unique(),
302 true);
295 Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
303296 ErrorOr> Ret = LTOModule::createInLocalContext(
304297 std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(),
305298 Options, Path);
843836 unsigned BaseArg = 0;
844837
845838 LLVMContext Context;
846 Context.setDiagnosticHandler(llvm::make_unique(),
847 true);
839 Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);
848840
849841 LTOCodeGenerator CodeGen(Context);
850842
7474
7575 static LLVMContext *LTOContext = nullptr;
7676
77 struct LTOToolDiagnosticHandler : public DiagnosticHandler {
78 bool handleDiagnostics(const DiagnosticInfo &DI) override {
79 if (DI.getSeverity() != DS_Error) {
80 DiagnosticPrinterRawOStream DP(errs());
81 DI.print(DP);
82 errs() << '\n';
83 return true;
84 }
85 sLastErrorString = "";
86 {
87 raw_string_ostream Stream(sLastErrorString);
88 DiagnosticPrinterRawOStream DP(Stream);
89 DI.print(DP);
90 }
91 return true;
92 }
93 };
77 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
78 if (DI.getSeverity() != DS_Error) {
79 DiagnosticPrinterRawOStream DP(errs());
80 DI.print(DP);
81 errs() << '\n';
82 return;
83 }
84 sLastErrorString = "";
85 {
86 raw_string_ostream Stream(sLastErrorString);
87 DiagnosticPrinterRawOStream DP(Stream);
88 DI.print(DP);
89 }
90 }
9491
9592 // Initialize the configured targets if they have not been initialized.
9693 static void lto_initialize() {
110107
111108 static LLVMContext Context;
112109 LTOContext = &Context;
113 LTOContext->setDiagnosticHandler(
114 llvm::make_unique(), true);
110 LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
115111 initialized = true;
116112 }
117113 }
277273
278274 // Create a local context. Ownership will be transferred to LTOModule.
279275 std::unique_ptr Context = llvm::make_unique();
280 Context->setDiagnosticHandler(llvm::make_unique(),
281 true);
276 Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
282277
283278 ErrorOr> M = LTOModule::createInLocalContext(
284279 std::move(Context), mem, length, Options, StringRef(path));