Enable LTO compilation (#2450)

* Enable LTO compilation

Similar to nimbus-eth2, LTO gives a significant boost for any CPU-bound operations such as the EVM.

The options are copied straight from nimbus-eth2 - for example at block height 1.7M there's a computation-heavy section where we can see a 15%-20% improvement in block processing time.

```
                       bps_x     bps_y     tps_x     tps_y time_x time_y     bpsd     tpsd    timed

(1722223, 1733334]    102.52    138.90  1,049.67  1,420.61  2m41s  1m58s   35.78%   35.78%  -26.32%
```

* avoid defer

When evmc recursion is enabled together with LTO, we run out of stack
space.

`defer` creates an exception handling context that takes up hundreds of
bytes of stack space - now that the EVM is no longer using exceptions,
we can safely get rid of it.
This commit is contained in:
Jacek Sieka 2024-07-04 18:10:40 +02:00 committed by GitHub
parent 79788c01d4
commit 893bfa4305
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 66 additions and 4 deletions

View File

@ -20,10 +20,41 @@ if getEnv("NIMBUS_BUILD_SYSTEM") == "yes" and
system.fileExists(currentDir & "nimbus-build-system.paths"): system.fileExists(currentDir & "nimbus-build-system.paths"):
include "nimbus-build-system.paths" include "nimbus-build-system.paths"
if defined(release): const nimCachePathOverride {.strdefine.} = ""
switch("nimcache", "nimcache/release/$projectName") when nimCachePathOverride == "":
when defined(release):
let nimCachePath = "nimcache/release/" & projectName()
else:
let nimCachePath = "nimcache/debug/" & projectName()
else: else:
switch("nimcache", "nimcache/debug/$projectName") let nimCachePath = nimCachePathOverride
switch("nimcache", nimCachePath)
# `-flto` gives a significant improvement in processing speed, specially hash tree and state transition (basically any CPU-bound code implemented in nim)
# With LTO enabled, optimization flags should be passed to both compiler and linker!
if defined(release) and not defined(disableLTO):
# "-w" is not passed to the compiler during linking, so we need to disable
# some warnings by hand.
switch("passL", "-Wno-stringop-overflow -Wno-stringop-overread")
if defined(macosx): # Clang
switch("passC", "-flto=thin")
switch("passL", "-flto=thin -Wl,-object_path_lto," & nimCachePath & "/lto")
elif defined(linux):
switch("passC", "-flto=auto")
switch("passL", "-flto=auto")
switch("passC", "-finline-limit=100000")
switch("passL", "-finline-limit=100000")
else:
# On windows, LTO needs more love and attention so "gcc-ar" and "gcc-ranlib" are
# used for static libraries.
discard
# Hidden visibility allows for better position-independent codegen - it also
# resolves a build issue in BLST where otherwise private symbols would require
# an unsupported relocation on PIE-enabled distros such as ubuntu - BLST itself
# solves this via a linker script which is messy
switch("passC", "-fvisibility=hidden")
if defined(windows): if defined(windows):
# disable timestamps in Windows PE headers - https://wiki.debian.org/ReproducibleBuilds/TimestampsInPEBinaries # disable timestamps in Windows PE headers - https://wiki.debian.org/ReproducibleBuilds/TimestampsInPEBinaries
@ -180,4 +211,35 @@ when defined(gcc):
# Assumes GCC # Assumes GCC
# -fomit-frame-pointer for https://github.com/status-im/nimbus-eth1/issues/2127 # -fomit-frame-pointer for https://github.com/status-im/nimbus-eth1/issues/2127
put("secp256k1.always", "-fomit-frame-pointer") put("secp256k1.always", "-fno-lto -fomit-frame-pointer")
# ############################################################
#
# No LTO for crypto
#
# ############################################################
# This applies per-file compiler flags to C files
# which do not support {.localPassC: "-fno-lto".}
# Unfortunately this is filename based instead of path-based
# Assumes GCC
# BLST
put("server.always", "-fno-lto")
put("assembly.always", "-fno-lto")
# BearSSL - only RNGs
put("aesctr_drbg.always", "-fno-lto")
put("hmac_drbg.always", "-fno-lto")
put("sysrng.always", "-fno-lto")
# ############################################################
#
# Spurious warnings
#
# ############################################################
# sqlite3.c: In function sqlite3SelectNew:
# vendor/nim-sqlite3-abi/sqlite3.c:124500: warning: function may return address of local variable [-Wreturn-local-addr]
put("sqlite3.always", "-fno-lto") # -Wno-return-local-addr