Skip to content

Commit 0675d65

Browse files
PGO: Add test case for branch weights and function call counts recording.
1 parent bd816fd commit 0675d65

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# needs-profiler-support
2+
3+
-include ../tools.mk
4+
5+
# This test makes sure that instrumented binaries record the right counts for
6+
# functions being called and branches being taken. We run an instrumented binary
7+
# with an argument that causes a know path through the program and then check
8+
# that the expected counts get added to the use-phase LLVM IR.
9+
10+
# LLVM doesn't support instrumenting binaries that use SEH:
11+
# https://github.com/rust-lang/rust/issues/61002
12+
#
13+
# Things work fine with -Cpanic=abort though.
14+
ifdef IS_MSVC
15+
COMMON_FLAGS=-Cpanic=abort
16+
endif
17+
18+
all:
19+
# We don't compile `opaque` with either optimizations or instrumentation.
20+
# We don't compile `opaque` with either optimizations or instrumentation.
21+
$(RUSTC) $(COMMON_FLAGS) opaque.rs
22+
# Compile the test program with instrumentation
23+
mkdir -p "$(TMPDIR)"/prof_data_dir
24+
$(RUSTC) $(COMMON_FLAGS) interesting.rs \
25+
-Cprofile-generate="$(TMPDIR)"/prof_data_dir -O -Ccodegen-units=1
26+
$(RUSTC) $(COMMON_FLAGS) main.rs -Cprofile-generate="$(TMPDIR)"/prof_data_dir -O
27+
# The argument below generates to the expected branch weights
28+
$(call RUN,main aaaaaaaaaaaa2bbbbbbbbbbbb2bbbbbbbbbbbbbbbbcc) || exit 1
29+
"$(LLVM_BIN_DIR)"/llvm-profdata merge \
30+
-o "$(TMPDIR)"/prof_data_dir/merged.profdata \
31+
"$(TMPDIR)"/prof_data_dir
32+
$(RUSTC) $(COMMON_FLAGS) interesting.rs \
33+
-Cprofile-use="$(TMPDIR)"/prof_data_dir/merged.profdata -O \
34+
-Ccodegen-units=1 --emit=llvm-ir
35+
cat "$(TMPDIR)"/interesting.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
# First, establish that certain !prof labels are attached to the expected
3+
# functions and branching instructions.
4+
5+
CHECK: define void @function_called_twice(i32 %c) {{.*}} !prof !29 {
6+
CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !prof !30
7+
8+
CHECK: define void @function_called_42_times(i32 %c) {{.*}} !prof !31 {
9+
CHECK: switch i32 %c, label {{.*}} [
10+
CHECK-NEXT: i32 97, label {{.*}}
11+
CHECK-NEXT: i32 98, label {{.*}}
12+
CHECK-NEXT: ], !prof !32
13+
14+
CHECK: define void @function_called_never(i32 {{.*}} !prof !33 {
15+
16+
17+
18+
# Now check that those !prof tags hold the expected counts
19+
20+
CHECK: !29 = !{!"function_entry_count", i64 2}
21+
CHECK: !30 = !{!"branch_weights", i32 2, i32 0}
22+
CHECK: !31 = !{!"function_entry_count", i64 42}
23+
CHECK: !32 = !{!"branch_weights", i32 2, i32 12, i32 28}
24+
CHECK: !33 = !{!"function_entry_count", i64 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![crate_name="interesting"]
2+
#![crate_type="rlib"]
3+
4+
extern crate opaque;
5+
6+
#[no_mangle]
7+
#[inline(never)]
8+
pub fn function_called_twice(c: char) {
9+
if c == '2' {
10+
// This branch is taken twice
11+
opaque::f1();
12+
} else {
13+
// This branch is never taken
14+
opaque::f2();
15+
}
16+
}
17+
18+
#[no_mangle]
19+
#[inline(never)]
20+
pub fn function_called_42_times(c: char) {
21+
if c == 'a' {
22+
// This branch is taken 12 times
23+
opaque::f1();
24+
} else {
25+
26+
if c == 'b' {
27+
// This branch is taken 28 times
28+
opaque::f2();
29+
} else {
30+
// This branch is taken 2 times
31+
opaque::f3();
32+
}
33+
}
34+
}
35+
36+
#[no_mangle]
37+
#[inline(never)]
38+
pub fn function_called_never(_: char) {
39+
opaque::f1();
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
extern crate interesting;
2+
3+
fn main() {
4+
let arg = std::env::args().skip(1).next().unwrap();
5+
6+
for c in arg.chars() {
7+
if c == '2' {
8+
interesting::function_called_twice(c);
9+
} else {
10+
interesting::function_called_42_times(c);
11+
}
12+
13+
if c == '0' {
14+
interesting::function_called_never(c);
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_name="opaque"]
2+
#![crate_type="rlib"]
3+
4+
pub fn f1() {}
5+
pub fn f2() {}
6+
pub fn f3() {}

0 commit comments

Comments
 (0)