Index: llvm/trunk/include/llvm/LTO/Config.h =================================================================== --- llvm/trunk/include/llvm/LTO/Config.h +++ llvm/trunk/include/llvm/LTO/Config.h @@ -79,6 +79,10 @@ /// 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. + unsigned RemarksHotnessThreshold = 0; + /// Whether to emit the pass manager debuggging informations. bool DebugPassManager = false; Index: llvm/trunk/include/llvm/LTO/LTO.h =================================================================== --- llvm/trunk/include/llvm/LTO/LTO.h +++ llvm/trunk/include/llvm/LTO/LTO.h @@ -73,7 +73,9 @@ /// Setup optimization remarks. Expected> setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename, - bool LTOPassRemarksWithHotness, int Count = -1); + bool LTOPassRemarksWithHotness, + unsigned LTOPassRemarksHotnessThreshold, + int Count = -1); class LTO; struct SymbolResolution; Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -1202,10 +1202,10 @@ return BackendProc->wait(); } -Expected> -lto::setupOptimizationRemarks(LLVMContext &Context, - StringRef LTORemarksFilename, - bool LTOPassRemarksWithHotness, int Count) { +Expected> lto::setupOptimizationRemarks( + LLVMContext &Context, StringRef LTORemarksFilename, + bool LTOPassRemarksWithHotness, unsigned LTOPassRemarksHotnessThreshold, + int Count) { if (LTORemarksFilename.empty()) return nullptr; @@ -1222,6 +1222,8 @@ llvm::make_unique(DiagnosticFile->os())); if (LTOPassRemarksWithHotness) Context.setDiagnosticsHotnessRequested(true); + if (LTOPassRemarksHotnessThreshold) + Context.setDiagnosticsHotnessThreshold(LTOPassRemarksHotnessThreshold); DiagnosticFile->keep(); return std::move(DiagnosticFile); } Index: llvm/trunk/lib/LTO/LTOBackend.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOBackend.cpp +++ llvm/trunk/lib/LTO/LTOBackend.cpp @@ -376,7 +376,8 @@ // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( - Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness); + Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness, + C.RemarksHotnessThreshold); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); auto DiagnosticOutputFile = std::move(*DiagFileOrErr); Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -89,6 +89,12 @@ "lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden); + +cl::opt LTOPassRemarksHotnessThreshold( + "lto-pass-remarks-hotness-threshold", + cl::desc("Minimum profile count required for an optimization remark to be " + "output"), + cl::Hidden); } LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) @@ -505,7 +511,8 @@ return false; auto DiagFileOrErr = lto::setupOptimizationRemarks( - Context, LTORemarksFilename, LTOPassRemarksWithHotness); + Context, LTORemarksFilename, LTOPassRemarksWithHotness, + LTOPassRemarksHotnessThreshold); if (!DiagFileOrErr) { errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; report_fatal_error("Can't get an output file for the remarks"); Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -63,6 +63,7 @@ extern cl::opt LTODiscardValueNames; extern cl::opt LTORemarksFilename; extern cl::opt LTOPassRemarksWithHotness; +extern cl::opt LTOPassRemarksHotnessThreshold; } namespace { @@ -998,7 +999,8 @@ Context.setDiscardValueNames(LTODiscardValueNames); Context.enableDebugTypeODRUniquing(); auto DiagFileOrErr = lto::setupOptimizationRemarks( - Context, LTORemarksFilename, LTOPassRemarksWithHotness, count); + Context, LTORemarksFilename, LTOPassRemarksWithHotness, + LTOPassRemarksHotnessThreshold, count); if (!DiagFileOrErr) { errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; report_fatal_error("ThinLTO: Can't get an output file for the " Index: llvm/trunk/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll =================================================================== --- llvm/trunk/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ llvm/trunk/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -8,6 +8,18 @@ ; 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.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=400 \ +; RUN: -exported-symbol _main -o %t.o %t.bc +; RUN: cat %t.yaml | FileCheck -allow-empty -check-prefix=YAML_TH_HIGH %s + +; RUN: llvm-lto -lto-pass-remarks-output=%t.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=200 \ +; RUN: -exported-symbol _main -o %t.o %t.bc +; RUN: cat %t.yaml | FileCheck -allow-empty -check-prefix=YAML %s + ; YAML: --- !Passed ; YAML-NEXT: Pass: inline ; YAML-NEXT: Name: Inlined @@ -24,6 +36,9 @@ ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... +; YAML_TH_HIGH-NOT: Name: Inlined + + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-darwin" Index: llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -5,7 +5,7 @@ ; with -lto-pass-remarks-with-hotness. ; RUN: llvm-lto -thinlto-action=run \ -; RUN: -lto-pass-remarks-output=%t.yaml \ +; RUN: -lto-pass-remarks-output=%t-no-th.yaml \ ; RUN: -lto-pass-remarks-with-hotness \ ; RUN: -exported-symbol _func2 \ ; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ @@ -13,9 +13,25 @@ ; CHECK-NOT: remark: ; CHECK-NOT: llvm-lto: +; RUN: llvm-lto -thinlto-action=run \ +; RUN: -lto-pass-remarks-output=%t-low-th.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=20 \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ + +; RUN: llvm-lto -thinlto-action=run \ +; RUN: -lto-pass-remarks-output=%t-high-th.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=100 \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ + ; Verify that bar is imported and inlined into foo -; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; RUN: cat %t-no-th.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; RUN: cat %t-low-th.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; RUN: cat %t-high-th.yaml.thin.0.yaml | FileCheck %s -allow-empty -check-prefix=YAML1_TH_HIGH ; YAML1: --- !Passed ; YAML1-NEXT: Pass: inline ; YAML1-NEXT: Name: Inlined @@ -32,9 +48,13 @@ ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... +; YAML1_TH_HIGH-NOT: Name: Inlined + ; Verify that bar is imported and inlined into foo -; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefix=YAML2 +; RUN: cat %t-no-th.yaml.thin.1.yaml | FileCheck %s -check-prefix=YAML2 +; RUN: cat %t-low-th.yaml.thin.1.yaml | FileCheck %s -allow-empty -check-prefix=YAML2_TH_HIGH +; RUN: cat %t-high-th.yaml.thin.1.yaml | FileCheck %s -allow-empty -check-prefix=YAML2_TH_HIGH ; YAML2: --- !Passed ; YAML2-NEXT: Pass: inline ; YAML2-NEXT: Name: Inlined @@ -50,6 +70,7 @@ ; YAML2-NEXT: - String: ')' ; YAML2-NEXT: ... +; YAML2_TH_HIGH-NOT: Name: Inlined target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.11.0"