Skip to content

Commit 3acda91

Browse files
committed
[Remarks][1/2] Expand remarks hotness threshold option support in more tools
This is the #1 of 2 changes that make remarks hotness threshold option available in more tools. The changes also allow the threshold to sync with hotness threshold from profile summary with special value 'auto'. This change modifies the interface of lto::setupLLVMOptimizationRemarks() to accept remarks hotness threshold. Update all the tools that use it with remarks hotness threshold options: * lld: '--opt-remarks-hotness-threshold=' * llvm-lto2: '--pass-remarks-hotness-threshold=' * llvm-lto: '--lto-pass-remarks-hotness-threshold=' * gold plugin: '-plugin-opt=opt-remarks-hotness-threshold=' Differential Revision: https://reviews.llvm.org/D85809
1 parent bcc802f commit 3acda91

25 files changed

+288
-45
lines changed

lld/ELF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct Configuration {
111111
llvm::StringRef mapFile;
112112
llvm::StringRef outputFile;
113113
llvm::StringRef optRemarksFilename;
114+
llvm::Optional<uint64_t> optRemarksHotnessThreshold = 0;
114115
llvm::StringRef optRemarksPasses;
115116
llvm::StringRef optRemarksFormat;
116117
llvm::StringRef progName;

lld/ELF/Driver.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "llvm/ADT/StringExtras.h"
4949
#include "llvm/ADT/StringSwitch.h"
5050
#include "llvm/LTO/LTO.h"
51+
#include "llvm/Remarks/HotnessThresholdParser.h"
5152
#include "llvm/Support/CommandLine.h"
5253
#include "llvm/Support/Compression.h"
5354
#include "llvm/Support/GlobPattern.h"
@@ -1013,6 +1014,17 @@ static void readConfigs(opt::InputArgList &args) {
10131014
config->oFormatBinary = isOutputFormatBinary(args);
10141015
config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
10151016
config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
1017+
1018+
// Parse remarks hotness threshold. Valid value is either integer or 'auto'.
1019+
if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
1020+
auto resultOrErr = remarks::parseHotnessThresholdOption(arg->getValue());
1021+
if (!resultOrErr)
1022+
error(arg->getSpelling() + ": invalid argument '" + arg->getValue() +
1023+
"', only integer or 'auto' is supported");
1024+
else
1025+
config->optRemarksHotnessThreshold = *resultOrErr;
1026+
}
1027+
10161028
config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
10171029
config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
10181030
config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);

lld/ELF/LTO.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ static lto::Config createConfig() {
143143
c.RemarksFilename = std::string(config->optRemarksFilename);
144144
c.RemarksPasses = std::string(config->optRemarksPasses);
145145
c.RemarksWithHotness = config->optRemarksWithHotness;
146+
c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
146147
c.RemarksFormat = std::string(config->optRemarksFormat);
147148

148149
c.SampleProfile = std::string(config->ltoSampleProfile);

lld/ELF/Options.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,10 @@ def disable_verify: F<"disable-verify">;
548548
defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">;
549549
def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
550550
HelpText<"YAML output file for optimization remarks">;
551+
defm opt_remarks_hotness_threshold: EEq<"opt-remarks-hotness-threshold",
552+
"Minimum profile count required for an optimization remark to be output."
553+
" Use 'auto' to apply the threshold from profile summary.">,
554+
MetaVarName<"<value>">;
551555
def opt_remarks_passes: Separate<["--"], "opt-remarks-passes">,
552556
HelpText<"Regex for the passes that need to be serialized to the output file">;
553557
def opt_remarks_with_hotness: FF<"opt-remarks-with-hotness">,
@@ -596,6 +600,21 @@ def: J<"plugin-opt=cs-profile-path=">,
596600
def: J<"plugin-opt=obj-path=">,
597601
Alias<lto_obj_path_eq>,
598602
HelpText<"Alias for --lto-obj-path=">;
603+
def: J<"plugin-opt=opt-remarks-filename=">,
604+
Alias<opt_remarks_filename>,
605+
HelpText<"Alias for --opt-remarks-filename">;
606+
def: J<"plugin-opt=opt-remarks-passes=">,
607+
Alias<opt_remarks_passes>,
608+
HelpText<"Alias for --opt-remarks-passes">;
609+
def: J<"plugin-opt=opt-remarks-format=">,
610+
Alias<opt_remarks_format>,
611+
HelpText<"Alias for --opt-remarks-format">;
612+
def: F<"plugin-opt=opt-remarks-with-hotness">,
613+
Alias<opt_remarks_with_hotness>,
614+
HelpText<"Alias for --opt-remarks-with_hotness">;
615+
def: J<"plugin-opt=opt-remarks-hotness-threshold=">,
616+
Alias<opt_remarks_hotness_threshold>,
617+
HelpText<"Alias for --opt-remarks-hotness-threshold">;
599618
def: J<"plugin-opt=sample-profile=">,
600619
Alias<lto_sample_profile>, HelpText<"Alias for --lto-sample-profile">;
601620
def: F<"plugin-opt=save-temps">, Alias<save_temps>, HelpText<"Alias for --save-temps">;

lld/test/ELF/lto/opt-remarks.ll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
; REQUIRES: x86
22
; RUN: llvm-as %s -o %t.o
33

4-
; RUN: rm -f %t.yaml
4+
; RUN: rm -f %t.yaml %t1.yaml %t.hot.yaml %t.t300.yaml %t.t301.yaml
55
; RUN: ld.lld --opt-remarks-filename %t.yaml %t.o -o %t -shared -save-temps
66
; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s
77
; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-filename %t.hot.yaml \
88
; RUN: %t.o -o %t -shared
9+
; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-hotness-threshold=300 \
10+
; RUN: --opt-remarks-filename %t.t300.yaml %t.o -o %t -shared
11+
; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-hotness-threshold=301 \
12+
; RUN: --opt-remarks-filename %t.t301.yaml %t.o -o %t -shared
913
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
1014
; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
15+
; RUN: FileCheck %s -check-prefix=YAML-HOT < %t.t300.yaml
16+
; RUN: count 0 < %t.t301.yaml
1117
; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-passes inline %t.o \
1218
; RUN: -o /dev/null -shared
1319
; RUN: cat %t1.yaml | FileCheck %s -check-prefix=YAML-PASSES
1420
; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-format yaml %t.o \
1521
; RUN: -o /dev/null -shared
16-
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
22+
; RUN: FileCheck %s -check-prefix=YAML < %t1.yaml
1723

1824
; Check that @tinkywinky is inlined after optimizations.
1925
; CHECK-LABEL: define i32 @main

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,20 @@ class LLVMContext {
222222
void setDiagnosticsHotnessRequested(bool Requested);
223223

224224
/// Return the minimum hotness value a diagnostic would need in order
225-
/// to be included in optimization diagnostics. If there is no minimum, this
226-
/// returns None.
225+
/// to be included in optimization diagnostics.
226+
///
227+
/// Three possible return values:
228+
/// 0 - threshold is disabled. Everything will be printed out.
229+
/// positive int - threshold is set.
230+
/// UINT64_MAX - threshold is not yet set, and needs to be synced from
231+
/// profile summary. Note that in case of missing profile
232+
/// summary, threshold will be kept at "MAX", effectively
233+
/// suppresses all remarks output.
227234
uint64_t getDiagnosticsHotnessThreshold() const;
228235

229236
/// Set the minimum hotness value a diagnostic needs in order to be
230237
/// included in optimization diagnostics.
231-
void setDiagnosticsHotnessThreshold(uint64_t Threshold);
238+
void setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold);
232239

233240
/// The "main remark streamer" used by all the specialized remark streamers.
234241
/// This streamer keeps generic remark metadata in memory throughout the life

llvm/include/llvm/IR/LLVMRemarkStreamer.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,15 @@ Expected<std::unique_ptr<ToolOutputFile>>
7979
setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
8080
StringRef RemarksPasses, StringRef RemarksFormat,
8181
bool RemarksWithHotness,
82-
unsigned RemarksHotnessThreshold = 0);
82+
Optional<uint64_t> RemarksHotnessThreshold = 0);
8383

8484
/// Setup optimization remarks that output directly to a raw_ostream.
8585
/// \p OS is managed by the caller and should be open for writing as long as \p
8686
/// Context is streaming remarks to it.
87-
Error setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
88-
StringRef RemarksPasses,
89-
StringRef RemarksFormat,
90-
bool RemarksWithHotness,
91-
unsigned RemarksHotnessThreshold = 0);
87+
Error setupLLVMOptimizationRemarks(
88+
LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
89+
StringRef RemarksFormat, bool RemarksWithHotness,
90+
Optional<uint64_t> RemarksHotnessThreshold = 0);
9291

9392
} // end namespace llvm
9493

llvm/include/llvm/LTO/Config.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ struct Config {
121121
/// Whether to emit optimization remarks with hotness informations.
122122
bool RemarksWithHotness = false;
123123

124+
/// The minimum hotness value a diagnostic needs in order to be included in
125+
/// optimization diagnostics.
126+
///
127+
/// The threshold is an Optional value, which maps to one of the 3 states:
128+
/// 1. 0 => threshold disabled. All emarks will be printed.
129+
/// 2. positive int => manual threshold by user. Remarks with hotness exceed
130+
/// threshold will be printed.
131+
/// 3. None => 'auto' threshold by user. The actual value is not
132+
/// available at command line, but will be synced with
133+
/// hotness threhold from profile summary during
134+
/// compilation.
135+
///
136+
/// If threshold option is not specified, it is disabled by default.
137+
llvm::Optional<uint64_t> RemarksHotnessThreshold = 0;
138+
124139
/// The format used for serializing remarks (default: YAML).
125140
std::string RemarksFormat = "";
126141

llvm/include/llvm/LTO/LTO.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ std::string getThinLTOOutputFile(const std::string &Path,
8282
const std::string &NewPrefix);
8383

8484
/// Setup optimization remarks.
85-
Expected<std::unique_ptr<ToolOutputFile>>
86-
setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
87-
StringRef RemarksPasses, StringRef RemarksFormat,
88-
bool RemarksWithHotness, int Count = -1);
85+
Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks(
86+
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
87+
StringRef RemarksFormat, bool RemarksWithHotness,
88+
Optional<uint64_t> RemarksHotnessThreshold = 0, int Count = -1);
8989

9090
/// Setups the output file for saving statistics.
9191
Expected<std::unique_ptr<ToolOutputFile>>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===- HotnessThresholdParser.h - Parser for hotness threshold --*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file implements a simple parser to decode commandline option for
11+
/// remarks hotness threshold that supports both int and a special 'auto' value.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
16+
#define LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
17+
18+
#include "llvm/ADT/Optional.h"
19+
#include "llvm/Support/CommandLine.h"
20+
21+
namespace llvm {
22+
namespace remarks {
23+
24+
// Parse remarks hotness threshold argument value.
25+
// Valid option values are
26+
// 1. integer: manually specified threshold; or
27+
// 2. string 'auto': automatically get threshold from profile summary.
28+
//
29+
// Return None Optional if 'auto' is specified, indicating the value will
30+
// be filled later during PSI.
31+
inline Expected<Optional<uint64_t>> parseHotnessThresholdOption(StringRef Arg) {
32+
if (Arg == "auto")
33+
return None;
34+
35+
int64_t Val;
36+
if (Arg.getAsInteger(10, Val))
37+
return createStringError(llvm::inconvertibleErrorCode(),
38+
"Not an integer: %s", Arg.data());
39+
40+
// Negative integer effectively means no threshold
41+
return Val < 0 ? 0 : Val;
42+
}
43+
44+
// A simple CL parser for '*-remarks-hotness-threshold='
45+
class HotnessThresholdParser : public cl::parser<Optional<uint64_t>> {
46+
public:
47+
HotnessThresholdParser(cl::Option &O) : cl::parser<Optional<uint64_t>>(O) {}
48+
49+
bool parse(cl::Option &O, StringRef ArgName, StringRef Arg,
50+
Optional<uint64_t> &V) {
51+
auto ResultOrErr = parseHotnessThresholdOption(Arg);
52+
if (!ResultOrErr)
53+
return O.error("Invalid argument '" + Arg +
54+
"', only integer or 'auto' is supported.");
55+
56+
V = *ResultOrErr;
57+
return false;
58+
}
59+
};
60+
61+
} // namespace remarks
62+
} // namespace llvm
63+
#endif // LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H

llvm/include/llvm/Support/CommandLine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,7 @@ class opt : public Option,
14811481

14821482
template <class... Mods>
14831483
explicit opt(const Mods &... Ms)
1484-
: Option(Optional, NotHidden), Parser(*this) {
1484+
: Option(llvm::cl::Optional, NotHidden), Parser(*this) {
14851485
apply(this, Ms...);
14861486
done();
14871487
}

llvm/lib/IR/LLVMContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ bool LLVMContext::getDiagnosticsHotnessRequested() const {
146146
return pImpl->DiagnosticsHotnessRequested;
147147
}
148148

149-
void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
149+
void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
150150
pImpl->DiagnosticsHotnessThreshold = Threshold;
151151
}
152152
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
153-
return pImpl->DiagnosticsHotnessThreshold;
153+
return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
154154
}
155155

156156
remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {

llvm/lib/IR/LLVMContextImpl.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,26 @@ class LLVMContextImpl {
13231323
std::unique_ptr<DiagnosticHandler> DiagHandler;
13241324
bool RespectDiagnosticFilters = false;
13251325
bool DiagnosticsHotnessRequested = false;
1326-
uint64_t DiagnosticsHotnessThreshold = 0;
1326+
/// The minimum hotness value a diagnostic needs in order to be included in
1327+
/// optimization diagnostics.
1328+
///
1329+
/// The threshold is an Optional value, which maps to one of the 3 states:
1330+
/// 1). 0 => threshold disabled. All emarks will be printed.
1331+
/// 2). positive int => manual threshold by user. Remarks with hotness exceed
1332+
/// threshold will be printed.
1333+
/// 3). None => 'auto' threshold by user. The actual value is not
1334+
/// available at command line, but will be synced with
1335+
/// hotness threhold from profile summary during
1336+
/// compilation.
1337+
///
1338+
/// State 1 and 2 are considered as terminal states. State transition is
1339+
/// only allowed from 3 to 2, when the threshold is first synced with profile
1340+
/// summary. This ensures that the threshold is set only once and stays
1341+
/// constant.
1342+
///
1343+
/// If threshold option is not specified, it is disabled (0) by default.
1344+
Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1345+
13271346
/// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
13281347
std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
13291348

llvm/lib/IR/LLVMRemarkStreamer.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ char LLVMRemarkSetupFormatError::ID = 0;
9292
Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
9393
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
9494
StringRef RemarksFormat, bool RemarksWithHotness,
95-
unsigned RemarksHotnessThreshold) {
95+
Optional<uint64_t> RemarksHotnessThreshold) {
9696
if (RemarksWithHotness)
9797
Context.setDiagnosticsHotnessRequested(true);
9898

@@ -137,11 +137,10 @@ Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
137137
return std::move(RemarksFile);
138138
}
139139

140-
Error llvm::setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
141-
StringRef RemarksPasses,
142-
StringRef RemarksFormat,
143-
bool RemarksWithHotness,
144-
unsigned RemarksHotnessThreshold) {
140+
Error llvm::setupLLVMOptimizationRemarks(
141+
LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
142+
StringRef RemarksFormat, bool RemarksWithHotness,
143+
Optional<uint64_t> RemarksHotnessThreshold) {
145144
if (RemarksWithHotness)
146145
Context.setDiagnosticsHotnessRequested(true);
147146

llvm/lib/LTO/LTO.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,8 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
983983
// Setup optimization remarks.
984984
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
985985
RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,
986-
Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness);
986+
Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness,
987+
Conf.RemarksHotnessThreshold);
987988
if (!DiagFileOrErr)
988989
return DiagFileOrErr.takeError();
989990

@@ -1488,7 +1489,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
14881489

14891490
Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(
14901491
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
1491-
StringRef RemarksFormat, bool RemarksWithHotness, int Count) {
1492+
StringRef RemarksFormat, bool RemarksWithHotness,
1493+
Optional<uint64_t> RemarksHotnessThreshold, int Count) {
14921494
std::string Filename = std::string(RemarksFilename);
14931495
// For ThinLTO, file.opt.<format> becomes
14941496
// file.opt.<format>.thin.<num>.<format>.
@@ -1498,7 +1500,8 @@ Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(
14981500
.str();
14991501

15001502
auto ResultOrErr = llvm::setupLLVMOptimizationRemarks(
1501-
Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness);
1503+
Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness,
1504+
RemarksHotnessThreshold);
15021505
if (Error E = ResultOrErr.takeError())
15031506
return std::move(E);
15041507

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,8 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
574574
// Setup optimization remarks.
575575
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
576576
Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
577-
Conf.RemarksFormat, Conf.RemarksWithHotness, Task);
577+
Conf.RemarksFormat, Conf.RemarksWithHotness, Conf.RemarksHotnessThreshold,
578+
Task);
578579
if (!DiagFileOrErr)
579580
return DiagFileOrErr.takeError();
580581
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);

0 commit comments

Comments
 (0)