Discussion:
[edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
Scott Duplichan
2015-07-14 16:44:23 UTC
Permalink
BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.

The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Kinney, Michael D
2015-07-14 20:55:39 UTC
Permalink
Hi Scott,

What is the purpose of GCCLINK_PREFIX? Why can't the Wl flag just be included in tools_def.txt as required?

Thanks,

Mike

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Tuesday, July 14, 2015 9:44 AM
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.

The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Scott Duplichan
2015-07-15 07:03:23 UTC
Permalink
Kinney, Michael D [mailto:***@intel.com] wrote:
]
]Sent: Tuesday, July 14, 2015 03:56 PM
]To: Scott Duplichan; edk2-***@lists.sourceforge.net; Kinney, Michael D
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Hi Scott,
]
]What is the purpose of GCCLINK_PREFIX? Why can't the Wl flag just be included in tools_def.txt as ]required?

Hello Kinney,

The tools_def.txt allows customization of the DLINK_FLAGS part of the
generated link command line. But the '-Wl,' must be prepended, with no
space, to the --start-group and --end-group options within the link
command line:

"$(DLINK)" -o ${dst} $(DLINK_FLAGS) \
$(GCCLINK_PREFIX)--start-group \
$(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) \
$(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)

Gcc will not accept --start-group or --end-group on the command line with
no prefix.

Thanks,
Scott

]Thanks,
]
]Mike

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Tuesday, July 14, 2015 9:44 AM
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.

The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Kinney, Michael D
2015-07-15 16:11:28 UTC
Permalink
Scott,

Is adding -Wl to those link options a new requirement for GCC49? Can all GCC toolchains accept -Wl in front of those link options? Maybe you can just all -Wl to the build rule without adding GCCLINK_PREFIX?

Mike

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Wednesday, July 15, 2015 12:03 AM
To: Kinney, Michael D; edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

Kinney, Michael D [mailto:***@intel.com] wrote:
]
]Sent: Tuesday, July 14, 2015 03:56 PM
]To: Scott Duplichan; edk2-***@lists.sourceforge.net; Kinney, Michael D
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Hi Scott,
]
]What is the purpose of GCCLINK_PREFIX? Why can't the Wl flag just be included in tools_def.txt as ]required?

Hello Kinney,

The tools_def.txt allows customization of the DLINK_FLAGS part of the
generated link command line. But the '-Wl,' must be prepended, with no
space, to the --start-group and --end-group options within the link
command line:

"$(DLINK)" -o ${dst} $(DLINK_FLAGS) \
$(GCCLINK_PREFIX)--start-group \
$(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) \
$(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)

Gcc will not accept --start-group or --end-group on the command line with
no prefix.

Thanks,
Scott

]Thanks,
]
]Mike

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Tuesday, July 14, 2015 9:44 AM
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.

The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Bruce Cran
2015-07-15 16:38:49 UTC
Permalink
Post by Kinney, Michael D
Is adding -Wl to those link options a new requirement for GCC49? Can all GCC toolchains accept -Wl in front of those link options? Maybe you can just all -Wl to the build rule without adding GCCLINK_PREFIX?
I came across that problem getting gcc 5.1 running using the GCC49
toolchain spec on FreeBSD last week: linker options have always (as far
as I know) required -Wl to be passed through to ld, but it appears that
gcc normally recognizes the ld options and passes them automatically but
for some reason it doesn't happen in some cases.
--
Bruce
Kinney, Michael D
2015-07-15 16:53:28 UTC
Permalink
Bruce,

I saw that -Wl, was for gcc to pass options to linker.

What does not make sense to me in the patch is the use of -Wl for DLINK, which should be mapped to ld, which should not require the Wl, prefix.

Mike

-----Original Message-----
From: Bruce Cran [mailto:***@cran.org.uk]
Sent: Wednesday, July 15, 2015 9:39 AM
To: Kinney, Michael D; Scott Duplichan; edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: Re: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
Post by Kinney, Michael D
Is adding -Wl to those link options a new requirement for GCC49? Can all GCC toolchains accept -Wl in front of those link options? Maybe you can just all -Wl to the build rule without adding GCCLINK_PREFIX?
I came across that problem getting gcc 5.1 running using the GCC49
toolchain spec on FreeBSD last week: linker options have always (as far
as I know) required -Wl to be passed through to ld, but it appears that
gcc normally recognizes the ld options and passes them automatically but
for some reason it doesn't happen in some cases.
--
Bruce
Scott Duplichan
2015-07-15 17:00:53 UTC
Permalink
Kinney, Michael D [mailto:***@intel.com] wrote:

]Sent: Wednesday, July 15, 2015 11:11 AM
]To: Scott Duplichan; edk2-***@lists.sourceforge.net; Kinney, Michael D
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Scott,
]
]Is adding -Wl to those link options a new requirement for GCC49? Can all GCC toolchains accept -Wl in ]front of those link options? Maybe you can just all -Wl to the build rule without adding GCCLINK_PREFIX?
]
]Mike

Hello Mike,

The -Wl is added to the GCC49LTO link command for compatibility
with a bigger change: GCC49LTO uses gcc to launch the link step
rather than calling ld directly. This is because the gcc docs state:

"to enable link-time optimizations you need to
use the GCC driver to perform the link-step"

To make this change, the patch substitutes gcc for ld in DLINK_PATH.
But when linking with gcc instead of ld, the command line is different
in some aspects. Options such as -o <path> are understood by both gcc
and ld and no change is needed there. But an option such as
--start-group is not understood by gcc. It needs to be passed to the
link step, and that is what the prepended '-Wl', does. Now if '-Wl,' is
unconditionally prepended, then the other gcc builds break because
they still use ld for linking, and ld doesn't understand a '-Wl,'
prefix.

The old gcc lto patch from last year that I never formally submitted
changes the link command from ld to gcc for all GCC tool chains. One
reason that I never submitted the patch is that making a change of this
significance to the existing gcc tool chains would be questioned.

Thanks,
Scott


-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Wednesday, July 15, 2015 12:03 AM
To: Kinney, Michael D; edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

Kinney, Michael D [mailto:***@intel.com] wrote:
]
]Sent: Tuesday, July 14, 2015 03:56 PM
]To: Scott Duplichan; edk2-***@lists.sourceforge.net; Kinney, Michael D
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Hi Scott,
]
]What is the purpose of GCCLINK_PREFIX? Why can't the Wl flag just be included in tools_def.txt as ]required?

Hello Kinney,

The tools_def.txt allows customization of the DLINK_FLAGS part of the
generated link command line. But the '-Wl,' must be prepended, with no
space, to the --start-group and --end-group options within the link
command line:

"$(DLINK)" -o ${dst} $(DLINK_FLAGS) \
$(GCCLINK_PREFIX)--start-group \
$(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) \
$(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)

Gcc will not accept --start-group or --end-group on the command line with
no prefix.

Thanks,
Scott

]Thanks,
]
]Mike

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Tuesday, July 14, 2015 9:44 AM
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.

The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Andrew Fish
2015-07-15 17:35:59 UTC
Permalink
Post by Scott Duplichan
]Sent: Wednesday, July 15, 2015 11:11 AM
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Scott,
]
]Is adding -Wl to those link options a new requirement for GCC49? Can all GCC toolchains accept -Wl in ]front of those link options? Maybe you can just all -Wl to the build rule without adding GCCLINK_PREFIX?
]
]Mike
Hello Mike,
The -Wl is added to the GCC49LTO link command for compatibility
with a bigger change: GCC49LTO uses gcc to launch the link step
"to enable link-time optimizations you need to
use the GCC driver to perform the link-step”
OK thanks for that I was getting confused. Xcode uses ld, so it does not have this restriction.
Post by Scott Duplichan
To make this change, the patch substitutes gcc for ld in DLINK_PATH.
But when linking with gcc instead of ld, the command line is different
in some aspects. Options such as -o <path> are understood by both gcc
and ld and no change is needed there. But an option such as
--start-group is not understood by gcc. It needs to be passed to the
link step, and that is what the prepended '-Wl', does. Now if '-Wl,' is
unconditionally prepended, then the other gcc builds break because
they still use ld for linking, and ld doesn't understand a '-Wl,'
prefix.
The old gcc lto patch from last year that I never formally submitted
changes the link command from ld to gcc for all GCC tool chains. One
reason that I never submitted the patch is that making a change of this
significance to the existing gcc tool chains would be questioned.
Maybe you are better off adding new targets in tools_def.txt for the LTO versions? That way you only need to add an target for tools that you test? The GCC stuff seems more modular than the other targets, it may not be that bad?

We turned on/off LTO in the DSC, and we ran into an issue in that we could not then override optimization in the INF, basically we could not make -fno-lto the last compiler flag.
Traditionally we did this:
[BuildOptions]
XCODE:*_*_*_CC_FLAGS = -O0
But with LTO we had to:
[BuildOptions]
XCODE:*_*_*_CC_FLAGS = -O0 -fno-lto
Thanks,
At a minimum you may want to make sure the over ride per driver still works, assuming gcc supports that.

If you want to modify the existing GCC entries, without really changing them you may want to use something like the PLATFORM_FLAGS on the ARM targets.

https://svn.code.sf.net/p/edk2/code/trunk/edk2/BaseTools/Conf/tools_def.template <https://svn.code.sf.net/p/edk2/code/trunk/edk2/BaseTools/Conf/tools_def.template>
#
# Use default values, or override in DSC file
#
*_ARMLINUXGCC_AARCH64_ARCHCC_FLAGS =
*_ARMLINUXGCC_AARCH64_ARCHASM_FLAGS =
*_ARMLINUXGCC_AARCH64_ARCHDLINK_FLAGS =
*_ARMLINUXGCC_AARCH64_PLATFORM_FLAGS =

DEBUG_ARMLINUXGCC_AARCH64_ASM_FLAGS = $(ARCHASM_FLAGS) $(PLATFORM_FLAGS) -g
RELEASE_ARMLINUXGCC_AARCH64_ASM_FLAGS = $(ARCHASM_FLAGS) $(PLATFORM_FLAGS)

*_ARMLINUXGCC_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
*_ARMLINUXGCC_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -x c -E -P -DVFRCOMPILE --include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h

*_ARMLINUXGCC_AARCH64_SLINK_FLAGS = -rc
*_ARMLINUXGCC_AARCH64_DLINK_FLAGS = $(ARCHDLINK_FLAGS) DEF(GCC_ARM_AARCH64_DLINK_COMMON)

DEBUG_ARMLINUXGCC_AARCH64_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -Wno-address -O0
RELEASE_ARMLINUXGCC_AARCH64_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -Wno-address -Wno-unused-but-set-variable

Thanks,
Andrew Fish
Post by Scott Duplichan
Thanks,
Scott
-----Original Message-----
Sent: Wednesday, July 15, 2015 12:03 AM
Cc: Mcdaniel, Daryl
Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Sent: Tuesday, July 14, 2015 03:56 PM
]Cc: Mcdaniel, Daryl
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Hi Scott,
]
]What is the purpose of GCCLINK_PREFIX? Why can't the Wl flag just be included in tools_def.txt as ]required?
Hello Kinney,
The tools_def.txt allows customization of the DLINK_FLAGS part of the
generated link command line. But the '-Wl,' must be prepended, with no
space, to the --start-group and --end-group options within the link
"$(DLINK)" -o ${dst} $(DLINK_FLAGS) \
$(GCCLINK_PREFIX)--start-group \
$(GCCLINK_PREFIX)--end-group $(DLINK2_FLAGS)
Gcc will not accept --start-group or --end-group on the command line with
no prefix.
Thanks,
Scott
]Thanks,
]
]Mike
-----Original Message-----
Sent: Tuesday, July 14, 2015 9:44 AM
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
New tool chain GCC49LTO uses gcc -flto (link time optimization) for
DEBUG and RELEASE builds of IA32, X64, and AARCH64.
Contributed-under: TianoCore Contribution Agreement 1.0
---
This patch enables gcc link time optimization by adding a stand-alone
GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain
unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of
the ARM projects. Link time optimization is added for RELEASE and DEBUG
builds. It is not enabled for NOOPT builds because the gcc documentation
states "Link-time optimization does not work well with generation of
debugging information. Combining ‘-flto’ with ‘-g’ is currently
experimental and expected to produce unexpected results."
Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/
AutoGen.c declaration difference for PCD array data. Other warnings
are exposed when ASSERT code is expanded and optimized. A separate
patch that allows overriding the warning as error option lets the
builds complete so that -flto can be tested before the autogen and
other warning issues are resolved.
The only successful boot test so far is Duet. The patches from
last year are still needed. I may rebsubmit these patches. GCC
builds using the latest CorebootPayloadPkg code are not working
on my board, so this needs to be debugged before it can be used
as a gcc -flto test case.
While this patch mainly targets BaseTools, some non-BaseTools files
are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified
to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its
build. This is because gcc code generation for StdLib contains calls
to compiler helper functions. While this can work with link time
optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed
by -plugin-opt=-pass-through=.
Laszlo suggested adding link time optimization support for GCC48
since it ships with RHEL-7.1. I will do that in a day or two. I
want to submit this patch now because I have done a lot of build
testing with it.
ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#
[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE
[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS = $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
<Command.GCC>
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}
<Command.ARMGCC, Command.ARMLINUXGCC>
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)
+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib -Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s
####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+####################################################################################
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that resolve
+ # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
https://lists.sourceforge.net/lists/listinfo/edk2-devel
Tian, Feng
2015-07-15 00:34:45 UTC
Permalink
Hi, Scott

How do you solve the linker plugin issue? GCC49 by default supports plugin now?

Thanks
Feng

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Wednesday, July 15, 2015 00:44
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of the ARM projects. Link time optimization is added for RELEASE and DEBUG builds. It is not enabled for NOOPT builds because the gcc documentation states "Link-time optimization does not work well with generation of debugging information. Combining ‘-flto’ with ‘-g’ is currently experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/ AutoGen.c declaration difference for PCD array data. Other warnings are exposed when ASSERT code is expanded and optimized. A separate patch that allows overriding the warning as error option lets the builds complete so that -flto can be tested before the autogen and other warning issues are resolved.

The only successful boot test so far is Duet. The patches from last year are still needed. I may rebsubmit these patches. GCC builds using the latest CorebootPayloadPkg code are not working on my board, so this needs to be debugged before it can be used as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its build. This is because gcc code generation for StdLib contains calls to compiler helper functions. While this can work with link time optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48 since it ships with RHEL-7.1. I will do that in a day or two. I want to submit this patch now because I have done a lot of build testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS =
+ $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-al
+ ign-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS =
+ $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-al
+ ign-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS)
+ $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH)
+ @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group
+ $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC> diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib
+-Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTR
+Y_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS =
+DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS
+= DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS =
+DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+#######################################################################
+#############
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that
+ resolve # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
Scott Duplichan
2015-07-15 13:52:38 UTC
Permalink
Tian, Feng [mailto:***@intel.com] wrote:

]Sent: Tuesday, July 14, 2015 07:35 PM
]To: Scott Duplichan; edk2-***@lists.sourceforge.net
]Cc: Mcdaniel, Daryl; Tian, Feng
]Subject: RE: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]Hi, Scott
]
]How do you solve the linker plugin issue? GCC49 by default supports plugin now?

I think a gcc supplied with Linux always has linker plugin support enabled. I
tried Ubuntu, and its gcc does have linker plugin support enabled. Laszlo said
the RHEL version he uses has linker plugin support enabled in its gcc. For
Windows, the opposite is true. I have never found a Windows gcc that has linker
plugin support enabled. I had to patch the gcc build source to make it work. To
Windows, the linker plugin is a dll. Binutils has the dll support code, but
not gcc itself. I ported the binutils dll support to gcc. The gcc tool chains
at http://sourceforge.net/projects/edk2developertoolsforwindows/ have the patch
and plugin support enabled.

A related problem is the need for gcc option -plugin-opt=-pass-through= when
linking to a library that satisfies compiler generated calls to helper
functions. This option needs the library name, and complete path if the library
is not in the compiler's default library search path. For EDK2, the path
depends on the build options like debug/release/noopt and gcc tool chain name.
There is no simple way to create this path using the existing EDK2 build
system. I have not solved this problem. Instead, I have disabled -flto for
objects/libraries that trigger compiler generated helper function calls. This
has essentially no impact on x86 builds, because x86 builds of most projects
do not produce any compiler generated calls to helper functions. An exception
is the IA32 build of AppPkg. It needs libc to resolve compiler generated calls
to functions such as __umoddi3, __udivdi3, etc. The workaround is in StdLib.inc:
GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
More exceptions are present for ARM builds. I have not enabled LTO for ARM builds
because I do not know how to resolve compiler generated calls to functions such
as __aeabi_dcmpeq, __aeabi_ui2d, __aeabi_dmul, etc.

Thanks,
Scott

]Thanks
]Feng

-----Original Message-----
From: Scott Duplichan [mailto:***@notabs.org]
Sent: Wednesday, July 15, 2015 00:44
To: edk2-***@lists.sourceforge.net
Cc: Mcdaniel, Daryl
Subject: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization

New tool chain GCC49LTO uses gcc -flto (link time optimization) for DEBUG and RELEASE builds of IA32, X64, and AARCH64.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Duplichan <***@notabs.org>
---

This patch enables gcc link time optimization by adding a stand-alone GCC49LTO tool chain. The existing GCC49 and other GCC tool chains remain unmodified. Link time optimization is added for IA32, X64 and AARCH64.
ARM is omitted for the time being because I am unable to build some of the ARM projects. Link time optimization is added for RELEASE and DEBUG builds. It is not enabled for NOOPT builds because the gcc documentation states "Link-time optimization does not work well with generation of debugging information. Combining ‘-flto’ with ‘-g’ is currently experimental and expected to produce unexpected results."

Builds that complete error free with GCC49 also complete with GCC49LTO.
However, use of -flto allows gcc to see and warn about an AutoGen.h/ AutoGen.c declaration difference for PCD array data. Other warnings are exposed when ASSERT code is expanded and optimized. A separate patch that allows overriding the warning as error option lets the builds complete so that -flto can be tested before the autogen and other warning issues are resolved.

The only successful boot test so far is Duet. The patches from last year are still needed. I may rebsubmit these patches. GCC builds using the latest CorebootPayloadPkg code are not working on my board, so this needs to be debugged before it can be used as a gcc -flto test case.

While this patch mainly targets BaseTools, some non-BaseTools files are changed: ArmVirt.dsc.inc and ArmVExpress.dsc.inc are modified to add GCC LTO compatibility to their overrides of DLINK_FLAGS.
StdLib.inc is modified to disable link time optimization for its build. This is because gcc code generation for StdLib contains calls to compiler helper functions. While this can work with link time optimization, it requires linker option -plugin-opt=-pass-through=.
Right now we have no easy way to generate the library path needed by -plugin-opt=-pass-through=.

Laszlo suggested adding link time optimization support for GCC48 since it ships with RHEL-7.1. I will do that in a day or two. I want to submit this patch now because I have done a lot of build testing with it.


ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
BaseTools/Conf/build_rule.template | 2 +-
BaseTools/Conf/tools_def.template | 178 ++++++++++++++++++++++
StdLib/StdLib.inc | 6 +
5 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 37a1ef7..1736104 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -13,7 +13,7 @@
#

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS =
+ $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-al
+ ign-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index d3f401b..4e2b237 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -18,7 +18,7 @@
DEFINE TTY_TERMINAL = FALSE

[BuildOptions.AARCH64.EDKII.DXE_RUNTIME_DRIVER]
- GCC:*_*_AARCH64_DLINK_FLAGS = --script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-align-ld-script
+ GCC:*_*_AARCH64_DLINK_FLAGS =
+ $(GCCLINK_PREFIX)--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-64K-al
+ ign-ld-script

[LibraryClasses.common]
!if $(TARGET) == RELEASE
diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index 596d41d..86ea464 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -279,7 +279,7 @@
"$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST)

<Command.GCC>
- "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS)
+ $(GCCLINK_PREFIX)--start-group $(DLINK_SPATH)
+ @$(STATIC_LIBRARY_FILES_LIST) $(GCCLINK_PREFIX)--end-group
+ $(DLINK2_FLAGS)
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}

<Command.ARMGCC, Command.ARMLINUXGCC> diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8e5750e..8d1b319 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -344,6 +344,12 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCC49LTO -Linux,Windows- Requires:
+# LTO capable GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
+# Optional:
+# Required to build platforms or ACPI tables:
+# Intel(r) ACPI Compiler from
+# https://acpica.org/downloads
# ELFGCC -Linux- Requires:
# GCC(this tool chain uses whatever version of gcc and binutils that is installed in /usr/bin)
# Optional:
@@ -3920,6 +3926,39 @@ DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS)
DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

+DEFINE GCC49LTO_IA32_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m32 -malign-double -fno-stack-protector -D EFI32 -fno-builtin
+DEFINE GCC49LTO_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections,--script=$(EDK_TOOLS_PATH)/Scripts/gcc4.9-ld-script
+DEFINE GCC49LTO_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+DEFINE GCC49LTO_IA32_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_COMMON),--entry,$(IMAGE_ENTRY_POINT),-u,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_i386,--oformat=elf32-i386
+DEFINE GCC49LTO_X64_BASE_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large -fno-builtin
+DEFINE GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_IA32_X64_DLINK_FLAGS),-melf_x86_64,--oformat=elf64-x86-64
+DEFINE GCC49LTO_ASM_FLAGS = DEF(GCC48_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_AARCH64_DLINK_COMMON = -nostdlib
+-Wl,--emit-relocs,--gc-sections,-u,$(IMAGE_ENTRY_POINT),-e,$(IMAGE_ENTR
+Y_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+
+DEFINE GCC49LTO_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS)
+DEFINE GCC49LTO_ARM_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mword-relocations -mlittle-endian -mabi=aapcs -mapcs -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -mthumb -mfloat-abi=soft -fstack-protector -mno-unaligned-access
+DEFINE GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),-Ttext=0x0
+DEFINE GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS)
+DEFINE GCC49LTO_AARCH64_BASE_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -mcmodel=large -mlittle-endian -fno-short-enums -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address
+DEFINE GCC49LTO_AARCH64_DLINK_FLAGS = DEF(GCC49LTO_ARM_AARCH64_DLINK_COMMON),--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
+DEFINE GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_DLINK_FLAGS),--entry,ReferenceAcpiTable,-u,ReferenceAcpiTable
+
+DEFINE GCC49LTO_IA32_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_IA32_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_IA32_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_X64_DEBUG_FLAGS = -Os -flto
+DEFINE GCC49LTO_X64_RELEASE_FLAGS = -Os -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_X64_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_ARM_DEBUG_FLAGS = -Og
+DEFINE GCC49LTO_ARM_RELEASE_FLAGS = -Wno-unused-but-set-variable
+DEFINE GCC49LTO_ARM_NOOPT_FLAGS = -Og
+DEFINE GCC49LTO_AARCH64_DEBUG_FLAGS = -Og -flto
+DEFINE GCC49LTO_AARCH64_RELEASE_FLAGS = -flto -Wno-unused-but-set-variable
+DEFINE GCC49LTO_AARCH64_NOOPT_FLAGS = -Og
+
####################################################################################
#
# Unix GCC And Intel Linux ACPI Compiler
@@ -4613,6 +4652,145 @@ RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-s

####################################################################################
#
+# GCC 4.9 LTO - This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC 4.9 with Link Time Optimization enabled.
+#
+####################################################################################
+*_GCC49LTO_*_*_FAMILY = GCC
+
+*_GCC49LTO_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCC49LTO_*_*_DLL = ENV(GCC49_DLL)
+*_GCC49LTO_*_ASL_PATH = DEF(UNIX_IASL_BIN)
+*_GCC49LTO_*_GCCLINK_PREFIX = -Wl,
+
+*_GCC49LTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCC49LTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCC49LTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCC49LTO_*_APP_FLAGS =
+*_GCC49LTO_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCC49LTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC49LTO IA32 definitions
+##################
+*_GCC49LTO_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+*_GCC49LTO_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc-ar
+*_GCC49LTO_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc
+*_GCC49LTO_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy
+
+ *_GCC49LTO_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+ *_GCC49LTO_IA32_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_i386
+ *_GCC49LTO_IA32_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m32 -march=i386
+ DEBUG_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_IA32_CC_FLAGS = DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_DEBUG_FLAGS)
+RELEASE_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_IA32_DLINK_FLAGS = DEF(GCC49LTO_IA32_DLINK_FLAGS) DEF(GCC49LTO_IA32_BASE_CC_FLAGS) DEF(GCC49LTO_IA32_NOOPT_FLAGS)
+ *_GCC49LTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+ *_GCC49LTO_IA32_OBJCOPY_FLAGS =
+ *_GCC49LTO_IA32_NASM_FLAGS = -f elf32
+
+##################
+# GCC49LTO X64 definitions
+##################
+*_GCC49LTO_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy
+*_GCC49LTO_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)gcc-ar
+*_GCC49LTO_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc
+*_GCC49LTO_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy
+
+*_GCC49LTO_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCC49LTO_X64_ASLDLINK_FLAGS = DEF(GCC49LTO_IA32_X64_ASLDLINK_FLAGS),-melf_x86_64
+*_GCC49LTO_X64_ASM_FLAGS = DEF(GCC49LTO_ASM_FLAGS) -m64
+ DEBUG_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_X64_CC_FLAGS = DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_DEBUG_FLAGS)
+RELEASE_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_X64_DLINK_FLAGS = DEF(GCC49LTO_X64_DLINK_FLAGS) DEF(GCC49LTO_X64_BASE_CC_FLAGS) DEF(GCC49LTO_X64_NOOPT_FLAGS)
+ *_GCC49LTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS)
+ *_GCC49LTO_X64_OBJCOPY_FLAGS =
+ *_GCC49LTO_X64_NASM_FLAGS = -f elf64
+
+##################
+# GCC49LTO ARM definitions
+##################
+*_GCC49LTO_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc-ar
+*_GCC49LTO_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc
+*_GCC49LTO_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy
+
+*_GCC49LTO_ARM_ARCHCC_FLAGS = -mthumb
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+
+*_GCC49LTO_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_ARM_ASLDLINK_FLAGS = DEF(GCC49LTO_ARM_ASLDLINK_FLAGS)
+*_GCC49LTO_ARM_ASM_FLAGS = DEF(GCC49LTO_ARM_ASM_FLAGS)
+*_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS)
+*_GCC49LTO_ARM_PLATFORM_FLAGS = -march=armv7-a
+*_GCC49LTO_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS)
+*_GCC49LTO_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_ARM_CC_FLAGS = DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_DEBUG_FLAGS)
+RELEASE_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_ARM_DLINK_FLAGS = DEF(GCC49LTO_ARM_DLINK_FLAGS) DEF(GCC49LTO_ARM_BASE_CC_FLAGS) DEF(GCC49LTO_ARM_NOOPT_FLAGS)
+
+##################
+# GCC49LTO AARCH64 definitions
+##################
+*_GCC49LTO_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc-ar
+*_GCC49LTO_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
+*_GCC49LTO_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy
+
+*_GCC49LTO_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCC49LTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49LTO_AARCH64_ASLDLINK_FLAGS)
+*_GCC49LTO_AARCH64_ASM_FLAGS = DEF(GCC49LTO_AARCH64_ASM_FLAGS)
+*_GCC49LTO_AARCH64_PLATFORM_FLAGS=
+*_GCC49LTO_AARCH64_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC49LTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC49LTO_AARCH64_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+ DEBUG_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) -c
+RELEASE_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_RELEASE_FLAGS) -c
+ NOOPT_GCC49LTO_AARCH64_CC_FLAGS = DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS) DEF(GCC49LTO_AARCH64_NOOPT_FLAGS) -c
+ DEBUG_GCC49LTO_AARCH64_DLINK_FLAGS =
+DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_DEBUG_FLAGS) RELEASE_GCC49LTO_AARCH64_DLINK_FLAGS
+= DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_RELEASE_FLAGS)
+ NOOPT_GCC49LTO_AARCH64_DLINK_FLAGS =
+DEF(GCC49LTO_AARCH64_DLINK_FLAGS) DEF(GCC49LTO_AARCH64_BASE_CC_FLAGS)
+DEF(GCC49LTO_AARCH64_NOOPT_FLAGS)
+
+#######################################################################
+#############
+#
# Cygwin GCC And Intel ACPI Compiler
#
####################################################################################
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc index 1b7fcf0..1821a46 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -125,3 +125,9 @@
ARMGCC:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unknown-pragmas -Wno-unused -Wno-format-zero-length
XCODE:*_*_*_CC_FLAGS = -nostdinc -nostdlib -DUEFI_C_SOURCE -Wno-unused-const-variable -Wno-string-compare -Wno-sometimes-uninitialized
!endif
+
+ # For gcc link time optimization (-flto) use, library functions that
+ resolve # compiler generated calls must be compiled without -flto.
+ # Wildcard can't be used for gcc version because GCC44 predates -flto/-fno-lto
+ GCC:*_GCC49LTO_IA32_CC_FLAGS = -fno-lto
+ GCC:*_GCC51LTO_IA32_CC_FLAGS = -fno-lto
David Woodhouse
2015-08-14 08:42:48 UTC
Permalink
Post by Scott Duplichan
It needs libc to resolve compiler generated calls
Hm, do we pull libgcc into the build?

The OpenSSL patches disable any functionality that would do 64-bit
division and hence require __umoddi3/__udivdi3 et al. Do we not need to
do that?
--
--
David Woodhouse Open Source Technology Centre
***@intel.com Intel Corporation
Scott Duplichan
2015-08-14 14:55:39 UTC
Permalink
David Woodhouse [mailto:***@infradead.org] wrote:

]Sent: Friday, August 14, 2015 03:43 AM
]To: Scott Duplichan <***@notabs.org>; 'Tian, Feng' <***@intel.com>; edk2-***@lists.sourceforge.net
]Cc: 'Mcdaniel, Daryl' <***@intel.com>
]Subject: Re: [edk2] [PATCH] BaseTools: Add GCC49LTO tool chain: GCC49 with link time optimization
]
]On Wed, 2015-07-15 at 08:52 -0500, Scott Duplichan wrote:
]> It needs libc to resolve compiler generated calls
]> to functions such as __umoddi3, __udivdi3, etc. The workaround is in
]> StdLib.inc:
]
]Hm, do we pull libgcc into the build?

No, EDK2 is not using an external lib such as libgcc. It still relies
on supplying its own versions of the compiler helper functions (with
one exception: EDK2 uses Microsoft code for one function, ftol2.obj).
For a long time a gap in this scheme was missing compiler helper
functions needed by GCC for ARM. But that is fixed now. For example,
GCC can now build AppPkg for ARM (well almost. The NOOPT build remains
broken). The only other missing compiler helper function EDK2 needs
but is missing is __dtoui3, and this one is needed only for VS2013.


]The OpenSSL patches disable any functionality that would do 64-bit
]division and hence require __umoddi3/__udivdi3 et al. Do we not need to
]do that?

It sounds like the answer is no. It might be worth a build test with
those disabled functions restored.

Thanks,
Scott

]--
]--
]David Woodhouse Open Source Technology Centre
]***@intel.com Intel Corporation


------------------------------------------------------------------------------
David Woodhouse
2015-08-14 15:01:43 UTC
Permalink
Post by Scott Duplichan
It sounds like the answer is no. It might be worth a build test with
those disabled functions restored.
It was definitely failing.... but then again, maybe the GCC build
succeeded and the MinGW build fails. Perhaps we don't include the
libgcc functions in the MinGW case? And I got similar failures when
building with VS2008, just with different function names.
--
dwmw2
Andrew Fish
2015-08-14 15:13:00 UTC
Permalink
Post by David Woodhouse
Post by Scott Duplichan
It sounds like the answer is no. It might be worth a build test with
those disabled functions restored.
It was definitely failing.... but then again, maybe the GCC build
succeeded and the MinGW build fails. Perhaps we don't include the
libgcc functions in the MinGW case? And I got similar failures when
building with VS2008, just with different function names.
David,

This is an example of what you need to do the DSC to include the ARM the compiler intrinsics.

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/MdeModulePkg.dsc
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent ARM compiler calls to generic intrinsic functions.
# This library provides the instrinsic functions generated by a given compiler.
# [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

It is not a full set of intrinsics, just what is needed for the edk2 coding standard.

Thanks,

Andrew Fish
Post by David Woodhouse
--
dwmw2
------------------------------------------------------------------------------
_______________________________________________
edk2-devel mailing list
https://lists.sourceforge.net/lists/listinfo/edk2-devel
------------------------------------------------------------------------------
David Woodhouse
2015-08-14 15:36:24 UTC
Permalink
Post by Andrew Fish
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/MdeModulePkg.dsc
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent ARM compiler calls to generic intrinsic functions.
# This library provides the instrinsic functions generated by a given compiler.
# [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
It is not a full set of intrinsics, just what is needed for the edk2 coding standard.
Thanks. I note that the ARM implementation of __umoddi3 is there, but
the IA32 version of the same function is in StdLib/LibC/CRT. Is there a
reason for that?
--
dwmw2
Andrew Fish
2015-08-14 15:50:49 UTC
Permalink
Post by David Woodhouse
Post by Andrew Fish
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/MdeModulePkg.dsc
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent ARM compiler calls to generic intrinsic functions.
# This library provides the instrinsic functions generated by a given compiler.
# [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
It is not a full set of intrinsics, just what is needed for the edk2 coding standard.
Thanks. I note that the ARM implementation of __umoddi3 is there, but
the IA32 version of the same function is in StdLib/LibC/CRT. Is there a
reason for that?
Well the ARM Intrinsic lib started out so we did not have to change the rules of how to do math. I seem to remember some folks tried to port some existing code, and ended up adding some extra functions to round out simple 64-bit math.

I also seem to remember that LLVM has these math function coded in C with a BSD compatible license if you need to find a new one.

Thanks,

Andrew Fish
Post by David Woodhouse
--
dwmw2
------------------------------------------------------------------------------
Loading...