
Add plumbing for building U-Boot with Link Time Optimizations (gcc only).
Signed-off-by: Marek Behún marek.behun@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 + + 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