mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
libexpr/meson: Rice the compiler inlining heuristics to improve perf of the bison generated parser
Turns out both GCC and Clang need a bit of hand-holding to optimize the bison generated
code well, otherwise parser performance tanks.
(Comparisons against baseline in 7e8db2eb59):
For GCC:
Benchmark 1 (15 runs): result/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
measurement mean ± σ min … max outliers delta
wall_time 335ms ± 2.89ms 332ms … 342ms 0 ( 0%) 0%
Benchmark 2 (16 runs): result-old/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
measurement mean ± σ min … max outliers delta
wall_time 330ms ± 2.87ms 326ms … 337ms 0 ( 0%) - 1.4% ± 0.6%
For Clang:
Benchmark 1 (15 runs): result-clang/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
measurement mean ± σ min … max outliers delta
wall_time 340ms ± 1.43ms 338ms … 343ms 0 ( 0%) 0%
Benchmark 2 (15 runs): result-old-clang/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
measurement mean ± σ min … max outliers delta
wall_time 334ms ± 1.61ms 332ms … 338ms 0 ( 0%) ⚡- 1.7% ± 0.3%
This commit is contained in:
parent
32b286e5d6
commit
96c8cc550f
1 changed files with 47 additions and 2 deletions
|
|
@ -183,17 +183,62 @@ subdir('primops')
|
|||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
# Turns out that Bison/Flex are particularly sensitive to compilers
|
||||
# failing to inline functions. For that reason we crank up the inlining
|
||||
# threshold manually for optimized builds. Yes, this can be considered 'ricing'
|
||||
# the compiler, but it does pay off.
|
||||
#
|
||||
# NOTE: missed inlining can be spotted (for Clang) using -Rpass-missed=inline
|
||||
# and -fdump-ipa-inline-missed (for GCC).
|
||||
parser_library_cpp_args = []
|
||||
|
||||
if not get_option('debug')
|
||||
if cxx.get_id() == 'clang'
|
||||
# The default as of LLVM 21 is 225:
|
||||
# llc --help-hidden | grep inline-threshold
|
||||
parser_library_cpp_args += [
|
||||
'-mllvm',
|
||||
'-inline-threshold=5000',
|
||||
]
|
||||
elif cxx.get_id() == 'gcc'
|
||||
parser_library_cpp_args += [
|
||||
'--param=max-inline-insns-single=1000',
|
||||
'--param=max-inline-insns-auto=1000',
|
||||
'--param=inline-unit-growth=400',
|
||||
]
|
||||
endif
|
||||
endif
|
||||
|
||||
# Working around https://github.com/mesonbuild/meson/issues/1367.
|
||||
parser_library = static_library(
|
||||
'nixexpr-parser',
|
||||
parser_tab,
|
||||
lexer_tab,
|
||||
cpp_args : parser_library_cpp_args,
|
||||
dependencies : deps_public + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# 1. Stdlib and regular assertions regress parser performance significantly, so build without
|
||||
# them for this one library when building in a release configuration.
|
||||
# 2. Disable LTO for GCC because then inlining flags won't apply, since LTO in GCC is done
|
||||
# by plonking down GIMPLE in the archive.
|
||||
override_options : [
|
||||
'b_ndebug=@0@'.format(not get_option('debug')),
|
||||
'b_lto=@0@'.format(cxx.get_id() != 'gcc'),
|
||||
],
|
||||
)
|
||||
|
||||
this_library = library(
|
||||
'nixexpr',
|
||||
sources,
|
||||
config_priv_h,
|
||||
parser_tab,
|
||||
lexer_tab,
|
||||
parser_tab[1],
|
||||
lexer_tab[1],
|
||||
generated_headers,
|
||||
soversion : nix_soversion,
|
||||
dependencies : deps_public + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
link_args : linker_export_flags,
|
||||
link_whole : [ parser_library ],
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
cpp_pch : do_pch ? [ 'pch/precompiled-headers.hh' ] : [],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue