llvm::StringRef mapFile;
llvm::StringRef outputFile;
llvm::StringRef optRemarksFilename;
+ llvm::Optional<uint64_t> optRemarksHotnessThreshold = 0;
llvm::StringRef optRemarksPasses;
llvm::StringRef optRemarksFormat;
llvm::StringRef progName;
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/LTO/LTO.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/GlobPattern.h"
config->oFormatBinary = isOutputFormatBinary(args);
config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
+
+ // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
+ if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
+ auto resultOrErr = remarks::parseHotnessThresholdOption(arg->getValue());
+ if (!resultOrErr)
+ error(arg->getSpelling() + ": invalid argument '" + arg->getValue() +
+ "', only integer or 'auto' is supported");
+ else
+ config->optRemarksHotnessThreshold = *resultOrErr;
+ }
+
config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
c.RemarksFilename = std::string(config->optRemarksFilename);
c.RemarksPasses = std::string(config->optRemarksPasses);
c.RemarksWithHotness = config->optRemarksWithHotness;
+ c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
c.RemarksFormat = std::string(config->optRemarksFormat);
c.SampleProfile = std::string(config->ltoSampleProfile);
defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">;
def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
HelpText<"YAML output file for optimization remarks">;
+defm opt_remarks_hotness_threshold: EEq<"opt-remarks-hotness-threshold",
+ "Minimum profile count required for an optimization remark to be output."
+ " Use 'auto' to apply the threshold from profile summary.">,
+ MetaVarName<"<value>">;
def opt_remarks_passes: Separate<["--"], "opt-remarks-passes">,
HelpText<"Regex for the passes that need to be serialized to the output file">;
def opt_remarks_with_hotness: FF<"opt-remarks-with-hotness">,
def: J<"plugin-opt=obj-path=">,
Alias<lto_obj_path_eq>,
HelpText<"Alias for --lto-obj-path=">;
+def: J<"plugin-opt=opt-remarks-filename=">,
+ Alias<opt_remarks_filename>,
+ HelpText<"Alias for --opt-remarks-filename">;
+def: J<"plugin-opt=opt-remarks-passes=">,
+ Alias<opt_remarks_passes>,
+ HelpText<"Alias for --opt-remarks-passes">;
+def: J<"plugin-opt=opt-remarks-format=">,
+ Alias<opt_remarks_format>,
+ HelpText<"Alias for --opt-remarks-format">;
+def: F<"plugin-opt=opt-remarks-with-hotness">,
+ Alias<opt_remarks_with_hotness>,
+ HelpText<"Alias for --opt-remarks-with_hotness">;
+def: J<"plugin-opt=opt-remarks-hotness-threshold=">,
+ Alias<opt_remarks_hotness_threshold>,
+ HelpText<"Alias for --opt-remarks-hotness-threshold">;
def: J<"plugin-opt=sample-profile=">,
Alias<lto_sample_profile>, HelpText<"Alias for --lto-sample-profile">;
def: F<"plugin-opt=save-temps">, Alias<save_temps>, HelpText<"Alias for --save-temps">;
; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
-; RUN: rm -f %t.yaml
+; RUN: rm -f %t.yaml %t1.yaml %t.hot.yaml %t.t300.yaml %t.t301.yaml
; RUN: ld.lld --opt-remarks-filename %t.yaml %t.o -o %t -shared -save-temps
; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s
; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-filename %t.hot.yaml \
; RUN: %t.o -o %t -shared
+; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-hotness-threshold=300 \
+; RUN: --opt-remarks-filename %t.t300.yaml %t.o -o %t -shared
+; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-hotness-threshold=301 \
+; RUN: --opt-remarks-filename %t.t301.yaml %t.o -o %t -shared
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
+; RUN: FileCheck %s -check-prefix=YAML-HOT < %t.t300.yaml
+; RUN: count 0 < %t.t301.yaml
; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-passes inline %t.o \
; RUN: -o /dev/null -shared
; RUN: cat %t1.yaml | FileCheck %s -check-prefix=YAML-PASSES
; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-format yaml %t.o \
; RUN: -o /dev/null -shared
-; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
+; RUN: FileCheck %s -check-prefix=YAML < %t1.yaml
; Check that @tinkywinky is inlined after optimizations.
; CHECK-LABEL: define i32 @main
void setDiagnosticsHotnessRequested(bool Requested);
/// Return the minimum hotness value a diagnostic would need in order
- /// to be included in optimization diagnostics. If there is no minimum, this
- /// returns None.
+ /// to be included in optimization diagnostics.
+ ///
+ /// Three possible return values:
+ /// 0 - threshold is disabled. Everything will be printed out.
+ /// positive int - threshold is set.
+ /// UINT64_MAX - threshold is not yet set, and needs to be synced from
+ /// profile summary. Note that in case of missing profile
+ /// summary, threshold will be kept at "MAX", effectively
+ /// suppresses all remarks output.
uint64_t getDiagnosticsHotnessThreshold() const;
/// Set the minimum hotness value a diagnostic needs in order to be
/// included in optimization diagnostics.
- void setDiagnosticsHotnessThreshold(uint64_t Threshold);
+ void setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold);
/// The "main remark streamer" used by all the specialized remark streamers.
/// This streamer keeps generic remark metadata in memory throughout the life
setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef RemarksPasses, StringRef RemarksFormat,
bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold = 0);
+ Optional<uint64_t> RemarksHotnessThreshold = 0);
/// Setup optimization remarks that output directly to a raw_ostream.
/// \p OS is managed by the caller and should be open for writing as long as \p
/// Context is streaming remarks to it.
-Error setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
- StringRef RemarksPasses,
- StringRef RemarksFormat,
- bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold = 0);
+Error setupLLVMOptimizationRemarks(
+ LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold = 0);
} // end namespace llvm
/// Whether to emit optimization remarks with hotness informations.
bool RemarksWithHotness = false;
+ /// The minimum hotness value a diagnostic needs in order to be included in
+ /// optimization diagnostics.
+ ///
+ /// The threshold is an Optional value, which maps to one of the 3 states:
+ /// 1. 0 => threshold disabled. All emarks will be printed.
+ /// 2. positive int => manual threshold by user. Remarks with hotness exceed
+ /// threshold will be printed.
+ /// 3. None => 'auto' threshold by user. The actual value is not
+ /// available at command line, but will be synced with
+ /// hotness threhold from profile summary during
+ /// compilation.
+ ///
+ /// If threshold option is not specified, it is disabled by default.
+ llvm::Optional<uint64_t> RemarksHotnessThreshold = 0;
+
/// The format used for serializing remarks (default: YAML).
std::string RemarksFormat = "";
const std::string &NewPrefix);
/// Setup optimization remarks.
-Expected<std::unique_ptr<ToolOutputFile>>
-setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, StringRef RemarksFormat,
- bool RemarksWithHotness, int Count = -1);
+Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks(
+ LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold = 0, int Count = -1);
/// Setups the output file for saving statistics.
Expected<std::unique_ptr<ToolOutputFile>>
--- /dev/null
+//===- HotnessThresholdParser.h - Parser for hotness threshold --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements a simple parser to decode commandline option for
+/// remarks hotness threshold that supports both int and a special 'auto' value.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
+#define LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+namespace remarks {
+
+// Parse remarks hotness threshold argument value.
+// Valid option values are
+// 1. integer: manually specified threshold; or
+// 2. string 'auto': automatically get threshold from profile summary.
+//
+// Return None Optional if 'auto' is specified, indicating the value will
+// be filled later during PSI.
+inline Expected<Optional<uint64_t>> parseHotnessThresholdOption(StringRef Arg) {
+ if (Arg == "auto")
+ return None;
+
+ int64_t Val;
+ if (Arg.getAsInteger(10, Val))
+ return createStringError(llvm::inconvertibleErrorCode(),
+ "Not an integer: %s", Arg.data());
+
+ // Negative integer effectively means no threshold
+ return Val < 0 ? 0 : Val;
+}
+
+// A simple CL parser for '*-remarks-hotness-threshold='
+class HotnessThresholdParser : public cl::parser<Optional<uint64_t>> {
+public:
+ HotnessThresholdParser(cl::Option &O) : cl::parser<Optional<uint64_t>>(O) {}
+
+ bool parse(cl::Option &O, StringRef ArgName, StringRef Arg,
+ Optional<uint64_t> &V) {
+ auto ResultOrErr = parseHotnessThresholdOption(Arg);
+ if (!ResultOrErr)
+ return O.error("Invalid argument '" + Arg +
+ "', only integer or 'auto' is supported.");
+
+ V = *ResultOrErr;
+ return false;
+ }
+};
+
+} // namespace remarks
+} // namespace llvm
+#endif // LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
template <class... Mods>
explicit opt(const Mods &... Ms)
- : Option(Optional, NotHidden), Parser(*this) {
+ : Option(llvm::cl::Optional, NotHidden), Parser(*this) {
apply(this, Ms...);
done();
}
return pImpl->DiagnosticsHotnessRequested;
}
-void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
+void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
pImpl->DiagnosticsHotnessThreshold = Threshold;
}
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
- return pImpl->DiagnosticsHotnessThreshold;
+ return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
}
remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
std::unique_ptr<DiagnosticHandler> DiagHandler;
bool RespectDiagnosticFilters = false;
bool DiagnosticsHotnessRequested = false;
- uint64_t DiagnosticsHotnessThreshold = 0;
+ /// The minimum hotness value a diagnostic needs in order to be included in
+ /// optimization diagnostics.
+ ///
+ /// The threshold is an Optional value, which maps to one of the 3 states:
+ /// 1). 0 => threshold disabled. All emarks will be printed.
+ /// 2). positive int => manual threshold by user. Remarks with hotness exceed
+ /// threshold will be printed.
+ /// 3). None => 'auto' threshold by user. The actual value is not
+ /// available at command line, but will be synced with
+ /// hotness threhold from profile summary during
+ /// compilation.
+ ///
+ /// State 1 and 2 are considered as terminal states. State transition is
+ /// only allowed from 3 to 2, when the threshold is first synced with profile
+ /// summary. This ensures that the threshold is set only once and stays
+ /// constant.
+ ///
+ /// If threshold option is not specified, it is disabled (0) by default.
+ Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
+
/// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
StringRef RemarksFormat, bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold) {
+ Optional<uint64_t> RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
return std::move(RemarksFile);
}
-Error llvm::setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
- StringRef RemarksPasses,
- StringRef RemarksFormat,
- bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold) {
+Error llvm::setupLLVMOptimizationRemarks(
+ LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
// Setup optimization remarks.
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,
- Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness);
+ Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness,
+ Conf.RemarksHotnessThreshold);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
- StringRef RemarksFormat, bool RemarksWithHotness, int Count) {
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold, int Count) {
std::string Filename = std::string(RemarksFilename);
// For ThinLTO, file.opt.<format> becomes
// file.opt.<format>.thin.<num>.<format>.
.str();
auto ResultOrErr = llvm::setupLLVMOptimizationRemarks(
- Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness);
+ Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness,
+ RemarksHotnessThreshold);
if (Error E = ResultOrErr.takeError())
return std::move(E);
// Setup optimization remarks.
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
- Conf.RemarksFormat, Conf.RemarksWithHotness, Task);
+ Conf.RemarksFormat, Conf.RemarksWithHotness, Conf.RemarksHotnessThreshold,
+ Task);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden);
+cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold(
+ "lto-pass-remarks-hotness-threshold",
+ cl::desc("Minimum profile count required for an "
+ "optimization remark to be output."
+ " Use 'auto' to apply the threshold from profile summary."),
+ cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);
+
cl::opt<std::string>
RemarksFilename("lto-pass-remarks-output",
cl::desc("Output filename for pass remarks"),
if (!this->determineTarget())
return false;
- auto DiagFileOrErr =
- lto::setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
- RemarksFormat, RemarksWithHotness);
+ auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
+ Context, RemarksFilename, RemarksPasses, RemarksFormat,
+ RemarksWithHotness, RemarksHotnessThreshold);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("Can't get an output file for the remarks");
#include "llvm/LTO/SummaryBasedOptimizations.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
extern cl::opt<std::string> RemarksFilename;
extern cl::opt<std::string> RemarksPasses;
extern cl::opt<bool> RemarksWithHotness;
+extern cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold;
extern cl::opt<std::string> RemarksFormat;
}
Context.enableDebugTypeODRUniquing();
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
Context, RemarksFilename, RemarksPasses, RemarksFormat,
- RemarksWithHotness, count);
+ RemarksWithHotness, RemarksHotnessThreshold, count);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("ThinLTO: Can't get an output file for the "
; RUN: -r %t.bc,main,px -o %t.o %t.bc
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
+; Check low threshold allows remarks to emit.
+; RUN: rm -f %t.t300.yaml
+; RUN: llvm-lto2 run -pass-remarks-output=%t.t300.yaml \
+; RUN: -pass-remarks-with-hotness \
+; RUN: -pass-remarks-hotness-threshold=300 \
+; RUN: -r %t.bc,tinkywinky,p \
+; RUN: -r %t.bc,patatino,px \
+; RUN: -r %t.bc,main,px -o %t.o %t.bc
+; RUN: FileCheck %s -check-prefix=YAML < %t.t300.yaml
+
+; Check high threshold disallows remarks to emit.
+; RUN: rm -f %t.t301.yaml
+; RUN: llvm-lto2 run -pass-remarks-output=%t.t301.yaml \
+; RUN: -pass-remarks-with-hotness \
+; RUN: -pass-remarks-hotness-threshold=301 \
+; RUN: -r %t.bc,tinkywinky,p \
+; RUN: -r %t.bc,patatino,px \
+; RUN: -r %t.bc,main,px -o %t.o %t.bc
+; RUN: count 0 < %t.t301.yaml
+
; Check pass remarks emitted to stderr
; RUN: llvm-lto2 run -pass-remarks=inline \
; RUN: -pass-remarks-with-hotness \
; RUN: -r %t.bc,patatino,px \
; RUN: -r %t.bc,main,px -o %t.o %t.bc 2>&1 | FileCheck %s
+; Check low threshold allows remarks to emit.
+; RUN: llvm-lto2 run -pass-remarks=inline \
+; RUN: -pass-remarks-with-hotness \
+; RUN: -pass-remarks-hotness-threshold=300 \
+; RUN: -r %t.bc,tinkywinky,p \
+; RUN: -r %t.bc,patatino,px \
+; RUN: -r %t.bc,main,px -o %t.o %t.bc 2>&1 | FileCheck %s
+
+; Check high threshold disallows remarks to emit.
+; RUN: llvm-lto2 run -pass-remarks=inline \
+; RUN: -pass-remarks-with-hotness \
+; RUN: -pass-remarks-hotness-threshold=301 \
+; RUN: -r %t.bc,tinkywinky,p \
+; RUN: -r %t.bc,patatino,px \
+; RUN: -r %t.bc,main,px -o %t.o %t.bc 2>&1 | count 0
+
; YAML: --- !Passed
; YAML-NEXT: Pass: inline
; YAML-NEXT: Name: Inlined
; with -lto-pass-remarks-with-hotness.
; RUN: llvm-as < %s >%t.bc
-; RUN: rm -f %t.yaml
+; RUN: rm -f %t.yaml %t.t300.yaml %t.t301.yaml
; RUN: llvm-lto -lto-pass-remarks-output=%t.yaml \
; RUN: -lto-pass-remarks-with-hotness \
; RUN: -exported-symbol _main -o %t.o %t.bc
; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
+; RUN: llvm-lto -lto-pass-remarks-output=%t.t300.yaml \
+; RUN: -lto-pass-remarks-with-hotness \
+; RUN: -lto-pass-remarks-hotness-threshold=300 \
+; RUN: -exported-symbol _main -o %t.o %t.bc
+; RUN: FileCheck -check-prefix=YAML %s < %t.t300.yaml
+
+; RUN: llvm-lto -lto-pass-remarks-output=%t.t301.yaml \
+; RUN: -lto-pass-remarks-with-hotness \
+; RUN: -lto-pass-remarks-hotness-threshold=301 \
+; RUN: -exported-symbol _main -o %t.o %t.bc
+; RUN: not FileCheck -check-prefix=YAML %s < %t.t301.yaml
+
; YAML: --- !Passed
; YAML-NEXT: Pass: inline
; YAML-NEXT: Name: Inlined
; RUN: -plugin-opt=opt-remarks-format=yaml \
; RUN: -plugin-opt=opt-remarks-with-hotness \
; RUN: -plugin-opt=opt-remarks-filename=%t.hot.yaml %t.o -o %t2.o 2>&1
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext -shared \
+; RUN: -plugin-opt=opt-remarks-passes=inline \
+; RUN: -plugin-opt=opt-remarks-format=yaml \
+; RUN: -plugin-opt=opt-remarks-with-hotness \
+; RUN: -plugin-opt=opt-remarks-hotness-threshold=300 \
+; RUN: -plugin-opt=opt-remarks-filename=%t.t300.yaml %t.o -o %t2.o 2>&1
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext -shared \
+; RUN: -plugin-opt=opt-remarks-passes=inline \
+; RUN: -plugin-opt=opt-remarks-format=yaml \
+; RUN: -plugin-opt=opt-remarks-with-hotness \
+; RUN: -plugin-opt=opt-remarks-hotness-threshold=301 \
+; RUN: -plugin-opt=opt-remarks-filename=%t.t301.yaml %t.o -o %t2.o 2>&1
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
+; RUN: FileCheck %s -check-prefix=YAML-HOT < %t.t300.yaml
+; RUN: count 0 < %t.t301.yaml
; Check that @f is inlined after optimizations.
; CHECK-LABEL: define i32 @_start
; YAML-NEXT: - String: ')'
; YAML-NEXT: ...
-; YAML-HOT: ...
; YAML-HOT: --- !Passed
; YAML-HOT: Pass: inline
; YAML-HOT-NEXT: Name: Inlined
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/Error.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
static std::string RemarksFilename;
static std::string RemarksPasses;
static bool RemarksWithHotness = false;
+ static Optional<uint64_t> RemarksHotnessThreshold = 0;
static std::string RemarksFormat;
// Context sensitive PGO options.
RemarksPasses = std::string(opt);
} else if (opt == "opt-remarks-with-hotness") {
RemarksWithHotness = true;
+ } else if (opt.consume_front("opt-remarks-hotness-threshold=")) {
+ auto ResultOrErr = remarks::parseHotnessThresholdOption(opt);
+ if (!ResultOrErr)
+ message(LDPL_FATAL, "Invalid remarks hotness threshold: %s", opt);
+ else
+ RemarksHotnessThreshold = *ResultOrErr;
} else if (opt.consume_front("opt-remarks-format=")) {
RemarksFormat = std::string(opt);
} else if (opt.consume_front("stats-file=")) {
Conf.RemarksFilename = options::RemarksFilename;
Conf.RemarksPasses = options::RemarksPasses;
Conf.RemarksWithHotness = options::RemarksWithHotness;
+ Conf.RemarksHotnessThreshold = options::RemarksHotnessThreshold;
Conf.RemarksFormat = options::RemarksFormat;
// Use new pass manager if set in driver
#include "llvm/InitializePasses.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Pass.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden);
-static cl::opt<unsigned>
- RemarksHotnessThreshold("pass-remarks-hotness-threshold",
- cl::desc("Minimum profile count required for "
- "an optimization remark to be output"),
- cl::Hidden);
+static cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold(
+ "pass-remarks-hotness-threshold",
+ cl::desc("Minimum profile count required for "
+ "an optimization remark to be output. "
+ "Use 'auto' to apply the threshold from profile summary."),
+ cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden);
static cl::opt<std::string>
RemarksFilename("pass-remarks-output",
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden);
+cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold(
+ "pass-remarks-hotness-threshold",
+ cl::desc("Minimum profile count required for an "
+ "optimization remark to be output."
+ " Use 'auto' to apply the threshold from profile summary."),
+ cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);
+
static cl::opt<std::string>
RemarksFilename("pass-remarks-output",
cl::desc("Output filename for pass remarks"),
Conf.RemarksFilename = RemarksFilename;
Conf.RemarksPasses = RemarksPasses;
Conf.RemarksWithHotness = RemarksWithHotness;
+ Conf.RemarksHotnessThreshold = RemarksHotnessThreshold;
Conf.RemarksFormat = RemarksFormat;
Conf.SampleProfile = SamplePGOFile;
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden);
-static cl::opt<unsigned>
- RemarksHotnessThreshold("pass-remarks-hotness-threshold",
- cl::desc("Minimum profile count required for "
- "an optimization remark to be output"),
- cl::Hidden);
+static cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
+ RemarksHotnessThreshold(
+ "pass-remarks-hotness-threshold",
+ cl::desc("Minimum profile count required for "
+ "an optimization remark to be output. "
+ "Use 'auto' to apply the threshold from profile summary."),
+ cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden);
static cl::opt<std::string>
RemarksFilename("pass-remarks-output",