FROMLIST: BACKPORT: kbuild: add support for clang LTO
This change adds the configuration option CONFIG_LTO_CLANG, and build system support for clang's Link Time Optimization (LTO). In preparation for LTO support for other compilers, potentially common parts of the changes are gated behind CONFIG_LTO instead. With -flto, instead of object files, clang produces LLVM bitcode, which is compiled into a native object at link time, allowing the final binary to be optimized globally. For more details, see: https://llvm.org/docs/LinkTimeOptimization.html While the kernel normally uses GNU ld for linking, LLVM supports LTO only with lld or GNU gold linkers. This patch set assumes gold will be used with the LLVMgold plug-in to perform the LTO link step. Due to potential incompatibilities with GNU ld, this change also adds LDFINAL_vmlinux for using a different linker for the vmlinux_link step, and defaults to using GNU ld. Assuming LLVMgold.so is in LD_LIBRARY_PATH and CONFIG_LTO_CLANG has been selected, an LTO kernel can be built simply by running make CC=clang. LTO requires clang >= 5.0 and gold from binutils >= 2.27. Bug: 62093296 Bug: 67506682 Change-Id: Ibcd9fc7ec501b4f30b43b4877897615645f8655f (am from https://patchwork.kernel.org/patch/10060329/) Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
This commit is contained in:
parent
331f1f5c7b
commit
475bdd7d35
5 changed files with 276 additions and 34 deletions
|
@ -53,9 +53,40 @@ archive_builtin()
|
|||
${AR} rcsT${KBUILD_ARFLAGS} built-in.o \
|
||||
${KBUILD_VMLINUX_INIT} \
|
||||
${KBUILD_VMLINUX_MAIN}
|
||||
|
||||
if [ -n "${CONFIG_LTO_CLANG}" ]; then
|
||||
mv -f built-in.o built-in.o.tmp
|
||||
${LLVM_AR} rcsT${KBUILD_ARFLAGS} built-in.o $(${AR} t built-in.o.tmp)
|
||||
rm -f built-in.o.tmp
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
|
||||
# .tmp_symversions
|
||||
modversions()
|
||||
{
|
||||
if [ -z "${CONFIG_LTO_CLANG}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -z "${CONFIG_MODVERSIONS}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
rm -f .tmp_symversions
|
||||
|
||||
for a in built-in.o ${KBUILD_VMLINUX_LIBS}; do
|
||||
for o in $(${AR} t $a); do
|
||||
if [ -f ${o}.symversions ]; then
|
||||
cat ${o}.symversions >> .tmp_symversions
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo "-T .tmp_symversions"
|
||||
}
|
||||
|
||||
# Link of vmlinux.o used for section mismatch analysis
|
||||
# ${1} output file
|
||||
modpost_link()
|
||||
|
@ -70,7 +101,16 @@ modpost_link()
|
|||
${KBUILD_VMLINUX_MAIN} \
|
||||
--end-group"
|
||||
fi
|
||||
${LD} ${LDFLAGS} -r -o ${1} ${objects}
|
||||
|
||||
if [ -n "${CONFIG_LTO_CLANG}" ]; then
|
||||
# This might take a while, so indicate that we're doing
|
||||
# an LTO link
|
||||
info LTO vmlinux.o
|
||||
else
|
||||
info LD vmlinux.o
|
||||
fi
|
||||
|
||||
${LD} ${LDFLAGS} -r -o ${1} $(modversions) ${objects}
|
||||
}
|
||||
|
||||
# Link of vmlinux
|
||||
|
@ -82,7 +122,15 @@ vmlinux_link()
|
|||
local objects
|
||||
|
||||
if [ "${SRCARCH}" != "um" ]; then
|
||||
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
|
||||
local ld=${LD}
|
||||
local ldflags="${LDFLAGS} ${LDFLAGS_vmlinux}"
|
||||
|
||||
if [ -n "${LDFINAL_vmlinux}" ]; then
|
||||
ld=${LDFINAL_vmlinux}
|
||||
ldflags="${LDFLAGS_FINAL_vmlinux} ${LDFLAGS_vmlinux}"
|
||||
fi
|
||||
|
||||
if [[ -n "${CONFIG_THIN_ARCHIVES}" && -z "${CONFIG_LTO_CLANG}" ]]; then
|
||||
objects="--whole-archive built-in.o ${1}"
|
||||
else
|
||||
objects="${KBUILD_VMLINUX_INIT} \
|
||||
|
@ -92,8 +140,7 @@ vmlinux_link()
|
|||
${1}"
|
||||
fi
|
||||
|
||||
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
|
||||
-T ${lds} ${objects}
|
||||
${ld} ${ldflags} -o ${2} -T ${lds} ${objects}
|
||||
else
|
||||
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
|
||||
objects="-Wl,--whole-archive built-in.o ${1}"
|
||||
|
@ -113,7 +160,6 @@ vmlinux_link()
|
|||
fi
|
||||
}
|
||||
|
||||
|
||||
# Create ${2} .o file with all symbols from the ${1} object file
|
||||
kallsyms()
|
||||
{
|
||||
|
@ -164,6 +210,7 @@ cleanup()
|
|||
rm -f .tmp_System.map
|
||||
rm -f .tmp_kallsyms*
|
||||
rm -f .tmp_version
|
||||
rm -f .tmp_symversions
|
||||
rm -f .tmp_vmlinux*
|
||||
rm -f built-in.o
|
||||
rm -f System.map
|
||||
|
@ -209,15 +256,6 @@ case "${KCONFIG_CONFIG}" in
|
|||
. "./${KCONFIG_CONFIG}"
|
||||
esac
|
||||
|
||||
archive_builtin
|
||||
|
||||
#link vmlinux.o
|
||||
info LD vmlinux.o
|
||||
modpost_link vmlinux.o
|
||||
|
||||
# modpost vmlinux.o to check for section mismatches
|
||||
${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
|
||||
|
||||
# Update version
|
||||
info GEN .version
|
||||
if [ ! -r .version ]; then
|
||||
|
@ -228,9 +266,24 @@ else
|
|||
expr 0$(cat .old_version) + 1 >.version;
|
||||
fi;
|
||||
|
||||
archive_builtin
|
||||
|
||||
#link vmlinux.o
|
||||
modpost_link vmlinux.o
|
||||
|
||||
# modpost vmlinux.o to check for section mismatches
|
||||
${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
|
||||
|
||||
# final build of init/
|
||||
${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
|
||||
|
||||
if [ -n "${CONFIG_LTO_CLANG}" ]; then
|
||||
# Re-use vmlinux.o, so we can avoid the slow LTO link step in
|
||||
# vmlinux_link
|
||||
KBUILD_VMLINUX_INIT=
|
||||
KBUILD_VMLINUX_MAIN=vmlinux.o
|
||||
fi
|
||||
|
||||
kallsymso=""
|
||||
kallsyms_vmlinux=""
|
||||
if [ -n "${CONFIG_KALLSYMS}" ]; then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue