From edbce9aad48fe71a6fed0df8d56eebb61e44632e Mon Sep 17 00:00:00 2001 From: zelalem-aweke Date: Tue, 12 Nov 2019 16:20:17 -0600 Subject: [PATCH] Enable Link Time Optimization in GCC This patch enables LTO for TF-A when compiled with GCC. LTO is disabled by default and is enabled by ENABLE_LTO=1 build option. LTO is enabled only for aarch64 as there seem to be a bug in the aarch32 compiler when LTO is enabled. The changes in the makefiles include: - Adding -flto and associated flags to enable LTO. - Using gcc as a wrapper at link time instead of ld. This is recommended when using LTO as gcc internally takes care of invoking the necessary plugins for LTO. - Adding switches to pass options to ld. - Adding a flag to disable fix for erratum cortex-a53-843419 unless explicitly enabled. This is needed because GCC seem to automatically add the erratum fix when used as a wrapper for LD. Additionally, this patch updates the TF-A user guide with the new build option. Signed-off-by: zelalem-aweke Change-Id: I1188c11974da98434b7dc9344e058cd1eacf5468 --- Makefile | 37 ++++++++++++++++++++++++-- docs/getting_started/build-options.rst | 4 +++ make_helpers/build_macros.mk | 6 ++++- make_helpers/defaults.mk | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 721246d51..eddd48d5a 100644 --- a/Makefile +++ b/Makefile @@ -204,6 +204,18 @@ LD = $(LINKER) AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) CPP = $(CC) -E PP = $(CC) -E +else ifneq ($(findstring gcc,$(notdir $(CC))),) +TF_CFLAGS_aarch32 = $(march32-directive) +TF_CFLAGS_aarch64 = $(march64-directive) +ifeq ($(ENABLE_LTO),1) + # Enable LTO only for aarch64 + ifeq (${ARCH},aarch64) + LTO_CFLAGS = -flto + # Use gcc as a wrapper for the ld, recommended for LTO + LINKER := ${CROSS_COMPILE}gcc + endif +endif +LD = $(LINKER) else TF_CFLAGS_aarch32 = $(march32-directive) TF_CFLAGS_aarch64 = $(march64-directive) @@ -300,11 +312,28 @@ GCC_V_OUTPUT := $(shell $(CC) -v 2>&1) ifneq ($(findstring armlink,$(notdir $(LD))),) TF_LDFLAGS += --diag_error=warning --lto_level=O1 TF_LDFLAGS += --remove --info=unused,unusedsymbols +TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH)) +else ifneq ($(findstring gcc,$(notdir $(LD))),) +# Pass ld options with Wl or Xlinker switches +TF_LDFLAGS += -Wl,--fatal-warnings -O1 +TF_LDFLAGS += -Wl,--gc-sections +ifeq ($(ENABLE_LTO),1) + ifeq (${ARCH},aarch64) + TF_LDFLAGS += -flto -fuse-linker-plugin + endif +endif +# GCC automatically adds fix-cortex-a53-843419 flag when used to link +# which breaks some builds, so disable if errata fix is not explicitly enabled +ifneq (${ERRATA_A53_843419},1) + TF_LDFLAGS += -mno-fix-cortex-a53-843419 +endif +TF_LDFLAGS += -nostdlib +TF_LDFLAGS += $(subst --,-Xlinker --,$(TF_LDFLAGS_$(ARCH))) else TF_LDFLAGS += --fatal-warnings -O1 TF_LDFLAGS += --gc-sections -endif TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH)) +endif DTC_FLAGS += -I dts -O dtb DTC_CPPFLAGS += -nostdinc -Iinclude -undef -x assembler-with-cpp @@ -405,7 +434,11 @@ endif ifeq ($(ENABLE_PIE),1) TF_CFLAGS += -fpie - TF_LDFLAGS += -pie --no-dynamic-linker + ifneq ($(findstring gcc,$(notdir $(LD))),) + TF_LDFLAGS += -Wl,-pie -Wl,--no-dynamic-linker + else + TF_LDFLAGS += -pie --no-dynamic-linker + endif else PIE_FOUND := $(findstring --enable-default-pie,${GCC_V_OUTPUT}) ifneq ($(PIE_FOUND),) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index fded1e0c9..051586bc3 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -196,6 +196,10 @@ Common build options builds, but this behaviour can be overridden in each platform's Makefile or in the build command line. + - ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO) + support in GCC for TF-A. This option is currently only supported for + AArch64. Default is 0. + - ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM feature. MPAM is an optional Armv8.4 extension that enables various memory system components and resources to define partitions; software running at diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index b89d87ea6..47f3ebd86 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -236,7 +236,7 @@ $(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS)) $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs $$(ECHO) " CC $$<" - $$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@ + $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@ -include $(DEP) @@ -433,6 +433,10 @@ ifneq ($(findstring armlink,$(notdir $(LD))),) --map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \ $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \ $(BUILD_DIR)/build_message.o $(OBJS) +else ifneq ($(findstring gcc,$(notdir $(LD))),) + $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \ + -Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \ + $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) else $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \ --script $(LINKERFILE) $(BUILD_DIR)/build_message.o \ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index b7fb173b1..348b3e52b 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -239,3 +239,6 @@ SANITIZE_UB := off # implementation variant using the ARMv8.1-LSE compare-and-swap instruction. # Default: disabled USE_SPINLOCK_CAS := 0 + +# Enable Link Time Optimization +ENABLE_LTO := 0