| # |
| # Support for gcc link time optimization |
| # |
| |
| DISABLE_LTO := |
| LTO_CFLAGS := |
| |
| export DISABLE_LTO |
| export LTO_CFLAGS |
| |
| ifdef CONFIG_LTO |
| # 4.7 works mostly, but it sometimes loses symbols on large builds |
| # This can be worked around by marking those symbols visible, |
| # but that is fairly ugly and the problem is gone with 4.8 |
| # 4.8 was very slow |
| # 4.9 still had a few bugs that needed workarounds |
| # make it 5.0+ only for now, which is also faster again |
| # 5.0 has some rare issues in the lto-streamer, could make this 6.0 |
| ifeq ($(call cc-ifversion, -ge, 0500,y),y) |
| # is the compiler compiled with LTO? |
| ifneq ($(call cc-option,${LTO_CFLAGS},n),n) |
| # binutils before 2.27 has various problems with plugins |
| ifeq ($(call ld-ifversion,-ge,227000000,y),y) |
| |
| $(info Enabling LTO) |
| |
| # gcc 5.0 supports __attribute__((no_reorder)), so we don't |
| # need to disable reordering globally, but can only use |
| # it on init calls. |
| # Disabled for now because of some undebugged bug in 5.x |
| #ifeq ($(call cc-ifversion,-ge,0500,y),y) |
| # DISABLE_TL_REORDER := |
| #else |
| DISABLE_TL_REORDER := -fno-toplevel-reorder |
| #endif |
| LTO_CFLAGS := -flto $(DISABLE_TL_REORDER) |
| LTO_FINAL_CFLAGS := -fuse-linker-plugin |
| |
| # the -fno-toplevel-reorder is to preserve the order of initcalls |
| # everything else should tolerate reordering |
| LTO_FINAL_CFLAGS += $(DISABLE_TL_REORDER) |
| |
| # enable LTO and set the jobs used by the LTO phase |
| # this should be -flto=jobserver to coordinate with the |
| # parent make, but work around |
| # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50639 |
| # use as many jobs as processors are online for now |
| # this actually seems to be a kernel bug with the pipe code |
| LTO_FINAL_CFLAGS := -flto=$(shell getconf _NPROCESSORS_ONLN) |
| #LTO_FINAL_CFLAGS := -flto=jobserver |
| |
| # requires plugin ar |
| LTO_CFLAGS += -fno-fat-lto-objects |
| |
| # Used to disable LTO for specific files (e.g. vdso) |
| DISABLE_LTO := -fno-lto |
| |
| LTO_FINAL_CFLAGS += ${LTO_CFLAGS} -fwhole-program |
| |
| ifdef CONFIG_LTO_DEBUG |
| LTO_FINAL_CFLAGS += -dH -fdump-ipa-cgraph -fdump-ipa-inline-details |
| # useful to add to reproduce compiler crashes |
| # -Wl,-plugin-save-temps -save-temps |
| LTO_CFLAGS += |
| endif |
| ifdef CONFIG_LTO_CP_CLONE |
| LTO_FINAL_CFLAGS += -fipa-cp-clone |
| LTO_CFLAGS += -fipa-cp-clone |
| endif |
| |
| KBUILD_CFLAGS += ${LTO_CFLAGS} |
| |
| # finally enable LTO for the final linking stage |
| |
| LDFINAL := ${CONFIG_SHELL} ${srctree}/scripts/gcc-ld \ |
| ${LTO_FINAL_CFLAGS} |
| |
| # LTO gcc creates a lot of files in TMPDIR, and with /tmp as tmpfs |
| # it's easy to drive the machine OOM. Use the object directory |
| # instead. |
| TMPDIR ?= $(objtree) |
| export TMPDIR |
| |
| # use plugin aware tools |
| AR = $(CROSS_COMPILE)gcc-ar |
| NM = $(CROSS_COMPILE)gcc-nm |
| else |
| $(warning WARNING old binutils. LTO disabled) |
| endif |
| else |
| $(warning "WARNING: Compiler/Linker does not support LTO/WHOPR with linker plugin. CONFIG_LTO disabled.") |
| endif |
| else |
| $(warning "WARNING: GCC $(call cc-version) too old for LTO/WHOPR. CONFIG_LTO disabled") |
| endif |
| endif |