llvm.org GIT mirror llvm / e330528
[ORE] Add diagnostics hotness threshold Summary: Add an option to prevent diagnostics that do not meet a minimum hotness threshold from being output. When generating optimization remarks for large codebases with a ton of cold code paths, this option can be used to limit the optimization remark output at a reasonable size. Discussion of this change can be read here: http://lists.llvm.org/pipermail/llvm-dev/2017-June/114377.html Reviewers: anemet, davidxl, hfinkel Reviewed By: anemet Subscribers: qcolombet, javed.absar, fhahn, eraman, llvm-commits Differential Revision: https://reviews.llvm.org/D34867 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306912 91177308-0d34-0410-b5e6-96231b3b80d8 Brian Gesiak 3 years ago
9 changed file(s) with 92 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
192192 /// diagnostics.
193193 void setDiagnosticsHotnessRequested(bool Requested);
194194
195 /// \brief Return the minimum hotness value a diagnostic would need in order
196 /// to be included in optimization diagnostics. If there is no minimum, this
197 /// returns None.
198 uint64_t getDiagnosticsHotnessThreshold() const;
199
200 /// \brief Set the minimum hotness value a diagnostic needs in order to be
201 /// included in optimization diagnostics.
202 void setDiagnosticsHotnessThreshold(uint64_t Threshold);
203
195204 /// \brief Return the YAML file used by the backend to save optimization
196205 /// diagnostics. If null, diagnostics are not saved in a file but only
197206 /// emitted via the diagnostic handler.
154154 DiagnosticInfoOptimizationBase &OptDiagBase) {
155155 auto &OptDiag = cast(OptDiagBase);
156156 computeHotness(OptDiag);
157 // If a diagnostic has a hotness value, then only emit it if its hotness
158 // meets the threshold.
159 if (OptDiag.getHotness() &&
160 *OptDiag.getHotness() <
161 F->getContext().getDiagnosticsHotnessThreshold()) {
162 return;
163 }
157164
158165 yaml::Output *Out = F->getContext().getDiagnosticsOutputFile();
159166 if (Out) {
5151 computeHotness(OptDiag);
5252
5353 LLVMContext &Ctx = MF.getFunction()->getContext();
54
55 // If a diagnostic has a hotness value, then only emit it if its hotness
56 // meets the threshold.
57 if (OptDiag.getHotness() &&
58 *OptDiag.getHotness() < Ctx.getDiagnosticsHotnessThreshold()) {
59 return;
60 }
61
5462 yaml::Output *Out = Ctx.getDiagnosticsOutputFile();
5563 if (Out) {
5664 auto *P = &const_cast(OptDiagCommon);
131131 return pImpl->DiagnosticsHotnessRequested;
132132 }
133133
134 void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
135 pImpl->DiagnosticsHotnessThreshold = Threshold;
136 }
137 uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
138 return pImpl->DiagnosticsHotnessThreshold;
139 }
140
134141 yaml::Output *LLVMContext::getDiagnosticsOutputFile() {
135142 return pImpl->DiagnosticsOutputFile.get();
136143 }
11691169 void *DiagnosticContext = nullptr;
11701170 bool RespectDiagnosticFilters = false;
11711171 bool DiagnosticsHotnessRequested = false;
1172 uint64_t DiagnosticsHotnessThreshold = 0;
11721173 std::unique_ptr DiagnosticsOutputFile;
11731174
11741175 LLVMContext::YieldCallbackTy YieldCallback = nullptr;
22 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple 2>&1 | FileCheck -check-prefix=NO_REMARK %s
33 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple -pass-remarks-output=%t.yaml -pass-remarks-with-hotness 2>&1 | FileCheck -check-prefix=NO_REMARK %s
44 ; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
5 ;
6 ; Verify that remarks below the hotness threshold are not output.
7 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple -pass-remarks-missed=regalloc \
8 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold=500 \
9 ; RUN: 2>&1 | FileCheck -check-prefix=THRESHOLD %s
10 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple -pass-remarks-output=%t.threshold.yaml \
11 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold=500 \
12 ; RUN: 2>&1 | FileCheck -check-prefix=NO_REMARK %s
13 ; RUN: cat %t.threshold.yaml | FileCheck -check-prefix=THRESHOLD_YAML %s
514
615 ; This has two nested loops, each with one value that has to be spilled and
716 ; then reloaded.
2130 ; HOTNESS: remark: /tmp/kk.c:1:20: 2 spills 2 reloads generated in loop (hotness: 300)
2231
2332 ; NO_REMARK-NOT: remark
33
34 ; THRESHOLD-NOT: (hotness: 300)
35 ; THRESHOLD: remark: /tmp/kk.c:2:20: 1 spills 1 reloads generated in loop (hotness: 30000)
2436
2537 ; YAML: --- !Missed
2638 ; YAML: Pass: regalloc
6173 ; YAML: - String: ' reloads '
6274 ; YAML: - String: generated in loop
6375 ; YAML: ...
76
77 ; THRESHOLD_YAML-NOT: Hotness: 300{{$}}
78 ; THRESHOLD_YAML: --- !Missed
79 ; THRESHOLD_YAML: Pass: regalloc
80 ; THRESHOLD_YAML: Name: LoopSpillReload
81 ; THRESHOLD_YAML: DebugLoc: { File: /tmp/kk.c, Line: 2, Column: 20 }
82 ; THRESHOLD_YAML: Function: fpr128
83 ; THRESHOLD_YAML: Hotness: 30000
84 ; THRESHOLD_YAML: Args:
85 ; THRESHOLD_YAML: - NumSpills: '1'
86 ; THRESHOLD_YAML: - String: ' spills '
87 ; THRESHOLD_YAML: - NumReloads: '1'
88 ; THRESHOLD_YAML: - String: ' reloads '
89 ; THRESHOLD_YAML: - String: generated in loop
90 ; THRESHOLD_YAML: ...
6491
6592 define void @fpr128(<4 x float>* %p) nounwind ssp !prof !11 {
6693 entry:
None ; RUN: opt < %s -S -inline -pass-remarks-missed=inline -pass-remarks-with-hotness \
0 ; RUN: opt < %s -S -inline -pass-remarks-missed=inline \
1 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 15 \
12 ; RUN: -pass-remarks-output=%t 2>&1 | FileCheck %s
23 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
34 ; RUN: opt < %s -S -inline -pass-remarks-with-hotness -pass-remarks-output=%t
45 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
6 ;
7 ; Verify that remarks that don't meet the hotness threshold are not output.
8 ; RUN: opt < %s -S -inline -pass-remarks-missed=inline \
9 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 100 \
10 ; RUN: -pass-remarks-output=%t.threshold 2>&1 | \
11 ; RUN: FileCheck -check-prefix=THRESHOLD %s
12 ; RUN: test ! -s %t.threshold
13 ; RUN: opt < %s -S -inline \
14 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 100 \
15 ; RUN: -pass-remarks-output=%t.threshold
16 ; The remarks output file should be empty.
17 ; RUN: test ! -s %t.threshold
518
619 ; Check the YAML file generated for inliner remarks for this program:
720 ;
4255 ; YAML-NEXT: - String: ' because its definition is unavailable'
4356 ; YAML-NEXT: ...
4457
58 ; No remarks should be output, since none meet the threshold.
59 ; THRESHOLD-NOT: remark
60
4561 ; ModuleID = '/tmp/s.c'
4662 source_filename = "/tmp/s.c"
4763 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
148148 cl::desc("With PGO, include profile count in optimization remarks"),
149149 cl::Hidden);
150150
151 static cl::opt PassRemarksHotnessThreshold(
152 "pass-remarks-hotness-threshold",
153 cl::desc("Minimum profile count required for an optimization remark to be output"),
154 cl::Hidden);
155
151156 static cl::opt
152157 RemarksFilename("pass-remarks-output",
153158 cl::desc("YAML output filename for pass remarks"),
324329 if (PassRemarksWithHotness)
325330 Context.setDiagnosticsHotnessRequested(true);
326331
332 if (PassRemarksHotnessThreshold)
333 Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold);
334
327335 std::unique_ptr YamlFile;
328336 if (RemarksFilename != "") {
329337 std::error_code EC;
241241 cl::desc("With PGO, include profile count in optimization remarks"),
242242 cl::Hidden);
243243
244 static cl::opt PassRemarksHotnessThreshold(
245 "pass-remarks-hotness-threshold",
246 cl::desc("Minimum profile count required for an optimization remark to be output"),
247 cl::Hidden);
248
244249 static cl::opt
245250 RemarksFilename("pass-remarks-output",
246251 cl::desc("YAML output filename for pass remarks"),
421426 if (PassRemarksWithHotness)
422427 Context.setDiagnosticsHotnessRequested(true);
423428
429 if (PassRemarksHotnessThreshold)
430 Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold);
431
424432 std::unique_ptr YamlFile;
425433 if (RemarksFilename != "") {
426434 std::error_code EC;