diff options
| author | Tom Rini <[email protected]> | 2021-05-24 16:12:31 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2021-05-24 16:12:31 -0400 |
| commit | 27c6d9663c3f42059514e47c17652304a1cfcfc9 (patch) | |
| tree | 15e7a1deb449053a3ffca9b708813cce2da366ec /scripts | |
| parent | eb53b943be2949ca111140a8e05532cd74cda058 (diff) | |
| parent | 2fc62f2991744dfeec65f8619092c359d8ecbcb0 (diff) | |
Merge branch '2021-05-24-add-lto-support'
- Add LTO (link time optimization) support to the build system and
enable it on a few boards. This is an alternative to using
-ffunction-sections/-fdata-sections and --gc-sections at link time to
remove unused code. This can result in notable savings, but needs
testing on each platform before use as it can expose problems by
optimizing away various functionally necessary calls.
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Makefile.build | 16 | ||||
| -rw-r--r-- | scripts/Makefile.lib | 3 | ||||
| -rw-r--r-- | scripts/Makefile.spl | 63 | ||||
| -rwxr-xr-x | scripts/checkpatch.pl | 2 | ||||
| -rw-r--r-- | scripts/dtc/pylibfdt/libfdt.i_shipped | 4 | ||||
| -rwxr-xr-x | scripts/gen_ll_addressable_symbols.sh | 12 |
6 files changed, 82 insertions, 18 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 705a886cb98..7e59ca54cd0 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -331,12 +331,11 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ; # Rule to compile a set of .o files into one .o file # ifdef builtin-target -quiet_cmd_link_o_target = LD $@ +quiet_cmd_link_o_target = AR $@ # If the list of objects to link is empty, just create an empty built-in.o cmd_link_o_target = $(if $(strip $(obj-y)),\ - $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \ - $(cmd_secanalysis),\ - rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@) + rm -f $@; $(AR) cDPrsT $@ $(filter $(obj-y), $^), \ + rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@) $(builtin-target): $(obj-y) FORCE $(call if_changed,link_o_target) @@ -362,7 +361,7 @@ $(modorder-target): $(subdir-ym) FORCE # ifdef lib-target quiet_cmd_link_l_target = AR $@ -cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) +cmd_link_l_target = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(lib-y) $(lib-target): $(lib-y) FORCE $(call if_changed,link_l_target) @@ -382,10 +381,11 @@ $(filter $(addprefix $(obj)/, \ $($(subst $(obj)/,,$(@:.o=-objs))) \ $($(subst $(obj)/,,$(@:.o=-y)))), $^) -quiet_cmd_link_multi-y = LD $@ -cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) -quiet_cmd_link_multi-m = LD [M] $@ +quiet_cmd_link_multi-y = AR $@ +cmd_link_multi-y = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(link_multi_deps) + +quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = $(cmd_link_multi-y) $(multi-used-y): FORCE diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 78543c6dd10..78bbebe7e93 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 c69525fa748..5be1a9ba1b1 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -399,6 +399,8 @@ LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL) # Avoid 'Not enough room for program headers' error on binutils 2.28 onwards. LDFLAGS_$(SPL_BIN) += $(call ld-option, --no-dynamic-linker) +LDFLAGS_$(SPL_BIN) += --build-id=none + # Pick the best-match (i.e. SPL_TEXT_BASE for SPL, TPL_TEXT_BASE for TPL) ifneq ($(CONFIG_$(SPL_TPL_)TEXT_BASE),) LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_$(SPL_TPL_)TEXT_BASE) @@ -448,18 +450,65 @@ quiet_cmd_sym ?= SYM $@ $(obj)/$(SPL_BIN).sym: $(obj)/$(SPL_BIN) FORCE $(call if_changed,sym) +# Generate linker list symbols references to force compiler to not optimize +# them away when compiling with LTO +ifdef CONFIG_LTO +u-boot-spl-keep-syms-lto := $(obj)/keep-syms-lto.o +u-boot-spl-keep-syms-lto_c := \ + $(patsubst $(obj)/%.o,$(obj)/%.c,$(u-boot-spl-keep-syms-lto)) + +quiet_cmd_keep_syms_lto = KSL $@ + cmd_keep_syms_lto = \ + NM=$(NM) $(srctree)/scripts/gen_ll_addressable_symbols.sh $^ >$@ + +quiet_cmd_keep_syms_lto_cc = KSLCC $@ + cmd_keep_syms_lto_cc = \ + $(CC) $(filter-out $(LTO_CFLAGS),$(c_flags)) -c -o $@ $< + +$(u-boot-spl-keep-syms-lto_c): $(u-boot-spl-main) $(u-boot-spl-platdata) + $(call if_changed,keep_syms_lto) +$(u-boot-spl-keep-syms-lto): $(u-boot-spl-keep-syms-lto_c) + $(call if_changed,keep_syms_lto_cc) +else +u-boot-spl-keep-syms-lto := +endif + # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk +ifdef CONFIG_LTO +quiet_cmd_u-boot-spl ?= 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)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-keep-syms-lto)) \ + $(PLATFORM_LIBS) \ + -Wl,--no-whole-archive \ + -Wl,-Map,$(SPL_BIN).map -o $(SPL_BIN) \ + ) +else quiet_cmd_u-boot-spl ?= LD $@ - cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \ - $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ - --end-group \ - $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN)) + 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)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + --no-whole-archive \ + $(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 + $(u-boot-spl-main) $(u-boot-spl-keep-syms-lto) \ + $(obj)/u-boot-spl.lds FORCE $(call if_changed,u-boot-spl) $(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ; diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 59a714a95fa..08a827535aa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6073,7 +6073,7 @@ sub process { my $old = substr($rawline, $-[1], $+[1] - $-[1]); my $new = substr($old, 1, -1); if (WARN("PREFER_SECTION", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + "__section(\"$new\") is preferred over __attribute__((section($old)))\n" . $herecurr) && $fix) { $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; } diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped index 1d69ad38e2e..27c29ea2603 100644 --- a/scripts/dtc/pylibfdt/libfdt.i_shipped +++ b/scripts/dtc/pylibfdt/libfdt.i_shipped @@ -1010,7 +1010,7 @@ typedef uint32_t fdt32_t; } $1 = (void *)PyByteArray_AsString($input); fdt = $1; - fdt = fdt; /* avoid unused variable warning */ + (void)fdt; /* avoid unused variable warning */ } /* Some functions do change the device tree, so use void * */ @@ -1021,7 +1021,7 @@ typedef uint32_t fdt32_t; } $1 = PyByteArray_AsString($input); fdt = $1; - fdt = fdt; /* avoid unused variable warning */ + (void)fdt; /* avoid unused variable warning */ } /* typemap used for fdt_get_property_by_offset() */ diff --git a/scripts/gen_ll_addressable_symbols.sh b/scripts/gen_ll_addressable_symbols.sh new file mode 100755 index 00000000000..3978a39d970 --- /dev/null +++ b/scripts/gen_ll_addressable_symbols.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2020 Marek BehĂșn <[email protected]> + +# Generate __ADDRESSABLE(symbol) for every linker list entry symbol, so that LTO +# does not optimize these symbols away + +set -e + +echo '#include <common.h>' +$NM "$@" 2>/dev/null | grep -oe '_u_boot_list_2_[a-zA-Z0-9_]*_2_[a-zA-Z0-9_]*' | \ + sort -u | sed -e 's/^\(.*\)/extern char \1[];\n__ADDRESSABLE(\1);/' |
