Skip to content

Commit da51a10

Browse files
[llvm-remarkutil] Introduce summary tool
This tool provides a harness for implementing different strategies that summarize many remarks (possibly from multiple translation units) into new summary remarks. The remark summaries can then be viewed using tools like `opt-viewer`. The first summary strategy is `--inline-callees`, which generates remarks that summarize the per-callee inline statistics for functions that appear in inling remarks. This is useful for troubleshooting inlining issues/regressions on large codebases. Pull Request: llvm#160549
1 parent 758c1f9 commit da51a10

File tree

11 files changed

+434
-3
lines changed

11 files changed

+434
-3
lines changed

llvm/include/llvm/Remarks/Remark.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ struct Argument {
5151
// If set, the debug location corresponding to the value.
5252
std::optional<RemarkLocation> Loc;
5353

54+
Argument() = default;
55+
Argument(StringRef Key, StringRef Val) : Key(Key), Val(Val) {}
56+
5457
/// Implement operator<< on Argument.
5558
LLVM_ABI void print(raw_ostream &OS) const;
5659
/// Return the value of argument as int.
5760
LLVM_ABI std::optional<int> getValAsInt() const;
61+
/// Return the value of argument as signed int.
62+
LLVM_ABI std::optional<int> getValAsSignedInt() const;
5863
/// Check if the argument value can be parsed as int.
5964
LLVM_ABI bool isValInt() const;
6065
};
@@ -127,6 +132,10 @@ struct Remark {
127132
/// Return a message composed from the arguments as a string.
128133
LLVM_ABI std::string getArgsAsMsg() const;
129134

135+
/// Return the first argument with the specified key or nullptr if no such
136+
/// argument was found.
137+
LLVM_ABI Argument *getArgByKey(StringRef Key);
138+
130139
/// Clone this remark to explicitly ask for a copy.
131140
Remark clone() const { return *this; }
132141

llvm/lib/Remarks/Remark.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "llvm/Remarks/Remark.h"
1414
#include "llvm/ADT/APInt.h"
1515
#include "llvm/ADT/ArrayRef.h"
16+
#include "llvm/ADT/STLExtras.h"
1617
#include <optional>
1718

1819
using namespace llvm;
@@ -26,6 +27,13 @@ std::string Remark::getArgsAsMsg() const {
2627
return Str;
2728
}
2829

30+
Argument *Remark::getArgByKey(StringRef Key) {
31+
auto *It = find_if(Args, [&](auto &Arg) { return Arg.Key == Key; });
32+
if (It == Args.end())
33+
return nullptr;
34+
return &*It;
35+
}
36+
2937
/// Returns the value of a specified key parsed from StringRef.
3038
std::optional<int> Argument::getValAsInt() const {
3139
APInt KeyVal;
@@ -34,6 +42,14 @@ std::optional<int> Argument::getValAsInt() const {
3442
return KeyVal.getSExtValue();
3543
}
3644

45+
std::optional<int> Argument::getValAsSignedInt() const {
46+
StringRef Str = Val;
47+
int Res;
48+
if (Str.consumeInteger(10, Res) || !Str.empty())
49+
return std::nullopt;
50+
return Res;
51+
}
52+
3753
bool Argument::isValInt() const { return getValAsInt().has_value(); }
3854

3955
void RemarkLocation::print(raw_ostream &OS) const {

llvm/test/tools/llvm-remarkutil/broken-bitstream-remark-magic.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ RUN: not llvm-remarkutil instruction-mix %p/Inputs/broken-remark-magic.bitstream
33
RUN: not llvm-remarkutil annotation-count --annotation-type=remark %p/Inputs/broken-remark-magic.bitstream -o - 2>&1 | FileCheck %s
44
RUN: not llvm-remarkutil count %p/Inputs/broken-remark-magic.bitstream -o - 2>&1 | FileCheck %s
55
RUN: not llvm-remarkutil filter %p/Inputs/broken-remark-magic.bitstream -o - 2>&1 | FileCheck %s
6+
RUN: not llvm-remarkutil summary %p/Inputs/broken-remark-magic.bitstream -o - 2>&1 | FileCheck %s
67

78
CHECK: error: Automatic detection of remark format failed. Unknown magic number: '1234'

llvm/test/tools/llvm-remarkutil/broken-bitstream-remark.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ RUN: not llvm-remarkutil instruction-count --parser=bitstream %p/Inputs/broken-r
33
RUN: not llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
44
RUN: not llvm-remarkutil count --parser=bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
55
RUN: not llvm-remarkutil filter --parser=bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
6+
RUN: not llvm-remarkutil summary --parser=bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
67

78
CHECK: error: Unknown magic number: expecting RMRK, got --- .

llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/broken-remark -
44
RUN: not llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
55
RUN: not llvm-remarkutil count --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
66
RUN: not llvm-remarkutil filter --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
7+
RUN: not llvm-remarkutil summary --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
78

89
CHECK: error: Type, Pass, Name or Function missing

llvm/test/tools/llvm-remarkutil/empty-file.test

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/empty-file -o -
44
RUN: not llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
55
RUN: not llvm-remarkutil count --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
66
RUN: not llvm-remarkutil filter --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
7+
RUN: not llvm-remarkutil summary --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
78
RUN: llvm-remarkutil bitstream2yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=BITSTREAM2YAML
89
RUN: llvm-remarkutil instruction-count --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=SIZEBITSTREAM
910
RUN: llvm-remarkutil instruction-mix --parser=bitstream %p/Inputs/empty-file --report_style=csv -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=MIXBITSTREAM
1011
RUN: llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=ANNOTATIONBITSTREAM
1112
RUN: llvm-remarkutil count --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=COUNTBITSTREAM
12-
RUN: llvm-remarkutil filter --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=FILTERBITSTREAM
13+
RUN: llvm-remarkutil filter --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=EMPTYBITSTREAM
14+
RUN: llvm-remarkutil summary --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=EMPTYBITSTREAM
1315
; Parser format auto-detection should treat empty files as bitstream files
1416
RUN: llvm-remarkutil instruction-count %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=SIZEBITSTREAM
1517
RUN: llvm-remarkutil instruction-mix %p/Inputs/empty-file --report_style=csv -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=MIXBITSTREAM
1618
RUN: llvm-remarkutil annotation-count --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=ANNOTATIONBITSTREAM
1719
RUN: llvm-remarkutil count %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=COUNTBITSTREAM
18-
RUN: llvm-remarkutil filter %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=FILTERBITSTREAM
20+
RUN: llvm-remarkutil filter %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=EMPTYBITSTREAM
21+
RUN: llvm-remarkutil summary %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=EMPTYBITSTREAM
1922

2023
; YAMLPARSER: error: document root is not of mapping type.
2124

@@ -34,4 +37,4 @@ RUN: llvm-remarkutil filter %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allo
3437
; MIXBITSTREAM-LABEL: Instruction,Count
3538
; MIXBITSTREAM-EMPTY:
3639

37-
; FILTERBITSTREAM-NOT: {{.}}
40+
; EMPTYBITSTREAM-NOT: {{.}}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--- !Missed
2+
Pass: inline
3+
Name: TooCostly
4+
DebugLoc: { File: 'foo.cpp', Line: 21, Column: 6 }
5+
Function: fooCaller
6+
Args:
7+
- Callee: fooCallee
8+
DebugLoc: { File: 'foo.cpp', Line: 10, Column: 0 }
9+
- Caller: fooCaller
10+
DebugLoc: { File: 'foo.cpp', Line: 20, Column: 0 }
11+
- Cost: '125'
12+
- Threshold: '100'
13+
...
14+
--- !Passed
15+
Pass: inline
16+
Name: Inlined
17+
DebugLoc: { File: 'foo.cpp', Line: 21, Column: 6 }
18+
Function: fooCaller2
19+
Args:
20+
- Callee: fooCallee
21+
DebugLoc: { File: 'foo.cpp', Line: 10, Column: 0 }
22+
- Caller: fooCaller
23+
DebugLoc: { File: 'foo.cpp', Line: 20, Column: 0 }
24+
- Cost: '-15'
25+
- Threshold: '100'
26+
- Line: '1'
27+
- Column: '6'
28+
...
29+
--- !Passed
30+
Pass: inline
31+
Name: AlwaysInline
32+
DebugLoc: { File: 'bar.cpp', Line: 23, Column: 10 }
33+
Function: barCaller
34+
Args:
35+
- Callee: barCallee
36+
DebugLoc: { File: 'bar.cpp', Line: 5, Column: 0 }
37+
- Caller: barCaller
38+
DebugLoc: { File: 'bar.cpp', Line: 22, Column: 0 }
39+
- Reason: always inline attribute
40+
- Line: '23'
41+
- Column: '10'
42+
...
43+
--- !Missed
44+
Pass: inline
45+
Name: NoDefinition
46+
Function: bazCaller
47+
Args:
48+
- Callee: bazCallee
49+
- Caller: bazCaller
50+
...
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
RUN: llvm-remarkutil summary --inline-callees %p/Inputs/inline.yaml | FileCheck -strict-whitespace %s
2+
3+
; CHECK: --- !Analysis
4+
; CHECK-NEXT: Pass: inline
5+
; CHECK-NEXT: Name: Summary
6+
; CHECK-NEXT: DebugLoc: { File: bar.cpp, Line: 5, Column: 0 }
7+
; CHECK-NEXT: Function: barCallee
8+
; CHECK-NEXT: Args:
9+
; CHECK-NEXT: - String: 'Incoming Calls ('
10+
; CHECK-NEXT: - String: AlwaysInline
11+
; CHECK-NEXT: - String: ': '
12+
; CHECK-NEXT: - AlwaysInline: '1'
13+
; CHECK-NEXT: - String: ')'
14+
; CHECK-NEXT: ...
15+
; CHECK-NEXT: --- !Analysis
16+
; CHECK-NEXT: Pass: inline
17+
; CHECK-NEXT: Name: Summary
18+
; CHECK-NEXT: Function: bazCallee
19+
; CHECK-NEXT: Args:
20+
; CHECK-NEXT: - String: 'Incoming Calls ('
21+
; CHECK-NEXT: - String: NoDefinition
22+
; CHECK-NEXT: - String: ': '
23+
; CHECK-NEXT: - NoDefinition: '1'
24+
; CHECK-NEXT: - String: ')'
25+
; CHECK-NEXT: ...
26+
; CHECK-NEXT: --- !Analysis
27+
; CHECK-NEXT: Pass: inline
28+
; CHECK-NEXT: Name: Summary
29+
; CHECK-NEXT: DebugLoc: { File: foo.cpp, Line: 10, Column: 0 }
30+
; CHECK-NEXT: Function: fooCallee
31+
; CHECK-NEXT: Args:
32+
; CHECK-NEXT: - String: 'Incoming Calls ('
33+
; CHECK-NEXT: - String: Inlined
34+
; CHECK-NEXT: - String: ': '
35+
; CHECK-NEXT: - Inlined: '1'
36+
; CHECK-NEXT: - String: ', '
37+
; CHECK-NEXT: - String: TooCostly
38+
; CHECK-NEXT: - String: ': '
39+
; CHECK-NEXT: - TooCostly: '1'
40+
; CHECK-NEXT: - String: ')'
41+
; CHECK-NEXT: - String: "\nLeast profitable (cost="
42+
; CHECK-NEXT: - LeastProfitCost: '125'
43+
; CHECK-NEXT: DebugLoc: { File: foo.cpp, Line: 21, Column: 6 }
44+
; CHECK-NEXT: - String: ', threshold='
45+
; CHECK-NEXT: - LeastProfitThreshold: '100'
46+
; CHECK-NEXT: - String: ')'
47+
; CHECK-NEXT: - String: "\nMost profitable (cost="
48+
; CHECK-NEXT: - MostProfitCost: '-15'
49+
; CHECK-NEXT: DebugLoc: { File: foo.cpp, Line: 21, Column: 6 }
50+
; CHECK-NEXT: - String: ', threshold='
51+
; CHECK-NEXT: - MostProfitThreshold: '100'
52+
; CHECK-NEXT: - String: ')'
53+
; CHECK-NEXT: ...
54+
; CHECK-NOT: {{.}}

llvm/tools/llvm-remarkutil/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_llvm_tool(llvm-remarkutil
1111
RemarkFilter.cpp
1212
RemarkInstructionMix.cpp
1313
RemarkSizeDiff.cpp
14+
RemarkSummary.cpp
1415
RemarkUtil.cpp
1516
RemarkUtilHelpers.cpp
1617
RemarkUtilRegistry.cpp

0 commit comments

Comments
 (0)