[tarantool-patches] [PATCH v2 2/3] Add LTO support

Alexander Turenko alexander.turenko at tarantool.org
Mon Oct 15 02:17:34 MSK 2018


From: AKhatskevich <avkhatskevich at tarantool.org>

Added -DENABLE_LTO=ON/OFF cmake option, OFF by default.

LTO speeds up cpu-intensive workloads by up to 20% (see [1] and [2]).

Requirements for LTO enabling:

- cmake >= 3.9;
- Linux: ld.bfd / ld.gold from binutils >= 2.31 (or later 2.30)
  (gold >= 1.15);
- Mac OS: xcode >= 8 (earlier versions are not tested).

The requirement of the recent ld version is due to bug with exporting
symbols from dynamic list when LTO is enabled, see [3].

Note: -Wlto-type-mismatch on GCC (enabled by default with -flto) gives
namy warnings. Filed [4] to investigate it.

Note: LuaJIT will be compiled w/o LTO despite the option set, filed [5].

[1]: https://github.com/tarantool/tarantool/wiki/performance-research
[2]: https://gist.github.com/Khatskevich/31a2da6ab46ce903120e7a03d65966db
[3]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84901
[4]: https://github.com/tarantool/tarantool/issues/3742
[5]: https://github.com/tarantool/tarantool/issues/3743

Closes #3117
---
 CMakeLists.txt  |  3 ++
 cmake/lto.cmake | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 cmake/lto.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 439a2750a..491ccaf0b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,9 @@ include(cmake/pod2man.cmake)
 include(cmake/arch.cmake)
 include(cmake/os.cmake)
 include(cmake/compiler.cmake)
+# NO_POLICY_SCOPE is to suppress CMP0069 warnings on the unset
+# policy.
+include(cmake/lto.cmake NO_POLICY_SCOPE)
 include(cmake/simd.cmake)
 include(cmake/atomic.cmake)
 include(cmake/profile.cmake)
diff --git a/cmake/lto.cmake b/cmake/lto.cmake
new file mode 100644
index 000000000..44a6f5771
--- /dev/null
+++ b/cmake/lto.cmake
@@ -0,0 +1,95 @@
+#
+# Manage LTO (Link-Time-Optimization) and IPO
+# (Inter-Procedural-Optimization)
+#
+
+# Tarantool uses both dynamic-list and lto link options, which
+# works only since binutils:
+#
+# - 2.30 for linking with ld.gold (gold version is 1.15);
+# - last 2.30 or 2.31 in case of ld.bfd.
+
+# This cmake module exports CMP0069 policy and should be included
+# with NO_POLICY_SCOPE option.
+
+# The file gives an error if LTO is requested, but cannot be
+# enabled for some reason.
+
+if (NOT DEFINED ENABLE_LTO)
+    set(ENABLE_LTO OFF)
+endif()
+
+# Disable LTO if not requested.
+if (NOT ENABLE_LTO)
+    message(STATUS "Enabling LTO: FALSE")
+    return()
+endif()
+
+if(CMAKE_VERSION VERSION_LESS 3.9)
+    message(FATAL_ERROR "cmake >= 3.9 is needed for LTO enabling")
+endif()
+
+# Set 'CMP0069 NEW' behaviour for this project to support
+# compilers other than Intel Compiler and suppress cmake
+# warnings on the unset policy.
+cmake_policy(SET CMP0069 NEW)
+
+# Retain 'CMP0069 NEW' behaviour after
+# 'cmake_minimum_required(VERSION ...) in subprojects to
+# avoid cmake warnings on the unset policy.
+set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
+
+# Check whether LTO is supported by the compiler / toolchain and
+# give an error otherwise.
+include(CheckIPOSupported)
+check_ipo_supported(RESULT CMAKE_IPO_AVAILABLE)
+if (NOT CMAKE_IPO_AVAILABLE)
+    message(FATAL_ERROR "LTO is not supported by the compiler / toolchain")
+endif()
+
+# Extra checks on Linux whether all needed LTO features are
+# supported. Mac OS seems to work correctly with xcode >= 8.
+if (NOT TARGET_OS_DARWIN)
+    execute_process(
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        COMMAND ld -v OUTPUT_VARIABLE linker_version_str)
+    message(STATUS "ld version string: ${linker_version_str}")
+
+    # GNU ld (Gentoo 2.31.1 p3) 2.31.1
+    # GNU ld (GNU Binutils for Ubuntu) 2.30
+    # GNU ld version 2.27-10.el7
+    string(REGEX MATCH "^GNU ld.* (2\\.[0-9]+)[^ ]*$" matched_bfd
+        ${linker_version_str})
+
+    # GNU gold (Gentoo 2.31.1 p3 2.31.1) 1.16
+    # GNU gold (GNU Binutils for Ubuntu 2.30) 1.15
+    # GNU gold (version 2.27-10.el7) 1.12
+    if (NOT matched_bfd)
+        string(REGEX MATCH "^GNU gold.* (1\\.[0-9]+)[^ ]*$" matched_gold
+            ${linker_version_str})
+    endif()
+
+    if(matched_bfd)
+        set(linker_version ${CMAKE_MATCH_1})
+        message(STATUS "Found ld.bfd version: ${linker_version}")
+
+        if (linker_version VERSION_LESS "2.31")
+            message(FATAL_ERROR "ld.bfd >= 2.31 is needed for LTO")
+        endif()
+    elseif(matched_gold)
+        set(linker_version ${CMAKE_MATCH_1})
+        message(STATUS "Found ld.gold version: ${linker_version}")
+
+        if (linker_version VERSION_LESS "1.15")
+            message(FATAL_ERROR "ld.gold >= 1.15 is needed for LTO")
+        endif()
+    else()
+        message(FATAL_ERROR "Unsupported ld version format")
+    endif()
+endif()
+
+# gh-3742: investigate LTO warnings.
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-lto-type-mismatch")
+
+set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+message(STATUS "Enabling LTO: TRUE")
-- 
2.19.1





More information about the Tarantool-patches mailing list