From 2113b625d17178f24189c0059a6f360c181b589f Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Sat, 21 May 2022 23:44:51 +0200 Subject: [PATCH] gcc: add `build_type` and `profiled` variants (#30660) Add a `build_type` variant, which allows building optimized compilers, as well as target libraries (libstdc++ and friends). The default is `build_type=RelWithDebInfo`, which corresponds to GCC's default of -O2 -g. When building with `+bootstrap %gcc`, also add Spack's arch specific flags using the common denominator between host and new GCC. It is done by creating a config/spack.mk file in def patch, that looks as follows: ``` BOOT_CFLAGS := $(filter-out -O% -g%, $(BOOT_CFLAGS)) -O2 -g -march=znver2 -mtune=znver2 CFLAGS_FOR_TARGET := $(filter-out -O% -g%, $(CFLAGS_FOR_TARGET)) -O2 -g -march=znver2 -mtune=znver2 CXXFLAGS_FOR_TARGET := $(filter-out -O% -g%, $(CXXFLAGS_FOR_TARGET)) -O2 -g -march=znver2 -mtune=znver2 ``` --- .../repos/builtin/packages/gcc/package.py | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py index b12f6ec360..8db53ecb87 100644 --- a/var/spack/repos/builtin/packages/gcc/package.py +++ b/var/spack/repos/builtin/packages/gcc/package.py @@ -8,6 +8,8 @@ import re import sys +from archspec.cpu import UnsupportedMicroarchitecture + import llnl.util.tty as tty import spack.platforms @@ -111,6 +113,13 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage): variant('graphite', default=False, description='Enable Graphite loop optimizations (requires ISL)') + variant('build_type', default='RelWithDebInfo', + values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'), + description='CMake-like build type. ' + 'Debug: -O0 -g; Release: -O3; ' + 'RelWithDebInfo: -O2 -g; MinSizeRel: -Os') + variant('profiled', default=False, description='Use Profile Guided Optimization', + when='+bootstrap %gcc') depends_on('flex', type='build', when='@master') @@ -508,6 +517,57 @@ def patch(self): 'Enum(ptx_isa) Var(ptx_isa_option) Init(PTX_ISA_SM35)', 'gcc/config/nvptx/nvptx.opt', string=True) + self.build_optimization_config() + + def get_common_target_flags(self, spec): + """Get the right (but pessimistic) architecture specific flags supported by + both host gcc and to-be-built gcc. For example: gcc@7 %gcc@12 target=znver3 + should pick -march=znver1, since that's what gcc@7 supports.""" + archs = [spec.target] + spec.target.ancestors + for arch in archs: + try: + return arch.optimization_flags('gcc', spec.version) + except UnsupportedMicroarchitecture: + pass + # no arch specific flags in common, unlikely to happen. + return '' + + def build_optimization_config(self): + """Write a config/spack.mk file with sensible optimization flags, taking into + account bootstrapping subtleties.""" + build_type_flags = { + 'Debug': '-O0 -g', + 'Release': '-O3', + 'RelWithDebInfo': '-O2 -g', + 'MinSizeRel': '-Os' + } + + # Generic optimization flags. + flags = build_type_flags[self.spec.variants['build_type'].value] + + # Pessimistic target specific flags. For example, when building + # gcc@11 %gcc@7 on znver3, Spack will fix the target to znver1 during + # concretization, so we'll stick to that. The other way around however can + # result in compilation errors, when gcc@7 is built with gcc@11, and znver3 + # is taken as a the target, which gcc@7 doesn't support. + if '+bootstrap %gcc' in self.spec: + flags += ' ' + self.get_common_target_flags(self.spec) + + if '+bootstrap' in self.spec: + variables = ['BOOT_CFLAGS', 'CFLAGS_FOR_TARGET', 'CXXFLAGS_FOR_TARGET'] + else: + variables = ['CFLAGS', 'CXXFLAGS'] + + # Redefine a few variables without losing other defaults: + # BOOT_CFLAGS = $(filter-out -O% -g%, $(BOOT_CFLAGS)) -O3 + # This makes sure that build_type=Release is really -O3, not -O3 -g. + fmt_string = '{} := $(filter-out -O% -g%, $({})) {}\n' + with open('config/spack.mk', 'w') as f: + for var in variables: + f.write(fmt_string.format(var, var, flags)) + # Improve the build time for stage 2 a bit by enabling -O1 in stage 1. + # Note: this is ignored under ~bootstrap. + f.write('STAGE1_CFLAGS += -O1\n') # https://gcc.gnu.org/install/configure.html def configure_args(self): @@ -606,6 +666,7 @@ def configure_args(self): boot_ldflags = stage1_ldflags + ' -static-libstdc++ -static-libgcc' options.append('--with-stage1-ldflags=' + stage1_ldflags) options.append('--with-boot-ldflags=' + boot_ldflags) + options.append('--with-build-config=spack') return options @@ -668,6 +729,12 @@ def nvptx_install(self): make() make('install') + @property + def build_targets(self): + if '+profiled' in self.spec: + return ['profiledbootstrap'] + return [] + @property def install_targets(self): if '+strip' in self.spec: