[RFC PATCH u-boot 06/12] build: support building with Link Time Optimizations

Marek Behún marek.behun at nic.cz
Wed Mar 3 05:12:05 CET 2021


Add plumbing for building U-Boot with Link Time Optimizations (gcc
only).

Signed-off-by: Marek Behún <marek.behun at 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
-- 
2.26.2



More information about the U-Boot mailing list