Skip to content

Commit

Permalink
Add support for PGO builds.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pentarctagon authored and GregoryLundberg committed Nov 30, 2017
1 parent b7562ad commit be50bb9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 29 deletions.
58 changes: 46 additions & 12 deletions CMakeLists.txt
Expand Up @@ -517,6 +517,7 @@ set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}" CACHE STRING "removed
MESSAGE("Replacing default flags used for Release build with -O3")
set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "Release build flags" FORCE)
set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "Release build flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "" FORCE)
# set the arch to use for Release build if provided
if(ARCH)
MESSAGE("adding -march=${ARCH} to Release build")
Expand All @@ -530,17 +531,21 @@ if(WIN32 AND NOT ARCH)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=pentiumpro" CACHE STRING "Release build flags" FORCE)
endif(WIN32 AND NOT ARCH)

# if compiling with LTO
if(ENABLE_LTO)
# clang and gcc require different parallelization options and linkers
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
MESSAGE("added -flto=thin to Release build")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE)

MESSAGE("Using Clang LLD linker")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s -fuse-ld=lld" CACHE STRING "Linker flag for building with LTO and clang" FORCE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# PGO and LTO for GCC
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(PGO_DATA STREQUAL "generate")
MESSAGE("Generating PGO data")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-generate=${CMAKE_SOURCE_DIR}/pgo_data/" CACHE STRING "Release build flags generating PGO data" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate=${CMAKE_SOURCE_DIR}/pgo_data/" CACHE STRING "Release build flags generating PGO data" FORCE)
endif()

if(PGO_DATA STREQUAL "use")
MESSAGE("Using PGO data from previous runs")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-correction -fprofile-use=${CMAKE_SOURCE_DIR}/pgo_data/" CACHE STRING "Release build flags for using PGO data" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-correction -fprofile-use=${CMAKE_SOURCE_DIR}/pgo_data/" CACHE STRING "Release build flags for using PGO data" FORCE)
endif()

if(ENABLE_LTO)
if(NOT LTO_JOBS)
MESSAGE("LTO_JOBS not set, defaulting to 1")
set(LTO_JOBS "1" CACHE STRING "Number of threads to use for LTO with gcc" FORCE)
Expand All @@ -551,10 +556,36 @@ if(ENABLE_LTO)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=${LTO_JOBS}" CACHE STRING "Release build flags with LTO" FORCE)

MESSAGE("Using GCC gold linker")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s -fuse-ld=gold" CACHE STRING "Linker flag for building with LTO and gcc" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -fuse-ld=gold" CACHE STRING "" FORCE)
endif(ENABLE_LTO)
endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

# PGO and LTO for Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(PGO_DATA STREQUAL "generate")
MESSAGE("Generating PGO data")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-instr-generate=${CMAKE_SOURCE_DIR}/pgo_data/wesnoth-%p.profraw" CACHE STRING "Release build flags generating PGO data" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-instr-generate=${CMAKE_SOURCE_DIR}/pgo_data/wesnoth-%p.profraw" CACHE STRING "Release build flags generating PGO data" FORCE)
endif()

if(PGO_DATA STREQUAL "use")
MESSAGE("Using PGO data from previous runs")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-instr-use=${CMAKE_SOURCE_DIR}/pgo_data/wesnoth.profdata" CACHE STRING "Release build flags for using PGO data" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-instr-use=${CMAKE_SOURCE_DIR}/pgo_data/wesnoth.profdata" CACHE STRING "Release build flags for using PGO data" FORCE)
endif()

if(ENABLE_LTO)
MESSAGE("added -flto=thin to Release build")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE)

MESSAGE("Using Clang LLD linker")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -fuse-ld=lld" CACHE STRING "Linker flag for building with LTO and clang" FORCE)
endif(ENABLE_LTO)
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")

# set CMAKE_AR and CMAKE_RANLIB to use LTO-enabled variants if LTO is enabled
if(ENABLE_LTO)
MESSAGE("Using gcc-ar and gcc-ranlib")
find_program(LTO_AR NAMES gcc-ar)
find_program(LTO_RANLIB NAMES gcc-ranlib)
Expand All @@ -570,6 +601,9 @@ else()
endif()
MARK_AS_ADVANCED(LTO_AR LTO_RANLIB NON_LTO_AR NON_LTO_RANLIB)

# clean the pgo data
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_SOURCE_DIR}/pgo_data/")

# #
# End determining options for Release build
# Start setting options for Debug build
Expand Down
58 changes: 41 additions & 17 deletions SConstruct
Expand Up @@ -50,14 +50,15 @@ opts.AddVariables(
EnumVariable('build', 'Build variant: release, debug, profile or base (no subdirectory)', "release", ["release", "debug", "profile", "base"]),
PathVariable('build_dir', 'Build all intermediate files(objects, test programs, etc) under this dir', "build", PathVariable.PathAccept),
('extra_flags_config', "Extra compiler and linker flags to use for configuration and all builds. Whether they're compiler or linker is determined by env.ParseFlags. Unknown flags are compile flags by default. This applies to all extra_flags_* variables", ""),
('extra_flags_base', 'Extra compiler and linker flags to use for release builds', ""),
('extra_flags_base', 'Extra compiler and linker flags to use for base builds', ""),
('extra_flags_release', 'Extra compiler and linker flags to use for release builds', ""),
('extra_flags_debug', 'Extra compiler and linker flags to use for debug builds', ""),
('extra_flags_profile', 'Extra compiler and linker flags to use for profile builds', ""),
BoolVariable('enable_lto', 'Whether to enable Link Time Optimization for build=release', False),
('arch', 'What -march option to use for build=release, will default to pentiumpro on Windows', ""),
BoolVariable('glibcxx_debug', 'Whether to define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC for build=debug', False),
EnumVariable('profiler', 'profiler to be used for build=profile', "gprof", ["gprof", "gcov", "gperftools", "perf"]),
EnumVariable('pgo_data', 'whether to generate profiling data for PGO, or use existing profiling data', "", ["", "generate", "use"]),
PathVariable('bindir', 'Where to install binaries', "bin", PathVariable.PathAccept),
('cachedir', 'Directory that contains a cache of derived files.', ''),
PathVariable('datadir', 'read-only architecture-independent game data', "$datarootdir/$datadirname", PathVariable.PathAccept),
Expand Down Expand Up @@ -482,10 +483,10 @@ for env in [test_env, client_env, env]:
# Start determining options for debug build
# #

env["DEBUG_FLAGS"] = Split("-O0 -DDEBUG -ggdb3")
env["DEBUG_FLAGS"] = "-O0 -DDEBUG -ggdb3"

if env["glibcxx_debug"] == True:
glibcxx_debug_flags = Split("_GLIBCXX_DEBUG _GLIBCXX_DEBUG_PEDANTIC")
glibcxx_debug_flags = "_GLIBCXX_DEBUG _GLIBCXX_DEBUG_PEDANTIC"
else:
glibcxx_debug_flags = ""

Expand All @@ -494,27 +495,44 @@ for env in [test_env, client_env, env]:
# Start setting options for release build
# #

# default compiler flags
env["OPT_COMP_FLAGS"] = "-O3"

# use the arch if provided, or if on Windows and no arch was passed in then default to pentiumpro
# without setting to pentiumpro, compiling on Windows with 64-bit tdm-gcc and -O3 currently fails
if env["arch"]:
env["arch"] = " -march=" + env["arch"]
# without setting to pentiumpro, compiling on Windows with 64-bit tdm-gcc and -O3 currently fails
# therefore, set to pentiumpro if nothing else has been specified

if env["PLATFORM"] == "win32" and not env["arch"]:
env["arch"] = " -march=pentiumpro"

# set the -march option if windows or something was passed in
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + env["arch"]

# if building with LTO enabled
if env["enable_lto"] == True:
# gcc and clang need different LTO options and linkers
if env["CC"] == "gcc":
# PGO and LTO setup
if env["CC"] == "gcc":
if env["pgo_data"] == "generate":
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fprofile-generate=pgo_data/"
env["OPT_LINK_FLAGS"] = "-fprofile-generate=pgo_data/"

if env["pgo_data"] == "use":
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fprofile-correction -fprofile-use=pgo_data/"
env["OPT_LINK_FLAGS"] = "-fprofile-correction -fprofile-use=pgo_data/"

if env["enable_lto"] == True:
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -flto=" + str(env["jobs"])
env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -s -fuse-ld=gold"
elif "clang" in env["CXX"]:
env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fuse-ld=gold"
elif "clang" in env["CXX"]:
if env["pgo_data"] == "generate":
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fprofile-instr-generate=pgo_data/wesnoth-%p.profraw"
env["OPT_LINK_FLAGS"] = "-fprofile-instr-generate=pgo_data/wesnoth-%p.profraw"

if env["pgo_data"] == "use":
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fprofile-instr-use=pgo_data/wesnoth.profdata"
env["OPT_LINK_FLAGS"] = "-fprofile-instr-use=pgo_data/wesnoth.profdata"

if env["enable_lto"] == True:
env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -flto=thin"
env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -s -fuse-ld=lld"
env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -fuse-ld=lld"

# #
# End setting options for release build
Expand All @@ -526,15 +544,15 @@ for env in [test_env, client_env, env]:
prof_link_flags = "-pg"

if env["profiler"] == "gcov":
prof_comp_flags = Split("-fprofile-arcs -ftest-coverage")
prof_comp_flags = "-fprofile-arcs -ftest-coverage"
prof_link_flags = "-fprofile-arcs"

if env["profiler"] == "gperftools":
prof_comp_flags = ""
prof_link_flags = "-Wl,--no-as-needed,-lprofiler"

if env["profiler"] == "perf":
prof_comp_flags = Split("-ggdb -Og")
prof_comp_flags = "-ggdb -Og"
prof_link_flags = ""

# #
Expand Down Expand Up @@ -579,9 +597,9 @@ SConscript(dirs = Split("po doc packaging/windows packaging/systemd"))
binaries = Split("wesnoth wesnothd campaignd test")
builds = {
"base" : dict(CCFLAGS = Split("$OPT_COMP_FLAGS"), LINKFLAGS = Split("$OPT_LINK_FLAGS")),
"debug" : dict(CCFLAGS = Split("$DEBUG_FLAGS") , CPPDEFINES = glibcxx_debug_flags),
"debug" : dict(CCFLAGS = Split("$DEBUG_FLAGS") , CPPDEFINES = Split(glibcxx_debug_flags)),
"release" : dict(CCFLAGS = Split("$OPT_COMP_FLAGS"), LINKFLAGS = Split("$OPT_LINK_FLAGS")),
"profile" : dict(CCFLAGS = prof_comp_flags , LINKFLAGS = prof_link_flags)
"profile" : dict(CCFLAGS = Split(prof_comp_flags) , LINKFLAGS = Split(prof_link_flags))
}
build = env["build"]

Expand All @@ -607,6 +625,12 @@ env.Default([Alias(target) for target in env["default_targets"]])
if have_client_prereqs and env["nls"]:
env.Requires("wesnoth", Dir("translations"))

#
# clean out any PGO-related files
#

env.Clean(all, "pgo_data/")

#
# Utility productions (Unix-like systems only)
#
Expand Down

0 comments on commit be50bb9

Please sign in to comment.