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 <s...@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 <s...@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

Reply via email to