Message ID | 20210307042538.21229-18-marek.behun@nic.cz |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | U-Boot LTO (Sandbox + Some ARM boards) | expand |
On Sun, Mar 7, 2021 at 12:26 PM Marek Behún <marek.behun@nic.cz> wrote: > > Add plumbing for building U-Boot with Link Time Optimizations. > > Signed-off-by: Marek Behún <marek.behun@nic.cz> > --- > Kbuild | 2 ++ > Kconfig | 19 +++++++++++++++++++ > Makefile | 36 ++++++++++++++++++++++++++++++++++++ > scripts/Makefile.lib | 3 +++ > scripts/Makefile.spl | 14 ++++++++++++++ > 5 files changed, 74 insertions(+) > > 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 nits: this line is not needed as the default value is n if omitted > + 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 6dc47810ea..4eee0c4196 100644 > --- a/Makefile > +++ b/Makefile > @@ -677,6 +677,28 @@ else > KBUILD_CFLAGS += -O2 > endif > > +LTO_CFLAGS := > +LTO_FINAL_LDFLAGS := > +export LTO_CFLAGS LTO_FINAL_LDFLAGS > +ifdef CONFIG_LTO > + LTO_CFLAGS := -flto > + LTO_FINAL_LDFLAGS := -fwhole-program This one should not be necessary per my read of the GCC doc. Also in your patch, it is only used in the SPL build. > + > + CFLAGS_NON_EFI += $(LTO_CFLAGS) > + > + ifeq ($(cc-name),clang) > + LTO_FINAL_LDFLAGS += -flto > + else > + LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=jobserver > + > + # use plugin aware tools > + AR = $(CROSS_COMPILE)gcc-ar > + NM = $(CROSS_COMPILE)gcc-nm > + endif > + > + KBUILD_CFLAGS += $(LTO_CFLAGS) > +endif > + > KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) > KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) > > @@ -1751,6 +1773,19 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) > > # Rule to link u-boot > # May be overridden by arch/$(ARCH)/config.mk > +ifdef CONFIG_LTO > +quiet_cmd_u-boot__ ?= LTO $@ > + cmd_u-boot__ ?= \ > + $(CC) -nostdlib -nostartfiles \ > + $(LTO_FINAL_CFLAGS) $(c_flags) \ LTO_FINAL_CFLAGS is not defined anywhere. I guess you wanted to use LTO_FINAL_LDFLAGS? > + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) -o $@ \ > + -T u-boot.lds $(u-boot-init) \ > + -Wl,--start-group -Wl,--whole-archive \ --start-group should be dropped > + $(u-boot-main) \ > + -Wl,--no-whole-archive -Wl,--end-group \ > + $(PLATFORM_LIBS) -Wl,-Map,u-boot.map; \ > + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) > +else > quiet_cmd_u-boot__ ?= LD $@ > cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ > -T u-boot.lds $(u-boot-init) \ > @@ -1759,6 +1794,7 @@ quiet_cmd_u-boot__ ?= LD $@ > --no-whole-archive --end-group \ > $(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/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 889debb93c..6da5883442 100644 > --- a/scripts/Makefile.spl > +++ b/scripts/Makefile.spl > @@ -419,6 +419,19 @@ $(obj)/$(SPL_BIN).sym: $(obj)/$(SPL_BIN) FORCE > > # Rule to link u-boot-spl > # May be overridden by arch/$(ARCH)/config.mk > +ifdef CONFIG_LTO > +quiet_cmd_u-boot-spl ?= 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,--start-group -Wl,--whole-archive \ > + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ > + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ > + -Wl,--no-whole-archive -Wl,--end-group \ > + $(PLATFORM_LIBS) -Wl,-Map,$(SPL_BIN).map -o $(SPL_BIN) \ > + ) > +else > quiet_cmd_u-boot-spl ?= LD $@ > cmd_u-boot-spl ?= (cd $(obj) && \ > $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \ > @@ -429,6 +442,7 @@ quiet_cmd_u-boot-spl ?= LD $@ > --no-whole-archive --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
On Tue, 9 Mar 2021 21:30:26 +0800 Bin Meng <bmeng.cn@gmail.com> wrote: > > +config LTO > > + bool "Enable Link Time Optimizations" > > + depends on ARCH_SUPPORTS_LTO > > + default n > > nits: this line is not needed as the default value is n if omitted This is for consistency. The other options in this file also use "default n" > > +ifdef CONFIG_LTO > > + LTO_CFLAGS := -flto > > + LTO_FINAL_LDFLAGS := -fwhole-program > > This one should not be necessary per my read of the GCC doc. Also in > your patch, it is only used in the SPL build. I shall do some tests. > > +ifdef CONFIG_LTO > > +quiet_cmd_u-boot__ ?= LTO $@ > > + cmd_u-boot__ ?= \ > > + $(CC) -nostdlib -nostartfiles \ > > + $(LTO_FINAL_CFLAGS) $(c_flags) \ > > LTO_FINAL_CFLAGS is not defined anywhere. I guess you wanted to use > LTO_FINAL_LDFLAGS? THX, I forgot to change it here. We will see if this variable is needed (since it only contains -fwhole-program, which may be dropped) > > > + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) -o $@ \ > > + -T u-boot.lds $(u-boot-init) \ > > + -Wl,--start-group -Wl,--whole-archive \ > > --start-group should be dropped Will test
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 6dc47810ea..4eee0c4196 100644 --- a/Makefile +++ b/Makefile @@ -677,6 +677,28 @@ else KBUILD_CFLAGS += -O2 endif +LTO_CFLAGS := +LTO_FINAL_LDFLAGS := +export LTO_CFLAGS LTO_FINAL_LDFLAGS +ifdef CONFIG_LTO + LTO_CFLAGS := -flto + LTO_FINAL_LDFLAGS := -fwhole-program + + CFLAGS_NON_EFI += $(LTO_CFLAGS) + + ifeq ($(cc-name),clang) + LTO_FINAL_LDFLAGS += -flto + else + LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=jobserver + + # use plugin aware tools + AR = $(CROSS_COMPILE)gcc-ar + NM = $(CROSS_COMPILE)gcc-nm + endif + + KBUILD_CFLAGS += $(LTO_CFLAGS) +endif + KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) @@ -1751,6 +1773,19 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk +ifdef CONFIG_LTO +quiet_cmd_u-boot__ ?= 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,--start-group -Wl,--whole-archive \ + $(u-boot-main) \ + -Wl,--no-whole-archive -Wl,--end-group \ + $(PLATFORM_LIBS) -Wl,-Map,u-boot.map; \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) +else quiet_cmd_u-boot__ ?= LD $@ cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ -T u-boot.lds $(u-boot-init) \ @@ -1759,6 +1794,7 @@ quiet_cmd_u-boot__ ?= LD $@ --no-whole-archive --end-group \ $(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/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 889debb93c..6da5883442 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -419,6 +419,19 @@ $(obj)/$(SPL_BIN).sym: $(obj)/$(SPL_BIN) FORCE # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk +ifdef CONFIG_LTO +quiet_cmd_u-boot-spl ?= 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,--start-group -Wl,--whole-archive \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + -Wl,--no-whole-archive -Wl,--end-group \ + $(PLATFORM_LIBS) -Wl,-Map,$(SPL_BIN).map -o $(SPL_BIN) \ + ) +else quiet_cmd_u-boot-spl ?= LD $@ cmd_u-boot-spl ?= (cd $(obj) && \ $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \ @@ -429,6 +442,7 @@ quiet_cmd_u-boot-spl ?= LD $@ --no-whole-archive --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
Add plumbing for building U-Boot with Link Time Optimizations. Signed-off-by: Marek Behún <marek.behun@nic.cz> --- Kbuild | 2 ++ Kconfig | 19 +++++++++++++++++++ Makefile | 36 ++++++++++++++++++++++++++++++++++++ scripts/Makefile.lib | 3 +++ scripts/Makefile.spl | 14 ++++++++++++++ 5 files changed, 74 insertions(+)