Skip to content

Commit 7164a13

Browse files
authored
Rollup merge of rust-lang#60262 - michaelwoerister:pgo-preinlining-pass, r=alexcrichton
PGO: Add a run-make test that makes sure that PGO profiling data is used by the compiler during optimizations. From the tests comment section: ``` # This test makes sure that PGO profiling data leads to cold functions being # marked as `cold` and hot functions with `inlinehint`. # The test program contains an `if` were actual execution only ever takes the # `else` branch. Accordingly, we expect the function that is never called to # be marked as cold. ``` r? @alexcrichton
2 parents ae5100e + 33808b0 commit 7164a13

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed
Lines changed: 35 additions & 0 deletions
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 PGO profiling data leads to cold functions being
6+
# marked as `cold` and hot functions with `inlinehint`.
7+
# The test program contains an `if` were actual execution only ever takes the
8+
# `else` branch. Accordingly, we expect the function that is never called to
9+
# be marked as cold.
10+
#
11+
# The program is compiled with `-Copt-level=s` because this setting disables
12+
# LLVM's pre-inlining pass (i.e. a pass that does some inlining before it adds
13+
# the profiling instrumentation). Disabling this pass leads to rather
14+
# predictable IR which we need for this test to be stable.
15+
16+
COMMON_FLAGS=-Copt-level=s -Ccodegen-units=1
17+
18+
all:
19+
# Compile the test program with instrumentation
20+
$(RUSTC) $(COMMON_FLAGS) -Z pgo-gen="$(TMPDIR)" main.rs
21+
# Run it in order to generate some profiling data
22+
$(call RUN,main some-argument) || exit 1
23+
# Postprocess the profiling data so it can be used by the compiler
24+
$(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-profdata merge \
25+
-o "$(TMPDIR)"/merged.profdata \
26+
"$(TMPDIR)"/default_*.profraw
27+
# Compile the test program again, making use of the profiling data
28+
$(RUSTC) $(COMMON_FLAGS) -Z pgo-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs
29+
# Check that the generate IR contains some things that we expect
30+
#
31+
# We feed the file into LLVM FileCheck tool *in reverse* so that we see the
32+
# line with the function name before the line with the function attributes.
33+
# FileCheck only supports checking that something matches on the next line,
34+
# but not if something matches on the previous line.
35+
tac "$(TMPDIR)"/main.ll | $(LLVM_FILECHECK) filecheck-patterns.txt
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Add a check that the IR contains some expected metadata
2+
CHECK: !{!"ProfileFormat", !"InstrProf"}
3+
CHECK: !"ProfileSummary"
4+
5+
# Make sure that the hot function is marked with `inlinehint`
6+
CHECK: define {{.*}} @hot_function
7+
CHECK-NEXT: Function Attrs:{{.*}}inlinehint
8+
9+
# Make sure that the cold function is marked with `cold`
10+
CHECK: define {{.*}} @cold_function
11+
CHECK-NEXT: Function Attrs:{{.*}}cold
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#[no_mangle]
2+
pub fn cold_function(c: u8) {
3+
println!("cold {}", c);
4+
}
5+
6+
#[no_mangle]
7+
pub fn hot_function(c: u8) {
8+
std::env::set_var(format!("var{}", c), format!("hot {}", c));
9+
}
10+
11+
fn main() {
12+
let arg = std::env::args().skip(1).next().unwrap();
13+
14+
for i in 0 .. 1000_000 {
15+
let some_value = arg.as_bytes()[i % arg.len()];
16+
if some_value == b'!' {
17+
// This branch is never taken at runtime
18+
cold_function(some_value);
19+
} else {
20+
hot_function(some_value);
21+
}
22+
}
23+
}

src/tools/compiletest/src/runtest.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2689,6 +2689,10 @@ impl<'test> TestCx<'test> {
26892689
cmd.env("CLANG", clang);
26902690
}
26912691

2692+
if let Some(ref filecheck) = self.config.llvm_filecheck {
2693+
cmd.env("LLVM_FILECHECK", filecheck);
2694+
}
2695+
26922696
// We don't want RUSTFLAGS set from the outside to interfere with
26932697
// compiler flags set in the test cases:
26942698
cmd.env_remove("RUSTFLAGS");

0 commit comments

Comments
 (0)