On Wed, Mar 3, 2021 at 12:13 PM Marek Behún <marek.be...@nic.cz> wrote: > > Add plumbing for building U-Boot with Link Time Optimizations (gcc > only). > > Signed-off-by: Marek Behún <marek.be...@nic.cz> > --- > Kbuild | 2 ++ > Kconfig | 19 +++++++++++++++++++ > Makefile | 26 ++++++++++++++++++++++++++ > lib/efi_loader/Makefile | 2 +- > scripts/Makefile.lib | 3 +++ > scripts/Makefile.spl | 13 +++++++++++++ > 6 files changed, 64 insertions(+), 1 deletion(-) > > diff --git a/Kbuild b/Kbuild > index 1eac091594..bf52e54051 100644 > --- a/Kbuild > +++ b/Kbuild > @@ -10,6 +10,8 @@ generic-offsets-file := > include/generated/generic-asm-offsets.h > always := $(generic-offsets-file) > targets := lib/asm-offsets.s > > +CFLAGS_REMOVE_asm-offsets.o := $(LTO_CFLAGS) > + > $(obj)/$(generic-offsets-file): $(obj)/lib/asm-offsets.s FORCE > $(call filechk,offsets,__GENERIC_ASM_OFFSETS_H__) > > diff --git a/Kconfig b/Kconfig > index 86f0a39bb0..ceba53926f 100644 > --- a/Kconfig > +++ b/Kconfig > @@ -85,6 +85,25 @@ config SPL_OPTIMIZE_INLINING > do what it thinks is best, which is desirable in some cases for size > reasons. > > +config ARCH_SUPPORTS_LTO > + bool > + > +config LTO > + bool "Enable Link Time Optimizations" > + depends on ARCH_SUPPORTS_LTO > + default n > + help > + This option enables Link Time Optimization (LTO), a mechanism which > + allows the compiler to optimize between different compilation units. > + > + This can optimize away dead code paths, resulting in smaller binary > + size (if CC_OPTIMIZE_FOR_SIZE is enabled). > + > + This option is not available for every architecture and may > + introduce bugs. > + > + If unsure, say n. > + > config TPL_OPTIMIZE_INLINING > bool "Allow compiler to uninline functions marked 'inline' in TPL" > depends on TPL > diff --git a/Makefile b/Makefile > index 33d0b80de8..88600ec101 100644 > --- a/Makefile > +++ b/Makefile > @@ -677,6 +677,21 @@ else > KBUILD_CFLAGS += -O2 > endif > > +LTO_CFLAGS := > +LTO_FINAL_LDFLAGS := > +export LTO_CFLAGS LTO_FINAL_LDFLAGS > +ifdef CONFIG_LTO > + # use plugin aware tools > + AR = $(CROSS_COMPILE)gcc-ar > + NM = $(CROSS_COMPILE)gcc-nm > + > + LTO_CFLAGS := -flto > + LTO_FINAL_LDFLAGS := -fuse-linker-plugin -flto=jobserver \ > + -fwhole-program
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html says: -fwhole-program Assume that the current compilation unit represents the whole program being compiled. All public functions and variables with the exception of main and those merged by attribute externally_visible become static functions and in effect are optimized more aggressively by interprocedural optimizers. This option should not be used in combination with -flto. Instead relying on a linker plugin should provide safer and more precise information. It suggests this option should not be used in combination with -flto. > + > + KBUILD_CFLAGS += $(LTO_CFLAGS) > +endif > + > KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) > KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) > > @@ -1748,11 +1763,22 @@ ARCH_POSTLINK := $(wildcard > $(srctree)/arch/$(ARCH)/Makefile.postlink) > # Rule to link u-boot > # May be overridden by arch/$(ARCH)/config.mk > quiet_cmd_u-boot__ ?= LD $@ > +ifdef CONFIG_LTO > + cmd_u-boot__ ?= $(CC) -nostdlib -nostartfiles > \ > + $(LTO_FINAL_CFLAGS) $(c_flags) > \ > + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) > \ > + -o $@ -T u-boot.lds $(u-boot-init) > \ > + -Wl,--whole-archive > \ > + $(u-boot-main) $(PLATFORM_LIBS) > \ > + -Wl,--no-whole-archive -Wl,-Map,u-boot.map; > \ > + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) > +else > cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ > -T u-boot.lds $(u-boot-init) \ > --whole-archive $(u-boot-main) --no-whole-archive \ > $(PLATFORM_LIBS) -Map u-boot.map; \ > $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) > +endif > > quiet_cmd_smap = GEN common/system_map.o > cmd_smap = \ > diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile > index 10b42e8847..a5a6639fd3 100644 > --- a/lib/efi_loader/Makefile > +++ b/lib/efi_loader/Makefile > @@ -13,7 +13,7 @@ CFLAGS_efi_boottime.o += \ > -DFW_VERSION="0x$(VERSION)" \ > -DFW_PATCHLEVEL="0x$(PATCHLEVEL)" > CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding > -CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) > +CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) $(LTO_CFLAGS) > > ifneq ($(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),) > always += helloworld.efi > diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib > index 78543c6dd1..78bbebe7e9 100644 > --- a/scripts/Makefile.lib > +++ b/scripts/Makefile.lib > @@ -419,6 +419,9 @@ $(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o > $(obj)/efi_reloc.o $(obj)/efi_free > > targets += $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/efi_freestanding.o > > +CFLAGS_REMOVE_efi_reloc.o := $(LTO_CFLAGS) > +CFLAGS_REMOVE_efi_freestanding.o := $(LTO_CFLAGS) > + > # ACPI > # --------------------------------------------------------------------------- > # > diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl > index f9faf804de..b7cab2d302 100644 > --- a/scripts/Makefile.spl > +++ b/scripts/Makefile.spl > @@ -420,11 +420,24 @@ $(obj)/$(SPL_BIN).sym: $(obj)/$(SPL_BIN) FORCE > # Rule to link u-boot-spl > # May be overridden by arch/$(ARCH)/config.mk > quiet_cmd_u-boot-spl ?= LD $@ > +ifdef CONFIG_LTO > + cmd_u-boot-spl ?= (cd $(obj) && > \ > + $(CC) -nostdlib -nostartfiles $(LTO_FINAL_LDFLAGS) $(c_flags) > \ > + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_$(@F):%=-Wl,%) > \ > + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) > \ > + -Wl,--whole-archive > \ > + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) > $(PLATFORM_LIBS) \ > + -Wl,--no-whole-archive > \ > + -Wl,--start-group $(patsubst > $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \ > + -Wl,-Map,$(SPL_BIN).map -o $(SPL_BIN) > \ > + ) > +else > cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(KBUILD_LDFLAGS) > $(LDFLAGS_$(@F)) \ > $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ > --whole-archive $(patsubst > $(obj)/%,%,$(u-boot-spl-main)) --no-whole-archive \ > --start-group $(patsubst > $(obj)/%,%,$(u-boot-spl-platdata)) --end-group \ > $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN)) > +endif > > $(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \ > $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE > -- Regards, Bin