[PATCH v2 02/41] Makefile: Allow LTO to be disabled for a build
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Wed Oct 27 14:21:17 CEST 2021
On 10/27/21 10:50, Ilias Apalodimas wrote:
> Hi Simon
>
> How does this patch related to the standard boot series? Shouldn't
> this be a completely separate patch?
>
> Thanks
> /Ilias
>
> On Sun, 24 Oct 2021 at 02:26, 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.
>>
>> Add a LTO_BUILD=n parameter to the build, so it can be disabled during
>> development if needed, for faster builds.
>>
>> Add some documentation about LTO while we are here.
>>
>> Signed-off-by: Simon Glass <sjg at chromium.org>
>> ---
>>
>> (no changes since v1)
>>
>> Makefile | 18 +++++++++++++-----
>> arch/arm/config.mk | 4 ++--
>> arch/arm/include/asm/global_data.h | 2 +-
>> doc/build/gcc.rst | 17 +++++++++++++++++
>> 4 files changed, 33 insertions(+), 8 deletions(-)
>>
>> diff --git a/Makefile b/Makefile
>> index b79b2319ff6..7057723e046 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
This does not allow LTO_BUILD=y to enable LTO for CONFIG_LTO=n.
We should have something like
LTO_CONFIG ?= $CONFIG_LTO
Best regards
Heinrich
>> +
>> ifeq ($(cc-name),clang)
>> ifneq ($(CROSS_COMPILE),)
>> CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%))
>> @@ -641,6 +644,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.
>> @@ -688,16 +696,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
>> @@ -1717,7 +1725,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))
>>
>> @@ -1739,7 +1747,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 cdd79700326..136c318727d 100644
>> --- a/doc/build/gcc.rst
>> +++ b/doc/build/gcc.rst
>> @@ -141,6 +141,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
>> ~~~~~~~~~~~~~~~~~~~
>>
>> --
>> 2.33.0.1079.g6e70778dc9-goog
>>
More information about the U-Boot
mailing list