From 57e522065a9d4163ff9eb828546794d85dbcfd48 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Sat, 5 Sep 2015 00:12:13 +0200 Subject: [PATCH] Add linker optimizations and dead code and data elimination. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linkers also have options we can configure! The most usefull feature is to give every function its own section. This results in some bloat at compile time, but at link time now the linker can do dead code and data elimination by simply discarding appropriate sections. This works by splitting the `.text` section in a way that makes it possible to later only pull in sections that are actually referenced. That is, the basic idea is to keep the matching between sections and functions intact, so we can optimize based on it in the linking stage. Note: there's still an issue with how `libOSRM.a` gets build. CMake currently passes the linker flags on to ar, in order to create a static library. But ar does not understand the linker's flags. Referenes: - https://sourceware.org/binutils/docs/ld/Options.html#Options - http://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdfMCþ" - http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_EXE_LINKER_FLAGS.html - http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_MODULE_LINKER_FLAGS.html - http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_SHARED_LINKER_FLAGS.html - http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_STATIC_LINKER_FLAGS.html --- CMakeLists.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17b57c15d..d54d46b8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,28 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") target_link_libraries(osrm-extract wsock32 ws2_32) endif() +# Configuring linker +execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ERROR_QUIET OUTPUT_VARIABLE LINKER_VERSION) +# For ld.gold and ld.bfs (the GNU linkers) we optimize hard +if("${LINKER_VERSION}" MATCHES "GNU gold" OR "${LINKER_VERSION}" MATCHES "GNU ld") + message(STATUS "Setting linker optimizations") + if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") + # Tell compiler to put every function in separate section, linker can then match sections and functions + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") + # Tell linker to do dead code and data eminination during link time discarding sections + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--gc-sections") + endif() + # Default linker optimization flags + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common") +else() + message(STATUS "Using unknown linker, not setting linker optimizations") +endif () +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}") +# XXX(daniel-j-h): building libosrm.a invokes AR passing on the linker flags, but AR does not understand them +#set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${LINKER_FLAGS}") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") + # Activate C++11 if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")