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

Bin Meng bmeng.cn at gmail.com
Fri Mar 5 07:34:20 CET 2021


On Wed, Mar 3, 2021 at 12:13 PM Marek Behún <marek.behun at nic.cz> wrote:
>
> 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

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


More information about the U-Boot mailing list