From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Tue, 17 Nov 2020 22:45:47 +0100 Subject: [PATCH] Fixes for LTO+PGO support Cherry-picked from Firefox Nightly. --- build/moz.configure/lto-pgo.configure | 7 +++++-- config/makefiles/rust.mk | 21 +++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure index 366c6691f7d11..e5342a037ee92 100644 --- a/build/moz.configure/lto-pgo.configure +++ b/build/moz.configure/lto-pgo.configure @@ -229,7 +229,10 @@ def lto(value, c_compiler, ld64_known_good, target, instrumented_build): # instruction sets. else: num_cores = multiprocessing.cpu_count() - cflags.append("-flto") + if len(value) and value[0].lower() == 'full': + cflags.append("-flto") + else: + cflags.append("-flto=thin") cflags.append("-flifetime-dse=1") ldflags.append("-flto=%s" % num_cores) @@ -258,6 +261,6 @@ set_config('MOZ_LTO', lto.enabled) set_define('MOZ_LTO', lto.enabled) set_config('MOZ_LTO_CFLAGS', lto.cflags) set_config('MOZ_LTO_LDFLAGS', lto.ldflags) -set_config('MOZ_LTO_RUST', lto.rust_lto) +set_config('MOZ_LTO_RUST_CROSS', lto.rust_lto) add_old_configure_assignment('MOZ_LTO_CFLAGS', lto.cflags) add_old_configure_assignment('MOZ_LTO_LDFLAGS', lto.ldflags) diff --git a/config/makefiles/rust.mk b/config/makefiles/rust.mk index b5c7973104ceb..079408b358edb 100644 --- a/config/makefiles/rust.mk +++ b/config/makefiles/rust.mk @@ -59,17 +59,19 @@ cargo_rustc_flags = $(CARGO_RUSTCFLAGS) ifndef DEVELOPER_OPTIONS ifndef MOZ_DEBUG_RUST # Enable link-time optimization for release builds, but not when linking -# gkrust_gtest. +# gkrust_gtest. And not when doing cross-language LTO. +ifndef MOZ_LTO_RUST_CROSS ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE))) cargo_rustc_flags += -Clto endif # Versions of rust >= 1.45 need -Cembed-bitcode=yes for all crates when # using -Clto. ifeq (,$(filter 1.38.% 1.39.% 1.40.% 1.41.% 1.42.% 1.43.% 1.44.%,$(RUSTC_VERSION))) RUSTFLAGS += -Cembed-bitcode=yes endif endif endif +endif ifdef CARGO_INCREMENTAL export CARGO_INCREMENTAL @@ -185,10 +187,19 @@ target_rust_ltoable := force-cargo-library-build target_rust_nonltoable := force-cargo-test-run force-cargo-library-check $(foreach b,build check,force-cargo-program-$(b)) ifdef MOZ_PGO_RUST -rust_pgo_flags := $(if $(MOZ_PROFILE_GENERATE),-C profile-generate=$(topobjdir)) $(if $(MOZ_PROFILE_USE),-C profile-use=$(PGO_PROFILE_PATH)) +ifdef MOZ_PROFILE_GENERATE +rust_pgo_flags := -C profile-generate=$(topobjdir) +# The C compiler may be passed extra llvm flags for PGO that we also want to pass to rust as well. +# In PROFILE_GEN_CFLAGS, they look like "-mllvm foo", and we want "-C llvm-args=foo", so first turn +# "-mllvm foo" into "-mllvm:foo" so that it becomes a unique argument, that we can then filter for, +# excluding other flags, and then turn into the right string. +rust_pgo_flags += $(patsubst -mllvm:%,-C llvm-args=%,$(filter -mllvm:%,$(subst -mllvm ,-mllvm:,$(PROFILE_GEN_CFLAGS)))) +else # MOZ_PROFILE_USE +rust_pgo_flags := -C profile-use=$(PGO_PROFILE_PATH) +endif endif -$(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) $(if $(MOZ_LTO_RUST),-Clinker-plugin-lto) $(rust_pgo_flags) +$(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) $(if $(MOZ_LTO_RUST_CROSS),-Clinker-plugin-lto) $(rust_pgo_flags) $(target_rust_nonltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) TARGET_RECIPES := $(target_rust_ltoable) $(target_rust_nonltoable) @@ -302,17 +313,19 @@ $(RUST_LIBRARY_FILE): force-cargo-library-build # When we are building in --enable-release mode; we add an additional check to confirm # that we are not importing any networking-related functions in rust code. This reduces # the chance of proxy bypasses originating from rust code. -# The check only works when rust code is built with -Clto. +# The check only works when rust code is built with -Clto but without MOZ_LTO_RUST_CROSS. # Sanitizers and sancov also fail because compiler-rt hooks network functions. ifndef MOZ_PROFILE_GENERATE ifeq ($(OS_ARCH), Linux) ifeq (,$(rustflags_sancov)$(MOZ_ASAN)$(MOZ_TSAN)$(MOZ_UBSAN)) +ifndef MOZ_LTO_RUST_CROSS ifneq (,$(filter -Clto,$(cargo_rustc_flags))) $(call py_action,check_binary,--target --networking $@) endif endif endif endif +endif force-cargo-library-check: $(call CARGO_CHECK) --lib $(cargo_target_flag) $(rust_features_flag)