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
```
This commit is contained in:
Harmen Stoppels 2022-05-21 23:44:51 +02:00 committed by GitHub
parent c6c3d243e1
commit 2113b625d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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: