From 1e4d821136033fb08ac5140127f37f35ff687273 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:22:02 -0400 Subject: [PATCH 1/4] rewrite pgo-gen to rmake --- src/tools/run-make-support/src/lib.rs | 1 - .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pgo-gen/Makefile | 11 ----------- tests/run-make/pgo-gen/rmake.rs | 18 ++++++++++++++++++ 4 files changed, 18 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/pgo-gen/Makefile create mode 100644 tests/run-make/pgo-gen/rmake.rs diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index af5ae6a8e60..6c1bcc6d7cd 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -272,7 +272,6 @@ pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); - if path.is_file() && closure(&path) { matching_files.push(path); } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 70c1b055c6e..97990e59235 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -109,7 +109,6 @@ run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile -run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile diff --git a/tests/run-make/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile deleted file mode 100644 index c1d456986fb..00000000000 --- a/tests/run-make/pgo-gen/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)" - -all: - $(RUSTC) $(COMPILE_FLAGS) test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1) diff --git a/tests/run-make/pgo-gen/rmake.rs b/tests/run-make/pgo-gen/rmake.rs new file mode 100644 index 00000000000..d35b2930264 --- /dev/null +++ b/tests/run-make/pgo-gen/rmake.rs @@ -0,0 +1,18 @@ +// -C profile-generate, when used with rustc, is supposed to output +// profile files (.profraw) after running a binary to analyze how the compiler +// optimizes code. This test checks that these files are generated. +// See https://github.com/rust-lang/rust/pull/48346 + +//@ needs-profiler-support +//@ ignore-cross-compile + +use run_make_support::{cwd, find_files_by_prefix_and_extension, run, rustc}; + +fn main() { + rustc().arg("-g").profile_generate(cwd()).run(); + run("test"); + assert!( + find_files_by_prefix_and_extension(cwd(), "default", "profraw").len() > 0, + "no .profraw file generated" + ); +} From a1555eb0d618eb1abae39d07e6428e2688788b7b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:46:20 -0400 Subject: [PATCH 2/4] rewrite pgo-use to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pgo-use/Makefile | 43 --------------- tests/run-make/pgo-use/rmake.rs | 54 +++++++++++++++++++ 3 files changed, 54 insertions(+), 44 deletions(-) delete mode 100644 tests/run-make/pgo-use/Makefile create mode 100644 tests/run-make/pgo-use/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 97990e59235..2050189cead 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -110,7 +110,6 @@ run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile run-make/pgo-indirect-call-promotion/Makefile -run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile diff --git a/tests/run-make/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile deleted file mode 100644 index 92098a4019c..00000000000 --- a/tests/run-make/pgo-use/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -# 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. -# -# Disable the pre-inlining pass (i.e. a pass that does some inlining before -# it adds the profiling instrumentation). Disabling this pass leads to -# rather predictable IR which we need for this test to be stable. - -COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline - -ifeq ($(UNAME),Darwin) -# macOS does not have the `tac` command, but `tail -r` does the same thing -TAC := tail -r -else -# some other platforms don't support the `-r` flag for `tail`, so use `tac` -TAC := tac -endif - -all: - # Compile the test program with instrumentation - $(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs - # Run it in order to generate some profiling data - $(call RUN,main some-argument) || exit 1 - # Postprocess the profiling data so it can be used by the compiler - "$(LLVM_BIN_DIR)"/llvm-profdata merge \ - -o "$(TMPDIR)"/merged.profdata \ - "$(TMPDIR)"/default_*.profraw - # Compile the test program again, making use of the profiling data - $(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs - # Check that the generate IR contains some things that we expect - # - # We feed the file into LLVM FileCheck tool *in reverse* so that we see the - # line with the function name before the line with the function attributes. - # FileCheck only supports checking that something matches on the next line, - # but not if something matches on the previous line. - $(TAC) "$(TMPDIR)"/main.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs new file mode 100644 index 00000000000..04777821b51 --- /dev/null +++ b/tests/run-make/pgo-use/rmake.rs @@ -0,0 +1,54 @@ +// 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` where actual execution only ever takes the +// `else` branch. Accordingly, we expect the function that is never called to +// be marked as cold. +// See https://github.com/rust-lang/rust/pull/60262 + +//@ needs-profiler-support +//@ ignore-cross-compile + +use run_make_support::{ + cwd, find_files_by_prefix_and_extension, fs_wrapper, llvm_filecheck, llvm_profdata, + run_with_args, rustc, +}; + +fn main() { + // Compile the test program with instrumentation + // Disable the pre-inlining pass (i.e. a pass that does some inlining before + // it adds the profiling instrumentation). Disabling this pass leads to + // rather predictable IR which we need for this test to be stable. + rustc() + .opt_level("2") + .codegen_units(1) + .arg("-Cllvm-args=-disable-preinline") + .profile_generate(cwd()) + .input("main.rs") + .run(); + // Run it in order to generate some profiling data + run_with_args("main", &["some-argument"]); + // Postprocess the profiling data so it can be used by the compiler + llvm_profdata() + .merge() + .output("merged.profdata") + .input(find_files_by_prefix_and_extension(cwd(), "default", "profraw").get(0).unwrap()) + .run(); + // Compile the test program again, making use of the profiling data + rustc() + .opt_level("2") + .codegen_units(1) + .arg("-Cllvm-args=-disable-preinline") + .profile_use("merged.profdata") + .emit("llvm-ir") + .input("main.rs") + .run(); + // Check that the generate IR contains some things that we expect + // + // We feed the file into LLVM FileCheck tool *in reverse* so that we see the + // line with the function name before the line with the function attributes. + // FileCheck only supports checking that something matches on the next line, + // but not if something matches on the previous line. + let mut bytes = fs_wrapper::read("interesting.ll"); + bytes.reverse(); + llvm_filecheck().patterns("filecheck-patterns.txt").stdin(bytes).run(); +} From b15e72a9ed8f34b98d32eba2eb5d3a3d9befea77 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:58:48 -0400 Subject: [PATCH 3/4] rewrite profile to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/profile/Makefile | 13 ----------- tests/run-make/profile/rmake.rs | 22 +++++++++++++++++++ 3 files changed, 22 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/profile/Makefile create mode 100644 tests/run-make/profile/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2050189cead..0cb3275d7e9 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -113,7 +113,6 @@ run-make/pgo-indirect-call-promotion/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile -run-make/profile/Makefile run-make/prune-link-args/Makefile run-make/raw-dylib-alt-calling-convention/Makefile run-make/raw-dylib-c/Makefile diff --git a/tests/run-make/profile/Makefile b/tests/run-make/profile/Makefile deleted file mode 100644 index 7919b18ba74..00000000000 --- a/tests/run-make/profile/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -all: - $(RUSTC) -g -Z profile test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1) - [ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1) - $(RUSTC) -g -Z profile -Z profile-emit=$(TMPDIR)/abc/abc.gcda test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)/abc/abc.gcda" ] || (echo "gcda file not emitted to defined path"; exit 1) diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs new file mode 100644 index 00000000000..8d41978baec --- /dev/null +++ b/tests/run-make/profile/rmake.rs @@ -0,0 +1,22 @@ +// This test revolves around the rustc flag -Z profile, which should +// generate a .gcno file (initial profiling information) as well +// as a .gcda file (branch counters). The path where these are emitted +// should also be configurable with -Z profile-emit. This test checks +// that the files are produced, and then that the latter flag is respected. +// See https://github.com/rust-lang/rust/pull/42433 + +//@ ignore-cross-compile +//@ needs-profiler-support + +use run_make_support::{run, rustc}; +use std::path::Path; + +fn main() { + rustc().arg("-g").arg("-Zprofile").input("test.rs").run(); + run("test"); + assert!(Path::new("test.gcno").exists(), "no .gcno file"); + assert!(Path::new("test.gcda").exists(), "no .gcda file"); + rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run(); + run("test"); + assert!(Path::new("abc/abc.gcda").exists(), "gcda file not emitted to defined path"); +} From c9be69fd0a6214902749338074c7617cb9f40366 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 13:51:53 -0400 Subject: [PATCH 4/4] Add shallow_find_files helper function to run-make-support --- src/tools/run-make-support/src/lib.rs | 1 + tests/run-make/pgo-gen/rmake.rs | 12 ++++++------ tests/run-make/pgo-use/rmake.rs | 27 ++++++++++++++------------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 6c1bcc6d7cd..af5ae6a8e60 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -272,6 +272,7 @@ pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); + if path.is_file() && closure(&path) { matching_files.push(path); } diff --git a/tests/run-make/pgo-gen/rmake.rs b/tests/run-make/pgo-gen/rmake.rs index d35b2930264..ad2f6388e8f 100644 --- a/tests/run-make/pgo-gen/rmake.rs +++ b/tests/run-make/pgo-gen/rmake.rs @@ -6,13 +6,13 @@ //@ needs-profiler-support //@ ignore-cross-compile -use run_make_support::{cwd, find_files_by_prefix_and_extension, run, rustc}; +use run_make_support::{cwd, has_extension, has_prefix, run, rustc, shallow_find_files}; fn main() { - rustc().arg("-g").profile_generate(cwd()).run(); + rustc().arg("-g").profile_generate(cwd()).input("test.rs").run(); run("test"); - assert!( - find_files_by_prefix_and_extension(cwd(), "default", "profraw").len() > 0, - "no .profraw file generated" - ); + let profraw_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "default") && has_extension(path, "profraw") + }); + assert!(!profraw_files.is_empty(), "no .profraw file generated"); } diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs index 04777821b51..0f76aff80d0 100644 --- a/tests/run-make/pgo-use/rmake.rs +++ b/tests/run-make/pgo-use/rmake.rs @@ -9,8 +9,8 @@ //@ ignore-cross-compile use run_make_support::{ - cwd, find_files_by_prefix_and_extension, fs_wrapper, llvm_filecheck, llvm_profdata, - run_with_args, rustc, + cwd, fs_wrapper, has_extension, has_prefix, llvm_filecheck, llvm_profdata, run_with_args, + rustc, shallow_find_files, }; fn main() { @@ -28,11 +28,11 @@ fn main() { // Run it in order to generate some profiling data run_with_args("main", &["some-argument"]); // Postprocess the profiling data so it can be used by the compiler - llvm_profdata() - .merge() - .output("merged.profdata") - .input(find_files_by_prefix_and_extension(cwd(), "default", "profraw").get(0).unwrap()) - .run(); + let profraw_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "default") && has_extension(path, "profraw") + }); + let profraw_file = profraw_files.get(0).unwrap(); + llvm_profdata().merge().output("merged.profdata").input(profraw_file).run(); // Compile the test program again, making use of the profiling data rustc() .opt_level("2") @@ -42,13 +42,14 @@ fn main() { .emit("llvm-ir") .input("main.rs") .run(); - // Check that the generate IR contains some things that we expect - // - // We feed the file into LLVM FileCheck tool *in reverse* so that we see the + // Check that the generate IR contains some things that we expect. + // We feed the file into LLVM FileCheck tool *with its lines reversed* so that we see the // line with the function name before the line with the function attributes. // FileCheck only supports checking that something matches on the next line, // but not if something matches on the previous line. - let mut bytes = fs_wrapper::read("interesting.ll"); - bytes.reverse(); - llvm_filecheck().patterns("filecheck-patterns.txt").stdin(bytes).run(); + let ir = fs_wrapper::read_to_string("main.ll"); + let lines: Vec<_> = ir.lines().rev().collect(); + let mut reversed_ir = lines.join("\n"); + reversed_ir.push('\n'); + llvm_filecheck().patterns("filecheck-patterns.txt").stdin(reversed_ir.as_bytes()).run(); }