llvm.org GIT mirror llvm / 1e25281
Reland "[Remarks] Add -foptimization-record-passes to filter remark emission" Currently we have -Rpass for filtering the remarks that are displayed as diagnostics, but when using -fsave-optimization-record, there is no way to filter the remarks while generating them. This adds support for filtering remarks by passes using a regex. Ex: `clang -fsave-optimization-record -foptimization-record-passes=inline` will only emit the remarks coming from the pass `inline`. This adds: * `-fsave-optimization-record` to the driver * `-opt-record-passes` to cc1 * `-lto-pass-remarks-filter` to the LTOCodeGenerator * `--opt-remarks-passes` to lld * `-pass-remarks-filter` to llc, opt, llvm-lto, llvm-lto2 * `-opt-remarks-passes` to gold-plugin Differential Revision: https://reviews.llvm.org/D59268 Original llvm-svn: 355964 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355984 91177308-0d34-0410-b5e6-96231b3b80d8 Francis Visoiu Mistrih 5 months ago
14 changed file(s) with 85 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
1313 #define LLVM_IR_REMARKSTREAMER_H
1414
1515 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/Support/Error.h"
1617 #include "llvm/Support/YAMLTraits.h"
1718 #include "llvm/Support/raw_ostream.h"
19 #include "llvm/Support/Regex.h"
1820 #include
1921 #include
2022
2527 const std::string Filename;
2628 /// The open raw_ostream that the remark diagnostics are emitted to.
2729 raw_ostream &OS;
30 /// The regex used to filter remarks based on the passes that emit them.
31 Optional PassFilter;
2832
2933 /// The YAML streamer.
3034 yaml::Output YAMLOutput;
3539 StringRef getFilename() const { return Filename; }
3640 /// Return stream that the remark diagnostics are emitted to.
3741 raw_ostream &getStream() { return OS; }
42 /// Set a pass filter based on a regex \p Filter.
43 /// Returns an error if the regex is invalid.
44 Error setFilter(StringRef Filter);
3845 /// Emit a diagnostic through the streamer.
3946 void emit(const DiagnosticInfoOptimizationBase &Diag);
4047 };
9494
9595 /// Optimization remarks file path.
9696 std::string RemarksFilename = "";
97
98 /// Optimization remarks pass filter.
99 std::string RemarksPasses = "";
97100
98101 /// Whether to emit optimization remarks with hotness informations.
99102 bool RemarksWithHotness = false;
8383 /// Setup optimization remarks.
8484 Expected>
8585 setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename,
86 StringRef LTORemarksPasses,
8687 bool LTOPassRemarksWithHotness, int Count = -1);
8788
8889 class LTO;
2020 assert(!Filename.empty() && "This needs to be a real filename.");
2121 }
2222
23 Error RemarkStreamer::setFilter(StringRef Filter) {
24 Regex R = Regex(Filter);
25 std::string RegexError;
26 if (!R.isValid(RegexError))
27 return createStringError(std::make_error_code(std::errc::invalid_argument),
28 RegexError.data());
29 PassFilter = std::move(R);
30 return Error::success();
31 }
32
2333 void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
34 if (Optional &Filter = PassFilter)
35 if (!Filter->match(Diag.getPassName()))
36 return;
37
2438 DiagnosticInfoOptimizationBase *DiagPtr =
2539 const_cast(&Diag);
2640 YAMLOutput << DiagPtr;
13111311 Expected>
13121312 lto::setupOptimizationRemarks(LLVMContext &Context,
13131313 StringRef LTORemarksFilename,
1314 StringRef LTORemarksPasses,
13141315 bool LTOPassRemarksWithHotness, int Count) {
13151316 if (LTOPassRemarksWithHotness)
13161317 Context.setDiagnosticsHotnessRequested(true);
13281329 return errorCodeToError(EC);
13291330 Context.setRemarkStreamer(
13301331 llvm::make_unique(Filename, DiagnosticFile->os()));
1332
1333 if (!LTORemarksPasses.empty())
1334 if (Error E = Context.getRemarkStreamer()->setFilter(LTORemarksPasses))
1335 return std::move(E);
1336
13311337 DiagnosticFile->keep();
13321338 return std::move(DiagnosticFile);
13331339 }
428428 std::unique_ptr TM = createTargetMachine(C, *TOrErr, *Mod);
429429
430430 // Setup optimization remarks.
431 auto DiagFileOrErr = lto::setupOptimizationRemarks(
432 Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness);
431 auto DiagFileOrErr =
432 lto::setupOptimizationRemarks(Mod->getContext(), C.RemarksFilename,
433 C.RemarksPasses, C.RemarksWithHotness);
433434 if (!DiagFileOrErr)
434435 return DiagFileOrErr.takeError();
435436 auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
483484
484485 // Setup optimization remarks.
485486 auto DiagFileOrErr = lto::setupOptimizationRemarks(
486 Mod.getContext(), Conf.RemarksFilename, Conf.RemarksWithHotness, Task);
487 Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
488 Conf.RemarksWithHotness, Task);
487489 if (!DiagFileOrErr)
488490 return DiagFileOrErr.takeError();
489491 auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
8484 cl::desc("Output filename for pass remarks"),
8585 cl::value_desc("filename"));
8686
87 cl::opt
88 LTORemarksPasses("lto-pass-remarks-filter",
89 cl::desc("Only record optimization remarks from passes "
90 "whose names match the given regular expression"),
91 cl::value_desc("regex"));
92
8793 cl::opt LTOPassRemarksWithHotness(
8894 "lto-pass-remarks-with-hotness",
8995 cl::desc("With PGO, include profile count in optimization remarks"),
504510 return false;
505511
506512 auto DiagFileOrErr = lto::setupOptimizationRemarks(
507 Context, LTORemarksFilename, LTOPassRemarksWithHotness);
513 Context, LTORemarksFilename, LTORemarksPasses, LTOPassRemarksWithHotness);
508514 if (!DiagFileOrErr) {
509515 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
510516 report_fatal_error("Can't get an output file for the remarks");
6969 // Flags -discard-value-names, defined in LTOCodeGenerator.cpp
7070 extern cl::opt LTODiscardValueNames;
7171 extern cl::opt LTORemarksFilename;
72 extern cl::opt LTORemarksPasses;
7273 extern cl::opt LTOPassRemarksWithHotness;
7374 }
7475
971972 Context.setDiscardValueNames(LTODiscardValueNames);
972973 Context.enableDebugTypeODRUniquing();
973974 auto DiagFileOrErr = lto::setupOptimizationRemarks(
974 Context, LTORemarksFilename, LTOPassRemarksWithHotness, count);
975 Context, LTORemarksFilename, LTORemarksPasses,
976 LTOPassRemarksWithHotness, count);
975977 if (!DiagFileOrErr) {
976978 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
977979 report_fatal_error("ThinLTO: Can't get an output file for the "
33 ; RUN: llvm-as < %s >%t.bc
44 ; RUN: rm -f %t.yaml
55 ; RUN: llvm-lto2 run -pass-remarks-output=%t.yaml \
6 ; RUN: -pass-remarks-filter=inline \
67 ; RUN: -r %t.bc,tinkywinky,p \
78 ; RUN: -r %t.bc,patatino,px \
89 ; RUN: -r %t.bc,main,px -o %t.o %t.bc
1213 ; RUN: opt -module-summary %s -o %t.bc
1314 ; RUN: rm -f %t.thin.1.yaml
1415 ; RUN: llvm-lto2 run -pass-remarks-output=%t \
16 ; RUN: -pass-remarks-filter=inline \
1517 ; RUN: -r %t.bc,tinkywinky,p \
1618 ; RUN: -r %t.bc,patatino,px \
1719 ; RUN: -r %t.bc,main,px -o %t.o %t.bc
44 ; RUN: rm -f %t.yaml.thin.0.yaml %t.yaml.thin.1.yaml
55 ; RUN: llvm-lto -thinlto-action=run \
66 ; RUN: -lto-pass-remarks-output=%t.yaml \
7 ; RUN: -lto-pass-remarks-filter=inline \
78 ; RUN: -exported-symbol _func2 \
89 ; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \
910 ; RUN: FileCheck %s -allow-empty
204204 /// Statistics output filename.
205205 static std::string stats_file;
206206
207 // Optimization remarks filename and hotness options
207 // Optimization remarks filename, accepted passes and hotness options
208208 static std::string OptRemarksFilename;
209 static std::string OptRemarksFilter;
209210 static bool OptRemarksWithHotness = false;
210211
211212 // Context sensitive PGO options.
284285 dwo_dir = opt.substr(strlen("dwo_dir="));
285286 } else if (opt.startswith("opt-remarks-filename=")) {
286287 OptRemarksFilename = opt.substr(strlen("opt-remarks-filename="));
288 } else if (opt.startswith("opt-remarks-passes=")) {
289 OptRemarksFilter = opt.substr(strlen("opt-remarks-passes="));
287290 } else if (opt == "opt-remarks-with-hotness") {
288291 OptRemarksWithHotness = true;
289292 } else if (opt.startswith("stats-file=")) {
907910
908911 // Set up optimization remarks handling.
909912 Conf.RemarksFilename = options::OptRemarksFilename;
913 Conf.RemarksPasses = options::OptRemarksFilter;
910914 Conf.RemarksWithHotness = options::OptRemarksWithHotness;
911915
912916 // Use new pass manager if set in driver
147147 cl::desc("YAML output filename for pass remarks"),
148148 cl::value_desc("filename"));
149149
150 static cl::opt
151 RemarksPasses("pass-remarks-filter",
152 cl::desc("Only record optimization remarks from passes whose "
153 "names match the given regular expression"),
154 cl::value_desc("regex"));
155
150156 namespace {
151157 static ManagedStatic> RunPassNames;
152158
335341 }
336342 Context.setRemarkStreamer(
337343 llvm::make_unique(RemarksFilename, YamlFile->os()));
344
345 if (!RemarksPasses.empty())
346 if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
347 WithColor::error(errs(), argv[0]) << E << '\n';
348 return 1;
349 }
338350 }
339351
340352 if (InputLanguage != "" && InputLanguage != "ir" &&
9898 "pass-remarks-with-hotness",
9999 cl::desc("Whether to include hotness informations in the remarks.\n"
100100 "Has effect only if -pass-remarks-output is specified."));
101
102 static cl::opt
103 OptRemarksPasses("pass-remarks-filter",
104 cl::desc("Only record optimization remarks from passes "
105 "whose names match the given regular expression"),
106 cl::value_desc("regex"));
101107
102108 static cl::opt
103109 SamplePGOFile("lto-sample-profile-file",
219225
220226 // Optimization remarks.
221227 Conf.RemarksFilename = OptRemarksOutput;
228 Conf.RemarksPasses = OptRemarksPasses;
222229 Conf.RemarksWithHotness = OptRemarksWithHotness;
223230
224231 Conf.SampleProfile = SamplePGOFile;
274274 cl::desc("YAML output filename for pass remarks"),
275275 cl::value_desc("filename"));
276276
277 static cl::opt
278 RemarksPasses("pass-remarks-filter",
279 cl::desc("Only record optimization remarks from passes whose "
280 "names match the given regular expression"),
281 cl::value_desc("regex"));
282
277283 cl::opt
278284 PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
279285 cl::desc("The kind of profile guided optimization"),
565571 }
566572 Context.setRemarkStreamer(llvm::make_unique(
567573 RemarksFilename, OptRemarkFile->os()));
574
575 if (!RemarksPasses.empty())
576 if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
577 errs() << E << '\n';
578 return 1;
579 }
568580 }
569581
570582 // Load the input module...