about summary refs log tree commit diff
path: root/tests/run-make/pgo-branch-weights
diff options
context:
space:
mode:
authorJoshua Nelson <github@jyn.dev>2023-03-30 07:34:55 -0500
committerJoshua Nelson <github@jyn.dev>2023-03-30 07:34:55 -0500
commit433da1fc047bb39a263eefca4bdb2b1972f1d2ce (patch)
tree28540e78fdd5fdf158267e67495121ac64f0866a /tests/run-make/pgo-branch-weights
parentf2d9a3d0771504f1ae776226a5799dcb4408a91a (diff)
Move almost all run-make-fulldeps to run-make
They pass fine.
Diffstat (limited to 'tests/run-make/pgo-branch-weights')
-rw-r--r--tests/run-make/pgo-branch-weights/Makefile34
-rw-r--r--tests/run-make/pgo-branch-weights/filecheck-patterns.txt24
-rw-r--r--tests/run-make/pgo-branch-weights/interesting.rs40
-rw-r--r--tests/run-make/pgo-branch-weights/main.rs17
-rw-r--r--tests/run-make/pgo-branch-weights/opaque.rs6
5 files changed, 121 insertions, 0 deletions
diff --git a/tests/run-make/pgo-branch-weights/Makefile b/tests/run-make/pgo-branch-weights/Makefile
new file mode 100644
index 00000000000..c60206a1f34
--- /dev/null
+++ b/tests/run-make/pgo-branch-weights/Makefile
@@ -0,0 +1,34 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
+
+include ../tools.mk
+
+# For some very small programs GNU ld seems to not properly handle
+# instrumentation sections correctly. Neither Gold nor LLD have that problem.
+ifeq ($(UNAME),Linux)
+ifneq (,$(findstring x86,$(TARGET)))
+COMMON_FLAGS=-Clink-args=-fuse-ld=gold
+endif
+endif
+
+
+all:
+	# We don't compile `opaque` with either optimizations or instrumentation.
+	$(RUSTC) $(COMMON_FLAGS) opaque.rs || exit 1
+	# Compile the test program with instrumentation
+	mkdir -p "$(TMPDIR)/prof_data_dir" || exit 1
+	$(RUSTC) $(COMMON_FLAGS) interesting.rs \
+		-Cprofile-generate="$(TMPDIR)/prof_data_dir" -O -Ccodegen-units=1 || exit 1
+	$(RUSTC) $(COMMON_FLAGS) main.rs -Cprofile-generate="$(TMPDIR)/prof_data_dir" -O || exit 1
+	# The argument below generates to the expected branch weights
+	$(call RUN,main aaaaaaaaaaaa2bbbbbbbbbbbb2bbbbbbbbbbbbbbbbcc) || exit 1
+	"$(LLVM_BIN_DIR)/llvm-profdata" merge \
+		-o "$(TMPDIR)/prof_data_dir/merged.profdata" \
+		"$(TMPDIR)/prof_data_dir" || exit 1
+	$(RUSTC) $(COMMON_FLAGS) interesting.rs \
+		-Cprofile-use="$(TMPDIR)/prof_data_dir/merged.profdata" -O \
+		-Ccodegen-units=1 --emit=llvm-ir || exit 1
+	cat "$(TMPDIR)/interesting.ll" | "$(LLVM_FILECHECK)" filecheck-patterns.txt
diff --git a/tests/run-make/pgo-branch-weights/filecheck-patterns.txt b/tests/run-make/pgo-branch-weights/filecheck-patterns.txt
new file mode 100644
index 00000000000..70d5a645c14
--- /dev/null
+++ b/tests/run-make/pgo-branch-weights/filecheck-patterns.txt
@@ -0,0 +1,24 @@
+
+# First, establish that certain !prof labels are attached to the expected
+# functions and branching instructions.
+
+CHECK: define void @function_called_twice(i32 {{.*}} !prof [[function_called_twice_id:![0-9]+]] {
+CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !prof [[branch_weights0:![0-9]+]]
+
+CHECK: define void @function_called_42_times(i32{{.*}} %c) {{.*}} !prof [[function_called_42_times_id:![0-9]+]] {
+CHECK:      switch i32 %c, label {{.*}} [
+CHECK-NEXT:     i32 97, label {{.*}}
+CHECK-NEXT:     i32 98, label {{.*}}
+CHECK-NEXT: ], !prof [[branch_weights1:![0-9]+]]
+
+CHECK: define void @function_called_never(i32 {{.*}} !prof [[function_called_never_id:![0-9]+]] {
+
+
+
+# Now check that those !prof tags hold the expected counts
+
+CHECK: [[function_called_twice_id]] = !{!"function_entry_count", i64 2}
+CHECK: [[branch_weights0]] = !{!"branch_weights", i32 2, i32 0}
+CHECK: [[function_called_42_times_id]] = !{!"function_entry_count", i64 42}
+CHECK: [[branch_weights1]] = !{!"branch_weights", i32 2, i32 12, i32 28}
+CHECK: [[function_called_never_id]] = !{!"function_entry_count", i64 0}
diff --git a/tests/run-make/pgo-branch-weights/interesting.rs b/tests/run-make/pgo-branch-weights/interesting.rs
new file mode 100644
index 00000000000..a26d6fd69d1
--- /dev/null
+++ b/tests/run-make/pgo-branch-weights/interesting.rs
@@ -0,0 +1,40 @@
+#![crate_name="interesting"]
+#![crate_type="rlib"]
+
+extern crate opaque;
+
+#[no_mangle]
+#[inline(never)]
+pub fn function_called_twice(c: char) {
+    if c == '2' {
+        // This branch is taken twice
+        opaque::f1();
+    } else {
+        // This branch is never taken
+        opaque::f2();
+    }
+}
+
+#[no_mangle]
+#[inline(never)]
+pub fn function_called_42_times(c: char) {
+    if c == 'a' {
+        // This branch is taken 12 times
+        opaque::f1();
+    } else {
+
+        if c == 'b' {
+            // This branch is taken 28 times
+            opaque::f2();
+        } else {
+            // This branch is taken 2 times
+            opaque::f3();
+        }
+    }
+}
+
+#[no_mangle]
+#[inline(never)]
+pub fn function_called_never(_: char) {
+    opaque::f1();
+}
diff --git a/tests/run-make/pgo-branch-weights/main.rs b/tests/run-make/pgo-branch-weights/main.rs
new file mode 100644
index 00000000000..619cf9c698c
--- /dev/null
+++ b/tests/run-make/pgo-branch-weights/main.rs
@@ -0,0 +1,17 @@
+extern crate interesting;
+
+fn main() {
+    let arg = std::env::args().skip(1).next().unwrap();
+
+    for c in arg.chars() {
+        if c == '2' {
+            interesting::function_called_twice(c);
+        } else {
+            interesting::function_called_42_times(c);
+        }
+
+        if c == '0' {
+            interesting::function_called_never(c);
+        }
+    }
+}
diff --git a/tests/run-make/pgo-branch-weights/opaque.rs b/tests/run-make/pgo-branch-weights/opaque.rs
new file mode 100644
index 00000000000..72f93c9feab
--- /dev/null
+++ b/tests/run-make/pgo-branch-weights/opaque.rs
@@ -0,0 +1,6 @@
+#![crate_name="opaque"]
+#![crate_type="rlib"]
+
+pub fn f1() {}
+pub fn f2() {}
+pub fn f3() {}