summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2017-10-12 18:37:22 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2017-10-13 19:46:57 -0700
commit55f85f23079b7229204e89e29d568ac969931449 (patch)
tree5b551d3f2cde96cda678202d8ec1be50d6c616ba /lib
parent2e1aa0a5e956a293543bfb2f01d1673bb67a9dbb (diff)
downloadspack-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__.py68
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):