Skip to content

Commit

Permalink
Stabilize profile-guided optimization.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Jun 21, 2019
1 parent 314194e commit b7fe2ca
Show file tree
Hide file tree
Showing 14 changed files with 35 additions and 36 deletions.
25 changes: 12 additions & 13 deletions src/librustc/session/config.rs
Expand Up @@ -1221,7 +1221,11 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
parse_linker_plugin_lto, [TRACKED], parse_linker_plugin_lto, [TRACKED],
"generate build artifacts that are compatible with linker-based LTO."), "generate build artifacts that are compatible with linker-based LTO."),

profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
parse_switch_with_opt_path, [TRACKED],
"compile the program with profiling instrumentation"),
profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"use the given `.profdata` file for profile-guided optimization"),
} }


options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
Expand Down Expand Up @@ -1395,11 +1399,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"extra arguments to prepend to the linker invocation (space separated)"), "extra arguments to prepend to the linker invocation (space separated)"),
profile: bool = (false, parse_bool, [TRACKED], profile: bool = (false, parse_bool, [TRACKED],
"insert profiling code"), "insert profiling code"),
pgo_gen: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
parse_switch_with_opt_path, [TRACKED],
"Generate PGO profile data, to a given file, or to the default location if it's empty."),
pgo_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"Use PGO profile data from the given profile file."),
disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED], disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED],
"Disable the instrumentation pre-inliner, useful for profiling / PGO."), "Disable the instrumentation pre-inliner, useful for profiling / PGO."),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
Expand Down Expand Up @@ -2052,13 +2051,6 @@ pub fn build_session_options_and_crate_config(
} }
} }


if debugging_opts.pgo_gen.enabled() && debugging_opts.pgo_use.is_some() {
early_error(
error_format,
"options `-Z pgo-gen` and `-Z pgo-use` are exclusive",
);
}

let mut output_types = BTreeMap::new(); let mut output_types = BTreeMap::new();
if !debugging_opts.parse_only { if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") { for list in matches.opt_strs("emit") {
Expand Down Expand Up @@ -2170,6 +2162,13 @@ pub fn build_session_options_and_crate_config(
); );
} }


if cg.profile_generate.enabled() && cg.profile_use.is_some() {
early_error(
error_format,
"options `-C profile-generate` and `-C profile-use` are exclusive",
);
}

let mut prints = Vec::<PrintRequest>::new(); let mut prints = Vec::<PrintRequest>::new();
if cg.target_cpu.as_ref().map_or(false, |s| s == "help") { if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
prints.push(PrintRequest::TargetCPUs); prints.push(PrintRequest::TargetCPUs);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/session/config/tests.rs
Expand Up @@ -519,11 +519,11 @@ fn test_codegen_options_tracking_hash() {
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());


opts = reference.clone(); opts = reference.clone();
opts.debugging_opts.pgo_gen = SwitchWithOptPath::Enabled(None); opts.cg.profile_generate = SwitchWithOptPath::Enabled(None);
assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());


opts = reference.clone(); opts = reference.clone();
opts.debugging_opts.pgo_use = Some(PathBuf::from("abc")); opts.cg.profile_use = Some(PathBuf::from("abc"));
assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());


opts = reference.clone(); opts = reference.clone();
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/session/mod.rs
Expand Up @@ -1290,9 +1290,9 @@ fn validate_commandline_args_with_session_available(sess: &Session) {


// Make sure that any given profiling data actually exists so LLVM can't // Make sure that any given profiling data actually exists so LLVM can't
// decide to silently skip PGO. // decide to silently skip PGO.
if let Some(ref path) = sess.opts.debugging_opts.pgo_use { if let Some(ref path) = sess.opts.cg.profile_use {
if !path.exists() { if !path.exists() {
sess.err(&format!("File `{}` passed to `-Zpgo-use` does not exist.", sess.err(&format!("File `{}` passed to `-C profile-use` does not exist.",
path.display())); path.display()));
} }
} }
Expand All @@ -1301,7 +1301,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
// an error to combine the two for now. It always runs into an assertions // an error to combine the two for now. It always runs into an assertions
// if LLVM is built with assertions, but without assertions it sometimes // if LLVM is built with assertions, but without assertions it sometimes
// does not crash and will probably generate a corrupted binary. // does not crash and will probably generate a corrupted binary.
if sess.opts.debugging_opts.pgo_gen.enabled() && if sess.opts.cg.profile_generate.enabled() &&
sess.target.target.options.is_like_msvc && sess.target.target.options.is_like_msvc &&
sess.panic_strategy() == PanicStrategy::Unwind { sess.panic_strategy() == PanicStrategy::Unwind {
sess.err("Profile-guided optimization does not yet work in conjunction \ sess.err("Profile-guided optimization does not yet work in conjunction \
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/attributes.rs
Expand Up @@ -102,8 +102,8 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
return return
} }


// probestack doesn't play nice either with pgo-gen. // probestack doesn't play nice either with `-C profile-generate`.
if cx.sess().opts.debugging_opts.pgo_gen.enabled() { if cx.sess().opts.cg.profile_generate.enabled() {
return; return;
} }


Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/back/link.rs
Expand Up @@ -1156,7 +1156,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
cmd.build_static_executable(); cmd.build_static_executable();
} }


if sess.opts.debugging_opts.pgo_gen.enabled() { if sess.opts.cg.profile_generate.enabled() {
cmd.pgo_gen(); cmd.pgo_gen();
} }


Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/back/symbol_export.rs
Expand Up @@ -203,7 +203,7 @@ fn exported_symbols_provider_local<'tcx>(
} }
} }


if tcx.sess.opts.debugging_opts.pgo_gen.enabled() { if tcx.sess.opts.cg.profile_generate.enabled() {
// These are weak symbols that point to the profile version and the // These are weak symbols that point to the profile version and the
// profile name, which need to be treated as exported so LTO doesn't nix // profile name, which need to be treated as exported so LTO doesn't nix
// them. // them.
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_ssa/back/write.rs
Expand Up @@ -423,8 +423,8 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
modules_config.passes.push("insert-gcov-profiling".to_owned()) modules_config.passes.push("insert-gcov-profiling".to_owned())
} }


modules_config.pgo_gen = sess.opts.debugging_opts.pgo_gen.clone(); modules_config.pgo_gen = sess.opts.cg.profile_generate.clone();
modules_config.pgo_use = sess.opts.debugging_opts.pgo_use.clone(); modules_config.pgo_use = sess.opts.cg.profile_use.clone();


modules_config.opt_level = Some(sess.opts.optimize); modules_config.opt_level = Some(sess.opts.optimize);
modules_config.opt_size = Some(sess.opts.optimize); modules_config.opt_size = Some(sess.opts.optimize);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_metadata/creader.rs
Expand Up @@ -868,7 +868,7 @@ impl<'a> CrateLoader<'a> {


fn inject_profiler_runtime(&mut self) { fn inject_profiler_runtime(&mut self) {
if self.sess.opts.debugging_opts.profile || if self.sess.opts.debugging_opts.profile ||
self.sess.opts.debugging_opts.pgo_gen.enabled() self.sess.opts.cg.profile_generate.enabled()
{ {
info!("loading profiler"); info!("loading profiler");


Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/pgo-instrumentation.rs
@@ -1,8 +1,8 @@
// Test that `-Zpgo-gen` creates expected instrumentation artifacts in LLVM IR. // Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR.
// Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms. // Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms.


// needs-profiler-support // needs-profiler-support
// compile-flags: -Z pgo-gen -Ccodegen-units=1 -Cpanic=abort // compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort


// CHECK: @__llvm_profile_raw_version = // CHECK: @__llvm_profile_raw_version =
// CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global // CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global
Expand Down
Expand Up @@ -21,7 +21,7 @@ all: cpp-executable rust-executable


cpp-executable: cpp-executable:
$(RUSTC) -Clinker-plugin-lto=on \ $(RUSTC) -Clinker-plugin-lto=on \
-Zpgo-gen="$(TMPDIR)"/cpp-profdata \ -Cprofile-generate="$(TMPDIR)"/cpp-profdata \
-o "$(TMPDIR)"/librustlib-xlto.a \ -o "$(TMPDIR)"/librustlib-xlto.a \
$(COMMON_FLAGS) \ $(COMMON_FLAGS) \
./rustlib.rs ./rustlib.rs
Expand All @@ -39,7 +39,7 @@ cpp-executable:
-o "$(TMPDIR)"/cpp-profdata/merged.profdata \ -o "$(TMPDIR)"/cpp-profdata/merged.profdata \
"$(TMPDIR)"/cpp-profdata/default_*.profraw "$(TMPDIR)"/cpp-profdata/default_*.profraw
$(RUSTC) -Clinker-plugin-lto=on \ $(RUSTC) -Clinker-plugin-lto=on \
-Zpgo-use="$(TMPDIR)"/cpp-profdata/merged.profdata \ -Cprofile-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
-o "$(TMPDIR)"/librustlib-xlto.a \ -o "$(TMPDIR)"/librustlib-xlto.a \
$(COMMON_FLAGS) \ $(COMMON_FLAGS) \
./rustlib.rs ./rustlib.rs
Expand All @@ -57,7 +57,7 @@ rust-executable:
$(CLANG) ./clib.c -fprofile-generate="$(TMPDIR)"/rs-profdata -flto=thin -c -o $(TMPDIR)/clib.o -O3 $(CLANG) ./clib.c -fprofile-generate="$(TMPDIR)"/rs-profdata -flto=thin -c -o $(TMPDIR)/clib.o -O3
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
$(RUSTC) -Clinker-plugin-lto=on \ $(RUSTC) -Clinker-plugin-lto=on \
-Zpgo-gen="$(TMPDIR)"/rs-profdata \ -Cprofile-generate="$(TMPDIR)"/rs-profdata \
-L$(TMPDIR) \ -L$(TMPDIR) \
$(COMMON_FLAGS) \ $(COMMON_FLAGS) \
-Clinker=$(CLANG) \ -Clinker=$(CLANG) \
Expand All @@ -78,7 +78,7 @@ rust-executable:
rm "$(TMPDIR)"/libxyz.a rm "$(TMPDIR)"/libxyz.a
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
$(RUSTC) -Clinker-plugin-lto=on \ $(RUSTC) -Clinker-plugin-lto=on \
-Zpgo-use="$(TMPDIR)"/rs-profdata/merged.profdata \ -Cprofile-use="$(TMPDIR)"/rs-profdata/merged.profdata \
-L$(TMPDIR) \ -L$(TMPDIR) \
$(COMMON_FLAGS) \ $(COMMON_FLAGS) \
-Clinker=$(CLANG) \ -Clinker=$(CLANG) \
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/pgo-gen-lto/Makefile
Expand Up @@ -2,7 +2,7 @@


-include ../tools.mk -include ../tools.mk


COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)" COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)"


# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
# https://github.com/rust-lang/rust/issues/61002 # https://github.com/rust-lang/rust/issues/61002
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
Expand Up @@ -2,7 +2,7 @@


-include ../tools.mk -include ../tools.mk


COMPILE_FLAGS=-O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)" COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)"


# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
# https://github.com/rust-lang/rust/issues/61002 # https://github.com/rust-lang/rust/issues/61002
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/pgo-gen/Makefile
Expand Up @@ -2,7 +2,7 @@


-include ../tools.mk -include ../tools.mk


COMPILE_FLAGS=-g -Z pgo-gen="$(TMPDIR)" COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)"


# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
# https://github.com/rust-lang/rust/issues/61002 # https://github.com/rust-lang/rust/issues/61002
Expand Down
4 changes: 2 additions & 2 deletions src/test/run-make-fulldeps/pgo-use/Makefile
Expand Up @@ -33,15 +33,15 @@ endif


all: all:
# Compile the test program with instrumentation # Compile the test program with instrumentation
$(RUSTC) $(COMMON_FLAGS) -Z pgo-gen="$(TMPDIR)" main.rs $(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs
# Run it in order to generate some profiling data # Run it in order to generate some profiling data
$(call RUN,main some-argument) || exit 1 $(call RUN,main some-argument) || exit 1
# Postprocess the profiling data so it can be used by the compiler # Postprocess the profiling data so it can be used by the compiler
"$(LLVM_BIN_DIR)"/llvm-profdata merge \ "$(LLVM_BIN_DIR)"/llvm-profdata merge \
-o "$(TMPDIR)"/merged.profdata \ -o "$(TMPDIR)"/merged.profdata \
"$(TMPDIR)"/default_*.profraw "$(TMPDIR)"/default_*.profraw
# Compile the test program again, making use of the profiling data # Compile the test program again, making use of the profiling data
$(RUSTC) $(COMMON_FLAGS) -Z pgo-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs $(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs
# Check that the generate IR contains some things that we expect # 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 # We feed the file into LLVM FileCheck tool *in reverse* so that we see the
Expand Down

0 comments on commit b7fe2ca

Please sign in to comment.