From 9be15559cc0bfe506d9cdfba4ad0f4beacf5ce17 Mon Sep 17 00:00:00 2001 From: Octavian Soldea Date: Fri, 29 Jun 2018 15:54:01 -0700 Subject: [PATCH] build: enabling pgo at configure This modification allows for compiling with profiled guided optimization (pgo) using the flags --enable-pgo-generate and --enable-pgo-use. Refs: https://github.com/nodejs/node/issues/21583 Refs: https://github.com/nodejs/node/issues/1409 PR-URL: https://github.com/nodejs/node/pull/21596 Reviewed-By: James M Snell Reviewed-By: Richard Lau Reviewed-By: Denys Otrishko --- common.gypi | 10 +++++++++ configure | 61 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/common.gypi b/common.gypi index 1e154381b0e9d0..13bcb6742a8116 100644 --- a/common.gypi +++ b/common.gypi @@ -179,9 +179,19 @@ }], ['OS=="linux"', { 'variables': { + 'pgo_generate': ' -fprofile-generate ', + 'pgo_use': ' -fprofile-use -fprofile-correction ', 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', }, 'conditions': [ + ['enable_pgo_generate=="true"', { + 'cflags': ['<(pgo_generate)'], + 'ldflags': ['<(pgo_generate)'], + },], + ['enable_pgo_use=="true"', { + 'cflags': ['<(pgo_use)'], + 'ldflags': ['<(pgo_use)'], + },], ['enable_lto=="true"', { 'cflags': ['<(lto)'], 'ldflags': ['<(lto)'], diff --git a/configure b/configure index 332071345f4487..c04118e9832b0c 100755 --- a/configure +++ b/configure @@ -157,11 +157,23 @@ parser.add_option("--enable-vtune-profiling", "JavaScript code executed in nodejs. This feature is only available " "for x32, x86, and x64 architectures.") +parser.add_option("--enable-pgo-generate", + action="store_true", + dest="enable_pgo_generate", + help="Enable profiling with pgo of a binary. This feature is only available " + "on linux with gcc and g++ 5.4.1 or newer.") + +parser.add_option("--enable-pgo-use", + action="store_true", + dest="enable_pgo_use", + help="Enable use of the profile generated with --enable-pgo-generate. This " + "feature is only available on linux with gcc and g++ 5.4.1 or newer.") + parser.add_option("--enable-lto", action="store_true", dest="enable_lto", help="Enable compiling with lto of a binary. This feature is only available " - "on linux with gcc and g++.") + "on linux with gcc and g++ 5.4.1 or newer.") parser.add_option("--link-module", action="append", @@ -898,6 +910,16 @@ def configure_mips(o): o['variables']['mips_fpu_mode'] = options.mips_fpu_mode +def gcc_version_ge(version_checked): + for compiler in [(CC, 'c'), (CXX, 'c++')]: + ok, is_clang, clang_version, compiler_version = \ + try_check_compiler(compiler[0], compiler[1]) + compiler_version_num = tuple(map(int, compiler_version)) + if is_clang or compiler_version_num < version_checked: + return False + return True + + def configure_node(o): if options.dest_os == 'android': o['variables']['OS'] = 'android' @@ -942,6 +964,29 @@ def configure_node(o): else: o['variables']['node_enable_v8_vtunejit'] = 'false' + if flavor != 'linux' and (options.enable_pgo_generate or options.enable_pgo_use): + raise Exception( + 'The pgo option is supported only on linux.') + + if flavor == 'linux': + if options.enable_pgo_generate or options.enable_pgo_use: + version_checked = (5, 4, 1) + if not gcc_version_ge(version_checked): + version_checked_str = ".".join(map(str, version_checked)) + raise Exception( + 'The options --enable-pgo-generate and --enable-pgo-use ' + 'are supported for gcc and gxx %s or newer only.' % (version_checked_str)) + + if options.enable_pgo_generate and options.enable_pgo_use: + raise Exception( + 'Only one of the --enable-pgo-generate or --enable-pgo-use options ' + 'can be specified at a time. You would like to use ' + '--enable-pgo-generate first, profile node, and then recompile ' + 'with --enable-pgo-use') + + o['variables']['enable_pgo_generate'] = b(options.enable_pgo_generate) + o['variables']['enable_pgo_use'] = b(options.enable_pgo_use) + if flavor != 'linux' and (options.enable_lto): raise Exception( 'The lto option is supported only on linux.') @@ -949,15 +994,11 @@ def configure_node(o): if flavor == 'linux': if options.enable_lto: version_checked = (5, 4, 1) - for compiler in [(CC, 'c'), (CXX, 'c++')]: - ok, is_clang, clang_version, compiler_version = \ - try_check_compiler(compiler[0], compiler[1]) - compiler_version_num = tuple(map(int, compiler_version)) - if is_clang or compiler_version_num < version_checked: - version_checked_str = ".".join(map(str, version_checked)) - raise Exception( - 'The option --enable-lto is supported for gcc and gxx %s' - ' or newer only.' % (version_checked_str)) + if not gcc_version_ge(version_checked): + version_checked_str = ".".join(map(str, version_checked)) + raise Exception( + 'The option --enable-lto is supported for gcc and gxx %s' + ' or newer only.' % (version_checked_str)) o['variables']['enable_lto'] = b(options.enable_lto)