[PATCH 01/10] Makefile: v2 Allow LTO to be disabled for a build

Andrew Scull ascull at google.com
Thu Mar 31 12:29:11 CEST 2022


On Sun, 27 Mar 2022 at 21:27, Simon Glass <sjg at chromium.org> wrote:
>
> LTO (Link-Time Optimisation) is an very useful feature which can
> significantly reduce the size of U-Boot binaries. So far it has been
> made available for selected ARM boards and sandbox.
>
> However, incremental builds are much slower when LTO is used. For example,
> an incremental build of sandbox takes 2.1 seconds on my machine, but 6.7
> seconds with LTO enabled.

This is something that has been bothering me too. I'd resorted to adding
`# CONFIG_LTO is not set` to sandbox_defconfig because I couldn't work
out how to stop .config being regenerated each build. But then the
diff gets in the way and is difficult to manage.

> Add a LTO_BUILD=n parameter to the build, so it can be disabled during
> development if needed, for faster builds.

If you go the build parameter route rather than config route to
address this, could the flag be consistent e.g. with NO_SDL=1, which
would mean NO_LTO=1?

> Add some documentation about LTO while we are here.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
>  Makefile                           | 18 +++++++++++++-----
>  arch/arm/config.mk                 |  4 ++--
>  arch/arm/include/asm/global_data.h |  2 +-
>  doc/build/gcc.rst                  | 17 +++++++++++++++++
>  scripts/Makefile.spl               |  2 +-
>  5 files changed, 34 insertions(+), 9 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 06572ac07ee..c9585ddebfc 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -434,6 +434,9 @@ KBUILD_CFLAGS       += -fshort-wchar -fno-strict-aliasing
>  KBUILD_AFLAGS   := -D__ASSEMBLY__
>  KBUILD_LDFLAGS  :=
>
> +# Set this to "n" use of LTO for this build, e.g. LTO_BUILD=n
> +LTO_BUILD      ?= y
> +
>  ifeq ($(cc-name),clang)
>  ifneq ($(CROSS_COMPILE),)
>  CLANG_TARGET   := --target=$(notdir $(CROSS_COMPILE:%-=%))
> @@ -643,6 +646,11 @@ export CFLAGS_EFI  # Compiler flags to add when building EFI app
>  export CFLAGS_NON_EFI  # Compiler flags to remove when building EFI app
>  export EFI_TARGET      # binutils target if EFI is natively supported
>
> +export LTO_ENABLE
> +
> +# This is y if LTO is enabled for this build
> +LTO_ENABLE=$(if $(CONFIG_LTO),$(LTO_BUILD),)
> +
>  # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
>  # that (or fail if absent).  Otherwise, search for a linker script in a
>  # standard location.
> @@ -690,16 +698,16 @@ endif
>  LTO_CFLAGS :=
>  LTO_FINAL_LDFLAGS :=
>  export LTO_CFLAGS LTO_FINAL_LDFLAGS
> -ifdef CONFIG_LTO
> +ifeq ($(LTO_ENABLE),y)
>         ifeq ($(cc-name),clang)
> -               LTO_CFLAGS              += -flto
> +               LTO_CFLAGS              += -DLTO_ENABLE -flto
>                 LTO_FINAL_LDFLAGS       += -flto
>
>                 AR                      = $(shell $(CC) -print-prog-name=llvm-ar)
>                 NM                      = $(shell $(CC) -print-prog-name=llvm-nm)
>         else
>                 NPROC                   := $(shell nproc 2>/dev/null || echo 1)
> -               LTO_CFLAGS              += -flto=$(NPROC)
> +               LTO_CFLAGS              += -DLTO_ENABLE -flto=$(NPROC)
>                 LTO_FINAL_LDFLAGS       += -fuse-linker-plugin -flto=$(NPROC)
>
>                 # use plugin aware tools
> @@ -1740,7 +1748,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
>
>  # Generate linker list symbols references to force compiler to not optimize
>  # them away when compiling with LTO
> -ifdef CONFIG_LTO
> +ifeq ($(LTO_ENABLE),y)
>  u-boot-keep-syms-lto := keep-syms-lto.o
>  u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto))
>
> @@ -1762,7 +1770,7 @@ endif
>
>  # Rule to link u-boot
>  # May be overridden by arch/$(ARCH)/config.mk
> -ifdef CONFIG_LTO
> +ifeq ($(LTO_ENABLE),y)
>  quiet_cmd_u-boot__ ?= LTO     $@
>        cmd_u-boot__ ?=                                                          \
>                 $(CC) -nostdlib -nostartfiles                                   \
> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
> index b107b1af27a..065dbec4064 100644
> --- a/arch/arm/config.mk
> +++ b/arch/arm/config.mk
> @@ -15,11 +15,11 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \
>                   -fstack-protector-strong
>  CFLAGS_EFI := -fpic -fshort-wchar
>
> -ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy)
> +ifneq ($(LTO_ENABLE)$(CONFIG_USE_PRIVATE_LIBGCC),yy)
>  LDFLAGS_FINAL += --gc-sections
>  endif
>
> -ifndef CONFIG_LTO
> +ifneq ($(LTO_ENABLE),y)
>  PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
>  endif
>
> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
> index 085e12b5d4d..b255b195aa0 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -98,7 +98,7 @@ struct arch_global_data {
>
>  #include <asm-generic/global_data.h>
>
> -#if defined(__clang__) || defined(CONFIG_LTO)
> +#if defined(__clang__) || defined(LTO_ENABLE)
>
>  #define DECLARE_GLOBAL_DATA_PTR
>  #define gd     get_gd()
> diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst
> index 470a7aa3498..792be176aad 100644
> --- a/doc/build/gcc.rst
> +++ b/doc/build/gcc.rst
> @@ -152,6 +152,23 @@ of dtc is new enough. It also makes sure that pylibfdt is present, if needed
>  Note that the :doc:`tools` are always built with the included version of libfdt
>  so it is not possible to build U-Boot tools with a system libfdt, at present.
>
> +Link-time optimisation (LTO)
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +U-Boot supports link-time optimisation which can reduce the size of the final
> +U-Boot binaries, particularly with SPL.
> +
> +At present this can be enabled by ARM boards by adding `CONFIG_LTO=y` into the
> +defconfig file. Other architectures are not supported. LTO is enabled by default
> +for sandbox.
> +
> +This does incur a link-time penalty of several seconds. For faster incremental
> +builds during development, you can disable it by setting `LTO_BUILD` to `n`.
> +
> +.. code-block:: bash
> +
> +    LTO_BUILD=n make
> +
>  Other build targets
>  ~~~~~~~~~~~~~~~~~~~
>
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index 83a95ee4aa2..e3ca69c4449 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -472,7 +472,7 @@ endif
>
>  # Rule to link u-boot-spl
>  # May be overridden by arch/$(ARCH)/config.mk
> -ifdef CONFIG_LTO
> +ifeq ($(LTO_ENABLE),y)
>  quiet_cmd_u-boot-spl ?= LTO     $@
>        cmd_u-boot-spl ?= \
>         (                                                                       \
> --
> 2.35.1.1021.g381101b075-goog
>


More information about the U-Boot mailing list