llvm.org GIT mirror llvm / aa137aa
[Remarks] Refactor remark diagnostic emission in a RemarkStreamer This allows us to store more info about where we're emitting the remarks without cluttering LLVMContext. This is needed for future support for the remark section. Differential Revision: https://reviews.llvm.org/D58996 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355507 91177308-0d34-0410-b5e6-96231b3b80d8 Francis Visoiu Mistrih 5 months ago
13 changed file(s) with 130 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
7676 // remarks enabled. We can't currently check whether remarks are requested
7777 // for the calling pass since that requires actually building the remark.
7878
79 if (F->getContext().getDiagnosticsOutputFile() ||
79 if (F->getContext().getRemarkStreamer() ||
8080 F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
8181 auto R = RemarkBuilder();
8282 emit((DiagnosticInfoOptimizationBase &)R);
9191 /// provide more context so that non-trivial false positives can be quickly
9292 /// detected by the user.
9393 bool allowExtraAnalysis(StringRef PassName) const {
94 return (F->getContext().getDiagnosticsOutputFile() ||
94 return (F->getContext().getRemarkStreamer() ||
9595 F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
9696 }
9797
157157 /// (1) to filter trivial false positives or (2) to provide more context so
158158 /// that non-trivial false positives can be quickly detected by the user.
159159 bool allowExtraAnalysis(StringRef PassName) const {
160 return (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
161 MF.getFunction().getContext()
162 .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
160 return (
161 MF.getFunction().getContext().getRemarkStreamer() ||
162 MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
163 PassName));
163164 }
164165
165166 /// Take a lambda that returns a remark which will be emitted. Second
170171 // remarks enabled. We can't currently check whether remarks are requested
171172 // for the calling pass since that requires actually building the remark.
172173
173 if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
174 MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
174 if (MF.getFunction().getContext().getRemarkStreamer() ||
175 MF.getFunction()
176 .getContext()
177 .getDiagHandlerPtr()
178 ->isAnyRemarkEnabled()) {
175179 auto R = RemarkBuilder();
176180 emit((DiagnosticInfoOptimizationBase &)R);
177181 }
3434 class SMDiagnostic;
3535 class StringRef;
3636 class Twine;
37
38 namespace yaml {
39
40 class Output;
41
42 } // end namespace yaml
37 class RemarkStreamer;
38 class raw_ostream;
4339
4440 namespace SyncScope {
4541
245241 /// included in optimization diagnostics.
246242 void setDiagnosticsHotnessThreshold(uint64_t Threshold);
247243
248 /// Return the YAML file used by the backend to save optimization
249 /// diagnostics. If null, diagnostics are not saved in a file but only
250 /// emitted via the diagnostic handler.
251 yaml::Output *getDiagnosticsOutputFile();
252 /// Set the diagnostics output file used for optimization diagnostics.
253 ///
254 /// By default or if invoked with null, diagnostics are not saved in a file
255 /// but only emitted via the diagnostic handler. Even if an output file is
256 /// set, the handler is invoked for each diagnostic message.
257 void setDiagnosticsOutputFile(std::unique_ptr F);
244 /// Return the streamer used by the backend to save remark diagnostics. If it
245 /// does not exist, diagnostics are not saved in a file but only emitted via
246 /// the diagnostic handler.
247 RemarkStreamer *getRemarkStreamer();
248 const RemarkStreamer *getRemarkStreamer() const;
249
250 /// Set the diagnostics output used for optimization diagnostics.
251 /// This filename may be embedded in a section for tools to find the
252 /// diagnostics whenever they're needed.
253 ///
254 /// If a remark streamer is already set, it will be replaced with
255 /// \p RemarkStreamer.
256 ///
257 /// By default, diagnostics are not saved in a file but only emitted via the
258 /// diagnostic handler. Even if an output file is set, the handler is invoked
259 /// for each diagnostic message.
260 void setRemarkStreamer(std::unique_ptr RemarkStreamer);
258261
259262 /// Get the prefix that should be printed in front of a diagnostic of
260263 /// the given \p Severity
0 //===- llvm/IR/RemarkStreamer.h - Remark Streamer ---------------*- C++ -*-===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file declares the main interface for outputting remarks.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_IR_REMARKSTREAMER_H
13 #define LLVM_IR_REMARKSTREAMER_H
14
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/Support/YAMLTraits.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include
19 #include
20
21 namespace llvm {
22 /// Streamer for remarks.
23 class RemarkStreamer {
24 /// The filename that the remark diagnostics are emitted to.
25 const std::string Filename;
26 /// The open raw_ostream that the remark diagnostics are emitted to.
27 raw_ostream &OS;
28
29 /// The YAML streamer.
30 yaml::Output YAMLOutput;
31
32 public:
33 RemarkStreamer(StringRef Filename, raw_ostream& OS);
34 /// Return the filename that the remark diagnostics are emitted to.
35 StringRef getFilename() const { return Filename; }
36 /// Return stream that the remark diagnostics are emitted to.
37 raw_ostream &getStream() { return OS; }
38 /// Emit a diagnostic through the streamer.
39 void emit(const DiagnosticInfoOptimizationBase &Diag);
40 };
41 } // end namespace llvm
42
43 #endif // LLVM_IR_REMARKSTREAMER_H
7777 #include "llvm/IR/Metadata.h"
7878 #include "llvm/IR/Module.h"
7979 #include "llvm/IR/Operator.h"
80 #include "llvm/IR/RemarkStreamer.h"
8081 #include "llvm/IR/Type.h"
8182 #include "llvm/IR/Value.h"
8283 #include "llvm/MC/MCAsmInfo.h"
4545 PassManager.cpp
4646 PassRegistry.cpp
4747 PassTimingInfo.cpp
48 RemarkStreamer.cpp
4849 SafepointIRVerifier.cpp
4950 ProfileSummary.cpp
5051 Statepoint.cpp
2626 #include "llvm/IR/LLVMContext.h"
2727 #include "llvm/IR/Metadata.h"
2828 #include "llvm/IR/Module.h"
29 #include "llvm/IR/RemarkStreamer.h"
2930 #include "llvm/IR/Type.h"
3031 #include "llvm/IR/Value.h"
3132 #include "llvm/Support/Casting.h"
2020 #include "llvm/IR/DiagnosticPrinter.h"
2121 #include "llvm/IR/Metadata.h"
2222 #include "llvm/IR/Module.h"
23 #include "llvm/IR/RemarkStreamer.h"
2324 #include "llvm/Support/Casting.h"
2425 #include "llvm/Support/ErrorHandling.h"
2526 #include "llvm/Support/raw_ostream.h"
159160 return pImpl->DiagnosticsHotnessThreshold;
160161 }
161162
162 yaml::Output *LLVMContext::getDiagnosticsOutputFile() {
163 return pImpl->DiagnosticsOutputFile.get();
164 }
165
166 void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr F) {
167 pImpl->DiagnosticsOutputFile = std::move(F);
163 RemarkStreamer *LLVMContext::getRemarkStreamer() {
164 return pImpl->RemarkStreamer.get();
165 }
166 const RemarkStreamer *LLVMContext::getRemarkStreamer() const {
167 return const_cast(this)->getRemarkStreamer();
168 }
169 void LLVMContext::setRemarkStreamer(
170 std::unique_ptr RemarkStreamer) {
171 pImpl->RemarkStreamer = std::move(RemarkStreamer);
168172 }
169173
170174 DiagnosticHandler::DiagnosticHandlerTy
227231 }
228232
229233 void LLVMContext::diagnose(const DiagnosticInfo &DI) {
230 if (auto *OptDiagBase = dyn_cast(&DI)) {
231 yaml::Output *Out = getDiagnosticsOutputFile();
232 if (Out) {
233 // For remarks the << operator takes a reference to a pointer.
234 auto *P = const_cast(OptDiagBase);
235 *Out << P;
236 }
237 }
234 if (auto *OptDiagBase = dyn_cast(&DI))
235 if (RemarkStreamer *RS = getRemarkStreamer())
236 RS->emit(*OptDiagBase);
237
238238 // If there is a report handler, use it.
239239 if (pImpl->DiagHandler &&
240240 (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
3636 #include "llvm/IR/DerivedTypes.h"
3737 #include "llvm/IR/LLVMContext.h"
3838 #include "llvm/IR/Metadata.h"
39 #include "llvm/IR/RemarkStreamer.h"
3940 #include "llvm/IR/TrackingMDRef.h"
4041 #include "llvm/Support/Allocator.h"
4142 #include "llvm/Support/Casting.h"
12251226 bool RespectDiagnosticFilters = false;
12261227 bool DiagnosticsHotnessRequested = false;
12271228 uint64_t DiagnosticsHotnessThreshold = 0;
1228 std::unique_ptr<yaml::Output> DiagnosticsOutputFile;
1229 std::unique_ptr<RemarkStreamer> RemarkStreamer;
12291230
12301231 LLVMContext::YieldCallbackTy YieldCallback = nullptr;
12311232 void *YieldOpaqueHandle = nullptr;
0 //===- llvm/IR/RemarkStreamer.cpp - Remark Streamer -*- C++ -------------*-===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file contains the implementation of the remark outputting as part of
9 // LLVMContext.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/IR/RemarkStreamer.h"
14
15 using namespace llvm;
16
17 RemarkStreamer::RemarkStreamer(StringRef Filename, raw_ostream &OS)
18 : Filename(Filename), OS(OS),
19 YAMLOutput(OS, reinterpret_cast(this)) {
20 assert(!Filename.empty() && "This needs to be a real filename.");
21 }
22
23 void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
24 DiagnosticInfoOptimizationBase *DiagPtr =
25 const_cast(&Diag);
26 YAMLOutput << DiagPtr;
27 }
2323 #include "llvm/IR/LegacyPassManager.h"
2424 #include "llvm/IR/Mangler.h"
2525 #include "llvm/IR/Metadata.h"
26 #include "llvm/IR/RemarkStreamer.h"
2627 #include "llvm/LTO/LTOBackend.h"
2728 #include "llvm/LTO/SummaryBasedOptimizations.h"
2829 #include "llvm/Linker/IRMover.h"
13251326 llvm::make_unique(Filename, EC, sys::fs::F_None);
13261327 if (EC)
13271328 return errorCodeToError(EC);
1328 Context.setDiagnosticsOutputFile(
1329 llvm::make_unique(DiagnosticFile->os()));
1329 Context.setRemarkStreamer(
1330 llvm::make_unique(Filename, DiagnosticFile->os()));
13301331 DiagnosticFile->keep();
13311332 return std::move(DiagnosticFile);
13321333 }
3030 #include "llvm/IR/LLVMContext.h"
3131 #include "llvm/IR/LegacyPassManager.h"
3232 #include "llvm/IR/Module.h"
33 #include "llvm/IR/RemarkStreamer.h"
3334 #include "llvm/IR/Verifier.h"
3435 #include "llvm/IRReader/IRReader.h"
3536 #include "llvm/MC/SubtargetFeature.h"
332333 WithColor::error(errs(), argv[0]) << EC.message() << '\n';
333334 return 1;
334335 }
335 Context.setDiagnosticsOutputFile(
336 llvm::make_unique(YamlFile->os()));
336 Context.setRemarkStreamer(
337 llvm::make_unique(RemarksFilename, YamlFile->os()));
337338 }
338339
339340 if (InputLanguage != "" && InputLanguage != "ir" &&
3232 #include "llvm/IR/LegacyPassManager.h"
3333 #include "llvm/IR/LegacyPassNameParser.h"
3434 #include "llvm/IR/Module.h"
35 #include "llvm/IR/RemarkStreamer.h"
3536 #include "llvm/IR/Verifier.h"
3637 #include "llvm/IRReader/IRReader.h"
3738 #include "llvm/InitializePasses.h"
562563 errs() << EC.message() << '\n';
563564 return 1;
564565 }
565 Context.setDiagnosticsOutputFile(
566 llvm::make_unique(OptRemarkFile->os()));
566 Context.setRemarkStreamer(llvm::make_unique(
567 RemarksFilename, OptRemarkFile->os()));
567568 }
568569
569570 // Load the input module...