llvm.org GIT mirror llvm / 6058aa9
Reland: [Remarks] Refactor optimization remarks setup * Add a common function to setup opt-remarks * Rename common options to the same names * Add error types to distinguish between file errors and regex errors git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363415 91177308-0d34-0410-b5e6-96231b3b80d8 Francis Visoiu Mistrih 3 months ago
11 changed file(s) with 169 addition(s) and 140 deletion(s). Raw diff Collapse all Expand all
1616 #include "llvm/Remarks/RemarkSerializer.h"
1717 #include "llvm/Support/Error.h"
1818 #include "llvm/Support/Regex.h"
19 #include "llvm/Support/ToolOutputFile.h"
1920 #include "llvm/Support/raw_ostream.h"
2021 #include
2122 #include
5657 /// Emit a diagnostic through the streamer.
5758 void emit(const DiagnosticInfoOptimizationBase &Diag);
5859 };
60
61 template
62 struct RemarkSetupErrorInfo : public ErrorInfo {
63 std::string Msg;
64 std::error_code EC;
65
66 RemarkSetupErrorInfo(Error E) {
67 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
68 Msg = EIB.message();
69 EC = EIB.convertToErrorCode();
70 });
71 }
72
73 void log(raw_ostream &OS) const override { OS << Msg; }
74 std::error_code convertToErrorCode() const override { return EC; }
75 };
76
77 struct RemarkSetupFileError : RemarkSetupErrorInfo {
78 static char ID;
79 using RemarkSetupErrorInfo::RemarkSetupErrorInfo;
80 };
81
82 struct RemarkSetupPatternError : RemarkSetupErrorInfo {
83 static char ID;
84 using RemarkSetupErrorInfo::RemarkSetupErrorInfo;
85 };
86
87 /// Setup optimization remarks.
88 Expected>
89 setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
90 StringRef RemarksPasses, bool RemarksWithHotness,
91 unsigned RemarksHotnessThreshold = 0);
92
5993 } // end namespace llvm
6094
6195 #endif // LLVM_IR_REMARKSTREAMER_H
8383
8484 /// Setup optimization remarks.
8585 Expected>
86 setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename,
87 StringRef LTORemarksPasses,
88 bool LTOPassRemarksWithHotness, int Count = -1);
86 setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
87 StringRef RemarksPasses, bool RemarksWithHotness,
88 int Count = -1);
8989
9090 /// Setups the output file for saving statistics.
9191 Expected>
105105 // Then, emit the remark through the serializer.
106106 Serializer->emit(R);
107107 }
108
109 char RemarkSetupFileError::ID = 0;
110 char RemarkSetupPatternError::ID = 0;
111
112 Expected>
113 llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
114 StringRef RemarksPasses, bool RemarksWithHotness,
115 unsigned RemarksHotnessThreshold) {
116 if (RemarksWithHotness)
117 Context.setDiagnosticsHotnessRequested(true);
118
119 if (RemarksHotnessThreshold)
120 Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
121
122 if (RemarksFilename.empty())
123 return nullptr;
124
125 std::error_code EC;
126 auto RemarksFile =
127 llvm::make_unique(RemarksFilename, EC, sys::fs::F_None);
128 // We don't use llvm::FileError here because some diagnostics want the file
129 // name separately.
130 if (EC)
131 return errorCodeToError(EC);
132
133 Context.setRemarkStreamer(llvm::make_unique(
134 RemarksFilename,
135 llvm::make_unique(RemarksFile->os())));
136
137 if (!RemarksPasses.empty())
138 if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
139 return std::move(E);
140
141 return std::move(RemarksFile);
142 }
13371337 }
13381338
13391339 Expected>
1340 lto::setupOptimizationRemarks(LLVMContext &Context,
1341 StringRef LTORemarksFilename,
1342 StringRef LTORemarksPasses,
1343 bool LTOPassRemarksWithHotness, int Count) {
1344 if (LTOPassRemarksWithHotness)
1345 Context.setDiagnosticsHotnessRequested(true);
1346 if (LTORemarksFilename.empty())
1347 return nullptr;
1348
1349 std::string Filename = LTORemarksFilename;
1350 if (Count != -1)
1340 lto::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
1341 StringRef RemarksPasses, bool RemarksWithHotness,
1342 int Count) {
1343 std::string Filename = RemarksFilename;
1344 if (!Filename.empty() && Count != -1)
13511345 Filename += ".thin." + llvm::utostr(Count) + ".yaml";
13521346
1353 std::error_code EC;
1354 auto DiagnosticFile =
1355 llvm::make_unique(Filename, EC, sys::fs::F_None);
1356 if (EC)
1357 return errorCodeToError(EC);
1358 Context.setRemarkStreamer(llvm::make_unique(
1359 Filename,
1360 llvm::make_unique(DiagnosticFile->os())));
1361
1362 if (!LTORemarksPasses.empty())
1363 if (Error E = Context.getRemarkStreamer()->setFilter(LTORemarksPasses))
1364 return std::move(E);
1365
1366 DiagnosticFile->keep();
1367 return std::move(DiagnosticFile);
1347 auto ResultOrErr = llvm::setupOptimizationRemarks(
1348 Context, Filename, RemarksPasses, RemarksWithHotness);
1349 if (Error E = ResultOrErr.takeError())
1350 return std::move(E);
1351
1352 if (*ResultOrErr)
1353 (*ResultOrErr)->keep();
1354
1355 return ResultOrErr;
13681356 }
13691357
13701358 Expected>
2121 #include "llvm/Bitcode/BitcodeWriter.h"
2222 #include "llvm/IR/LegacyPassManager.h"
2323 #include "llvm/IR/PassManager.h"
24 #include "llvm/IR/RemarkStreamer.h"
2425 #include "llvm/IR/Verifier.h"
2526 #include "llvm/LTO/LTO.h"
2627 #include "llvm/MC/SubtargetFeature.h"
3132 #include "llvm/Support/MemoryBuffer.h"
3233 #include "llvm/Support/Path.h"
3334 #include "llvm/Support/Program.h"
34 #include "llvm/Support/raw_ostream.h"
3535 #include "llvm/Support/TargetRegistry.h"
3636 #include "llvm/Support/ThreadPool.h"
37 #include "llvm/Support/raw_ostream.h"
3738 #include "llvm/Target/TargetMachine.h"
3839 #include "llvm/Transforms/IPO.h"
3940 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
3232 #include "llvm/IR/Mangler.h"
3333 #include "llvm/IR/Module.h"
3434 #include "llvm/IR/PassTimingInfo.h"
35 #include "llvm/IR/RemarkStreamer.h"
3536 #include "llvm/IR/Verifier.h"
3637 #include "llvm/InitializePasses.h"
3738 #include "llvm/LTO/LTO.h"
7980 #endif
8081 cl::Hidden);
8182
82 cl::opt
83 LTORemarksFilename("lto-pass-remarks-output",
84 cl::desc("Output filename for pass remarks"),
85 cl::value_desc("filename"));
86
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
93 cl::opt LTOPassRemarksWithHotness(
83 cl::opt RemarksWithHotness(
9484 "lto-pass-remarks-with-hotness",
9585 cl::desc("With PGO, include profile count in optimization remarks"),
9686 cl::Hidden);
87
88 cl::opt
89 RemarksFilename("lto-pass-remarks-output",
90 cl::desc("Output filename for pass remarks"),
91 cl::value_desc("filename"));
92
93 cl::opt
94 RemarksPasses("lto-pass-remarks-filter",
95 cl::desc("Only record optimization remarks from passes whose "
96 "names match the given regular expression"),
97 cl::value_desc("regex"));
9798
9899 cl::opt LTOStatsFile(
99100 "lto-stats-file",
516517 return false;
517518
518519 auto DiagFileOrErr = lto::setupOptimizationRemarks(
519 Context, LTORemarksFilename, LTORemarksPasses, LTOPassRemarksWithHotness);
520 Context, RemarksFilename, RemarksPasses, RemarksWithHotness);
520521 if (!DiagFileOrErr) {
521522 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
522523 report_fatal_error("Can't get an output file for the remarks");
2828 #include "llvm/IR/LegacyPassManager.h"
2929 #include "llvm/IR/Mangler.h"
3030 #include "llvm/IR/PassTimingInfo.h"
31 #include "llvm/IR/RemarkStreamer.h"
3132 #include "llvm/IR/Verifier.h"
3233 #include "llvm/IRReader/IRReader.h"
3334 #include "llvm/LTO/LTO.h"
6869 namespace llvm {
6970 // Flags -discard-value-names, defined in LTOCodeGenerator.cpp
7071 extern cl::opt LTODiscardValueNames;
71 extern cl::opt LTORemarksFilename;
72 extern cl::opt LTORemarksPasses;
73 extern cl::opt<bool> LTOPassRemarksWithHotness;
72 extern cl::opt<std::string> RemarksFilename;
73 extern cl::opt RemarksPasses;
74 extern cl::opt RemarksWithHotness;
7475 }
7576
7677 namespace {
10181019 Context.setDiscardValueNames(LTODiscardValueNames);
10191020 Context.enableDebugTypeODRUniquing();
10201021 auto DiagFileOrErr = lto::setupOptimizationRemarks(
1021 Context, LTORemarksFilename, LTORemarksPasses,
1022 LTOPassRemarksWithHotness, count);
1022 Context, RemarksFilename, RemarksPasses,
1023 RemarksWithHotness, count);
10231024 if (!DiagFileOrErr) {
10241025 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
10251026 report_fatal_error("ThinLTO: Can't get an output file for the "
205205 static std::string stats_file;
206206
207207 // Optimization remarks filename, accepted passes and hotness options
208 static std::string OptRemarksFilename;
209 static std::string OptRemarksFilter;
210 static bool OptRemarksWithHotness = false;
208 static std::string RemarksFilename;
209 static std::string RemarksPasses;
210 static bool RemarksWithHotness = false;
211211
212212 // Context sensitive PGO options.
213213 static std::string cs_profile_path;
284284 } else if (opt.startswith("dwo_dir=")) {
285285 dwo_dir = opt.substr(strlen("dwo_dir="));
286286 } else if (opt.startswith("opt-remarks-filename=")) {
287 OptRemarksFilename = opt.substr(strlen("opt-remarks-filename="));
287 RemarksFilename = opt.substr(strlen("opt-remarks-filename="));
288288 } else if (opt.startswith("opt-remarks-passes=")) {
289 OptRemarksFilter = opt.substr(strlen("opt-remarks-passes="));
289 RemarksPasses = opt.substr(strlen("opt-remarks-passes="));
290290 } else if (opt == "opt-remarks-with-hotness") {
291 OptRemarksWithHotness = true;
291 RemarksWithHotness = true;
292292 } else if (opt.startswith("stats-file=")) {
293293 stats_file = opt.substr(strlen("stats-file="));
294294 } else {
909909 Conf.DwoDir = options::dwo_dir;
910910
911911 // Set up optimization remarks handling.
912 Conf.RemarksFilename = options::OptRemarksFilename;
913 Conf.RemarksPasses = options::OptRemarksFilter;
914 Conf.RemarksWithHotness = options::OptRemarksWithHotness;
912 Conf.RemarksFilename = options::RemarksFilename;
913 Conf.RemarksPasses = options::RemarksPasses;
914 Conf.RemarksWithHotness = options::RemarksWithHotness;
915915
916916 // Use new pass manager if set in driver
917917 Conf.UseNewPM = options::new_pass_manager;
132132
133133 static cl::list IncludeDirs("I", cl::desc("include search path"));
134134
135 static cl::opt PassRemarksWithHotness(
135 static cl::opt RemarksWithHotness(
136136 "pass-remarks-with-hotness",
137137 cl::desc("With PGO, include profile count in optimization remarks"),
138138 cl::Hidden);
139139
140 static cl::opt PassRemarksHotnessThreshold(
141 "pass-remarks-hotness-threshold",
142 cl::desc("Minimum profile count required for an optimization remark to be output"),
143 cl::Hidden);
140 static cl::opt
141 RemarksHotnessThreshold("pass-remarks-hotness-threshold",
142 cl::desc("Minimum profile count required for "
143 "an optimization remark to be output"),
144 cl::Hidden);
144145
145146 static cl::opt
146147 RemarksFilename("pass-remarks-output",
147 cl::desc("YAML output filename for pass remarks"),
148 cl::desc("Output filename for pass remarks"),
148149 cl::value_desc("filename"));
149150
150151 static cl::opt
325326 llvm::make_unique(&HasError));
326327 Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
327328
328 if (PassRemarksWithHotness)
329 Context.setDiagnosticsHotnessRequested(true);
330
331 if (PassRemarksHotnessThreshold)
332 Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold);
333
334 std::unique_ptr YamlFile;
335 if (RemarksFilename != "") {
336 std::error_code EC;
337 YamlFile =
338 llvm::make_unique(RemarksFilename, EC, sys::fs::F_None);
339 if (EC) {
340 WithColor::error(errs(), argv[0]) << EC.message() << '\n';
341 return 1;
342 }
343 Context.setRemarkStreamer(llvm::make_unique(
344 RemarksFilename,
345 llvm::make_unique(YamlFile->os())));
346
347 if (!RemarksPasses.empty())
348 if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
349 WithColor::error(errs(), argv[0]) << E << '\n';
350 return 1;
351 }
352 }
329 Expected> RemarksFileOrErr =
330 setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
331 RemarksWithHotness, RemarksHotnessThreshold);
332 if (Error E = RemarksFileOrErr.takeError()) {
333 WithColor::error(errs(), argv[0]) << toString(std::move(E)) << '\n';
334 return 1;
335 }
336 std::unique_ptr RemarksFile = std::move(*RemarksFileOrErr);
353337
354338 if (InputLanguage != "" && InputLanguage != "ir" &&
355339 InputLanguage != "mir") {
364348 if (int RetVal = compileModule(argv, Context))
365349 return RetVal;
366350
367 if (YamlFile)
368 YamlFile->keep();
351 if (RemarksFile)
352 RemarksFile->keep();
369353 return 0;
370354 }
371355
9090 cl::desc(
9191 "Replace unspecified target triples in input files with this triple"));
9292
93 static cl::opt RemarksWithHotness(
94 "pass-remarks-with-hotness",
95 cl::desc("With PGO, include profile count in optimization remarks"),
96 cl::Hidden);
97
9398 static cl::opt
94 OptRemarksOutput("pass-remarks-output",
95 cl::desc("YAML output file for optimization remarks"));
96
97 static cl::opt OptRemarksWithHotness(
98 "pass-remarks-with-hotness",
99 cl::desc("Whether to include hotness informations in the remarks.\n"
100 "Has effect only if -pass-remarks-output is specified."));
99 RemarksFilename("pass-remarks-output",
100 cl::desc("Output filename for pass remarks"),
101 cl::value_desc("filename"));
101102
102103 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"));
104 RemarksPasses("pass-remarks-filter",
105 cl::desc("Only record optimization remarks from passes whose "
106 "names match the given regular expression"),
107 cl::value_desc("regex"));
107108
108109 static cl::opt
109110 SamplePGOFile("lto-sample-profile-file",
224225 "Config::addSaveTemps failed");
225226
226227 // Optimization remarks.
227 Conf.RemarksFilename = OptRemarksOutput;
228 Conf.RemarksPasses = OptRemarksPasses;
229 Conf.RemarksWithHotness = OptRemarksWithHotness;
228 Conf.RemarksFilename = RemarksFilename;
229 Conf.RemarksPasses = RemarksPasses;
230 Conf.RemarksWithHotness = RemarksWithHotness;
230231
231232 Conf.SampleProfile = SamplePGOFile;
232233 Conf.CSIRProfile = CSPGOFile;
250250 cl::desc("Enable coroutine passes."),
251251 cl::init(false), cl::Hidden);
252252
253 static cl::opt PassRemarksWithHotness(
253 static cl::opt RemarksWithHotness(
254254 "pass-remarks-with-hotness",
255255 cl::desc("With PGO, include profile count in optimization remarks"),
256256 cl::Hidden);
257257
258 static cl::opt PassRemarksHotnessThreshold(
259 "pass-remarks-hotness-threshold",
260 cl::desc("Minimum profile count required for an optimization remark to be output"),
261 cl::Hidden);
258 static cl::opt
259 RemarksHotnessThreshold("pass-remarks-hotness-threshold",
260 cl::desc("Minimum profile count required for "
261 "an optimization remark to be output"),
262 cl::Hidden);
262263
263264 static cl::opt
264265 RemarksFilename("pass-remarks-output",
265 cl::desc("YAML output filename for pass remarks"),
266 cl::desc("Output filename for pass remarks"),
266267 cl::value_desc("filename"));
267268
268269 static cl::opt
548549 if (!DisableDITypeMap)
549550 Context.enableDebugTypeODRUniquing();
550551
551 if (PassRemarksWithHotness)
552 Context.setDiagnosticsHotnessRequested(true);
553
554 if (PassRemarksHotnessThreshold)
555 Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold);
556
557 std::unique_ptr OptRemarkFile;
558 if (RemarksFilename != "") {
559 std::error_code EC;
560 OptRemarkFile =
561 llvm::make_unique(RemarksFilename, EC, sys::fs::F_None);
562 if (EC) {
563 errs() << EC.message() << '\n';
564 return 1;
565 }
566 Context.setRemarkStreamer(llvm::make_unique(
567 RemarksFilename,
568 llvm::make_unique(OptRemarkFile->os())));
569
570 if (!RemarksPasses.empty())
571 if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
572 errs() << E << '\n';
573 return 1;
574 }
575 }
552 Expected> RemarksFileOrErr =
553 setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
554 RemarksWithHotness, RemarksHotnessThreshold);
555 if (Error E = RemarksFileOrErr.takeError()) {
556 errs() << toString(std::move(E)) << '\n';
557 return 1;
558 }
559 std::unique_ptr RemarksFile = std::move(*RemarksFileOrErr);
576560
577561 // Load the input module...
578562 std::unique_ptr M =
686670 // string. Hand off the rest of the functionality to the new code for that
687671 // layer.
688672 return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(),
689 OptRemarkFile.get(), PassPipeline, OK, VK,
673 RemarksFile.get(), PassPipeline, OK, VK,
690674 PreserveAssemblyUseListOrder,
691675 PreserveBitcodeUseListOrder, EmitSummaryIndex,
692676 EmitModuleHash, EnableDebugify)
922906 "the compile-twice option\n";
923907 Out->os() << BOS->str();
924908 Out->keep();
925 if (OptRemarkFile)
926 OptRemarkFile->keep();
909 if (RemarksFile)
910 RemarksFile->keep();
927911 return 1;
928912 }
929913 Out->os() << BOS->str();
936920 if (!NoOutput || PrintBreakpoints)
937921 Out->keep();
938922
939 if (OptRemarkFile)
940 OptRemarkFile->keep();
923 if (RemarksFile)
924 RemarksFile->keep();
941925
942926 if (ThinLinkOut)
943927 ThinLinkOut->keep();