diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2017-10-12 18:37:22 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2017-10-13 19:46:57 -0700 |
commit | 55f85f23079b7229204e89e29d568ac969931449 (patch) | |
tree | 5b551d3f2cde96cda678202d8ec1be50d6c616ba /lib | |
parent | 2e1aa0a5e956a293543bfb2f01d1673bb67a9dbb (diff) | |
download | spack-55f85f23079b7229204e89e29d568ac969931449.tar.gz spack-55f85f23079b7229204e89e29d568ac969931449.tar.bz2 spack-55f85f23079b7229204e89e29d568ac969931449.tar.xz spack-55f85f23079b7229204e89e29d568ac969931449.zip |
Cache compilers parsed from config files
- Spack ends up constructing compilers frequently from YAML data.
- This caches the result of parsing the compiler config
- The logic in compilers/__init__.py could use a bigger cleanup, but this
makes concretization much faster for now.
- on macOS, this also ensures that xcrun is called only twice, as opposed
to every time a new compiler object is constructed.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/compilers/__init__.py | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index f3a159d6b9..fba3352520 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -45,6 +45,9 @@ _other_instance_vars = ['modules', 'operating_system', 'environment', 'extra_rpaths'] _cache_config_file = [] +#: cache of compilers constructed from config data, keyed by config entry id. +_compiler_cache = {} + def _auto_compiler_spec(function): def converter(cspec_like, *args, **kwargs): @@ -251,35 +254,42 @@ def compilers_for_arch(arch_spec, scope=None): def compiler_from_config_entry(items): - cspec = spack.spec.CompilerSpec(items['spec']) - os = items.get('operating_system', None) - target = items.get('target', None) - - if not ('paths' in items and - all(n in items['paths'] for n in _path_instance_vars)): - raise InvalidCompilerConfigurationError(cspec) - - cls = class_for_compiler_name(cspec.name) - - compiler_paths = [] - for c in _path_instance_vars: - compiler_path = items['paths'][c] - if compiler_path != 'None': - compiler_paths.append(compiler_path) - else: - compiler_paths.append(None) - - mods = items.get('modules') - if mods == 'None': - mods = [] - - alias = items.get('alias', None) - compiler_flags = items.get('flags', {}) - environment = items.get('environment', {}) - extra_rpaths = items.get('extra_rpaths', []) - - return cls(cspec, os, target, compiler_paths, mods, alias, - environment, extra_rpaths, **compiler_flags) + config_id = id(items) + compiler = _compiler_cache.get(config_id, None) + + if compiler is None: + cspec = spack.spec.CompilerSpec(items['spec']) + os = items.get('operating_system', None) + target = items.get('target', None) + + if not ('paths' in items and + all(n in items['paths'] for n in _path_instance_vars)): + raise InvalidCompilerConfigurationError(cspec) + + cls = class_for_compiler_name(cspec.name) + + compiler_paths = [] + for c in _path_instance_vars: + compiler_path = items['paths'][c] + if compiler_path != 'None': + compiler_paths.append(compiler_path) + else: + compiler_paths.append(None) + + mods = items.get('modules') + if mods == 'None': + mods = [] + + alias = items.get('alias', None) + compiler_flags = items.get('flags', {}) + environment = items.get('environment', {}) + extra_rpaths = items.get('extra_rpaths', []) + + compiler = cls(cspec, os, target, compiler_paths, mods, alias, + environment, extra_rpaths, **compiler_flags) + _compiler_cache[id(items)] = compiler + + return compiler def get_compilers(config, cspec=None, arch_spec=None): |