Skip to content

Commit 1de93a7

Browse files
Add a smoketest for combining PGO with xLTO.
1 parent 30a3fad commit 1de93a7

File tree

5 files changed

+131
-0
lines changed

5 files changed

+131
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# needs-matching-clang
2+
3+
# This test makes sure that cross-language inlining can be used in conjunction
4+
# with profile-guided optimization. The test only tests that the whole workflow
5+
# can be executed without anything crashing. It does not test whether PGO or
6+
# xLTO have any specific effect on the generated code.
7+
8+
-include ../tools.mk
9+
10+
COMMON_FLAGS=-Copt-level=3 -Ccodegen-units=1
11+
12+
# LLVM doesn't support instrumenting binaries that use SEH:
13+
# https://bugs.llvm.org/show_bug.cgi?id=41279
14+
#
15+
# Things work fine with -Cpanic=abort though.
16+
ifdef IS_MSVC
17+
COMMON_FLAGS+= -Cpanic=abort
18+
endif
19+
20+
all: cpp-executable rust-executable
21+
22+
cpp-executable:
23+
$(RUSTC) -Clinker-plugin-lto=on \
24+
-Zpgo-gen="$(TMPDIR)"/cpp-profdata \
25+
-o "$(TMPDIR)"/librustlib-xlto.a \
26+
$(COMMON_FLAGS) \
27+
./rustlib.rs
28+
$(CLANG) -flto=thin \
29+
-fprofile-generate="$(TMPDIR)"/cpp-profdata \
30+
-fuse-ld=lld \
31+
-L "$(TMPDIR)" \
32+
-lrustlib-xlto \
33+
-o "$(TMPDIR)"/cmain \
34+
-O3 \
35+
./cmain.c
36+
$(TMPDIR)/cmain
37+
# Postprocess the profiling data so it can be used by the compiler
38+
"$(LLVM_BIN_DIR)"/llvm-profdata merge \
39+
-o "$(TMPDIR)"/cpp-profdata/merged.profdata \
40+
"$(TMPDIR)"/cpp-profdata/default_*.profraw
41+
$(RUSTC) -Clinker-plugin-lto=on \
42+
-Zpgo-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
43+
-o "$(TMPDIR)"/librustlib-xlto.a \
44+
$(COMMON_FLAGS) \
45+
./rustlib.rs
46+
$(CLANG) -flto=thin \
47+
-fprofile-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
48+
-fuse-ld=lld \
49+
-L "$(TMPDIR)" \
50+
-lrustlib-xlto \
51+
-o "$(TMPDIR)"/cmain \
52+
-O3 \
53+
./cmain.c
54+
55+
rust-executable:
56+
exit
57+
$(CLANG) ./clib.c -fprofile-generate="$(TMPDIR)"/rs-profdata -flto=thin -c -o $(TMPDIR)/clib.o -O3
58+
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
59+
$(RUSTC) -Clinker-plugin-lto=on \
60+
-Zpgo-gen="$(TMPDIR)"/rs-profdata \
61+
-L$(TMPDIR) \
62+
$(COMMON_FLAGS) \
63+
-Clinker=$(CLANG) \
64+
-Clink-arg=-fuse-ld=lld \
65+
-o $(TMPDIR)/rsmain \
66+
./main.rs
67+
$(TMPDIR)/rsmain
68+
# Postprocess the profiling data so it can be used by the compiler
69+
"$(LLVM_BIN_DIR)"/llvm-profdata merge \
70+
-o "$(TMPDIR)"/rs-profdata/merged.profdata \
71+
"$(TMPDIR)"/rs-profdata/default_*.profraw
72+
$(CLANG) ./clib.c \
73+
-fprofile-use="$(TMPDIR)"/rs-profdata/merged.profdata \
74+
-flto=thin \
75+
-c \
76+
-o $(TMPDIR)/clib.o \
77+
-O3
78+
rm "$(TMPDIR)"/libxyz.a
79+
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
80+
$(RUSTC) -Clinker-plugin-lto=on \
81+
-Zpgo-use="$(TMPDIR)"/rs-profdata/merged.profdata \
82+
-L$(TMPDIR) \
83+
$(COMMON_FLAGS) \
84+
-Clinker=$(CLANG) \
85+
-Clink-arg=-fuse-ld=lld \
86+
-o $(TMPDIR)/rsmain \
87+
./main.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <stdint.h>
2+
3+
uint32_t c_always_inlined() {
4+
return 1234;
5+
}
6+
7+
__attribute__((noinline)) uint32_t c_never_inlined() {
8+
return 12345;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdint.h>
2+
3+
// A trivial function defined in Rust, returning a constant value. This should
4+
// always be inlined.
5+
uint32_t rust_always_inlined();
6+
7+
8+
uint32_t rust_never_inlined();
9+
10+
int main(int argc, char** argv) {
11+
return (rust_never_inlined() + rust_always_inlined()) * 0;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[link(name = "xyz")]
2+
extern "C" {
3+
fn c_always_inlined() -> u32;
4+
fn c_never_inlined() -> u32;
5+
}
6+
7+
fn main() {
8+
unsafe {
9+
println!("blub: {}", c_always_inlined() + c_never_inlined());
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![crate_type="staticlib"]
2+
3+
#[no_mangle]
4+
pub extern "C" fn rust_always_inlined() -> u32 {
5+
42
6+
}
7+
8+
#[no_mangle]
9+
#[inline(never)]
10+
pub extern "C" fn rust_never_inlined() -> u32 {
11+
421
12+
}

0 commit comments

Comments
 (0)