aboutsummaryrefslogtreecommitdiff
path: root/build2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-01-08 12:46:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-01-08 12:46:10 +0200
commit8b07d68462c5fec92fd5a4aab77ddfd425d1f8d0 (patch)
tree155b5d4e1789bdb2523081da12201d87d5fa4153 /build2/cc
parentf6c3788de3d148c90aba705d045b1d92e7fea20a (diff)
Implement compiler_info caching
Diffstat (limited to 'build2/cc')
-rw-r--r--build2/cc/gcc.cxx4
-rw-r--r--build2/cc/guess.cxx41
-rw-r--r--build2/cc/guess.hxx2
-rw-r--r--build2/cc/module.cxx26
-rw-r--r--build2/cc/module.hxx14
-rw-r--r--build2/cc/msvc.cxx4
6 files changed, 62 insertions, 29 deletions
diff --git a/build2/cc/gcc.cxx b/build2/cc/gcc.cxx
index ec69524..523236a 100644
--- a/build2/cc/gcc.cxx
+++ b/build2/cc/gcc.cxx
@@ -28,7 +28,7 @@ namespace build2
// (Clang, Intel) using the -v -E </dev/null method.
//
dir_paths config_module::
- gcc_header_search_paths (process_path& xc, scope& rs) const
+ gcc_header_search_paths (const process_path& xc, scope& rs) const
{
dir_paths r;
@@ -161,7 +161,7 @@ namespace build2
// (Clang, Intel) using the -print-search-dirs option.
//
dir_paths config_module::
- gcc_library_search_paths (process_path& xc, scope& rs) const
+ gcc_library_search_paths (const process_path& xc, scope& rs) const
{
dir_paths r;
diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx
index 32c3166..9299885 100644
--- a/build2/cc/guess.cxx
+++ b/build2/cc/guess.cxx
@@ -4,6 +4,7 @@
#include <build2/cc/guess.hxx>
+#include <map>
#include <cstring> // strlen(), strchr()
#include <build2/diagnostics.hxx>
@@ -44,12 +45,12 @@ namespace build2
//
static string
stdlib (lang xl,
- const process_path& xc,
+ const process_path& xp,
const strings* c_po, const strings* x_po,
const strings* c_co, const strings* x_co,
const char* src)
{
- cstrings args {xc.recall_string ()};
+ cstrings args {xp.recall_string ()};
if (c_po != nullptr) append_options (args, *c_po);
if (x_po != nullptr) append_options (args, *x_po);
if (c_co != nullptr) append_options (args, *c_co);
@@ -72,6 +73,7 @@ namespace build2
// options but that we simply leave to blow up later).
//
process pr (run_start (3 /* verbosity */,
+ xp,
args.data (),
-1 /* stdin */,
-1 /* stdout */,
@@ -268,7 +270,7 @@ namespace build2
guess_result r;
- process_path xp (run_search (xc, true));
+ process_path xp (run_search (xc, false /* init */)); // Note: cached.
// Start with -v. This will cover gcc and clang.
//
@@ -601,7 +603,7 @@ namespace build2
// multi-arch support), then use the result. Otherwise, fallback to
// -dumpmachine (older gcc or not multi-arch).
//
- cstrings args {xc.string ().c_str (), "-print-multiarch"};
+ cstrings args {xp.recall_string (), "-print-multiarch"};
if (c_co != nullptr) append_options (args, *c_co);
if (x_co != nullptr) append_options (args, *x_co);
args.push_back (nullptr);
@@ -1042,7 +1044,7 @@ namespace build2
// "Intel(R)" "64"
// "Intel(R)" "MIC" (-dumpmachine says: x86_64-k1om-linux)
//
- cstrings args {xc.string ().c_str (), "-V"};
+ cstrings args {xp.recall_string (), "-V"};
if (c_co != nullptr) append_options (args, *c_co);
if (x_co != nullptr) append_options (args, *x_co);
args.push_back (nullptr);
@@ -1408,13 +1410,38 @@ namespace build2
move (xsl)};
}
- compiler_info
+ // Compiler checks can be expensive (we often need to run the compiler
+ // several times) so we cache the result.
+ //
+ static map<string, compiler_info> cache;
+
+ const compiler_info&
guess (lang xl,
const path& xc,
const strings* c_po, const strings* x_po,
const strings* c_co, const strings* x_co,
const strings* c_lo, const strings* x_lo)
{
+ // First check the cache.
+ //
+ string key;
+ {
+ sha256 cs;
+ cs.append (static_cast<size_t> (xl));
+ cs.append (xc.string ());
+ if (c_po != nullptr) hash_options (cs, *c_po);
+ if (x_po != nullptr) hash_options (cs, *x_po);
+ if (c_co != nullptr) hash_options (cs, *c_co);
+ if (x_co != nullptr) hash_options (cs, *x_co);
+ if (c_lo != nullptr) hash_options (cs, *c_lo);
+ if (x_lo != nullptr) hash_options (cs, *x_lo);
+ key = cs.string ();
+
+ auto i (cache.find (key));
+ if (i != cache.end ())
+ return i->second;
+ }
+
string pre (pre_guess (xl, xc));
guess_result gr;
@@ -1520,7 +1547,7 @@ namespace build2
r.bin_pattern = p.directory ().representation (); // Trailing slash.
}
- return r;
+ return (cache[key] = move (r));
}
path
diff --git a/build2/cc/guess.hxx b/build2/cc/guess.hxx
index d6ca28d..8c291a9 100644
--- a/build2/cc/guess.hxx
+++ b/build2/cc/guess.hxx
@@ -202,7 +202,7 @@ namespace build2
// of fur in multiple places doesn't seem wise, especially considering
// that most of it will be the same, at least for C and C++.
//
- compiler_info
+ const compiler_info&
guess (lang,
const path& xc,
const strings* c_poptions, const strings* x_poptions,
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 1020bd6..c56bca9 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -107,14 +107,15 @@ namespace build2
// Figure out which compiler we are dealing with, its target, etc.
//
const path& xc (cast<path> (*p.first));
- ci = build2::cc::guess (x_lang,
- xc,
- cast_null<strings> (rs[config_c_poptions]),
- cast_null<strings> (rs[config_x_poptions]),
- cast_null<strings> (rs[config_c_coptions]),
- cast_null<strings> (rs[config_x_coptions]),
- cast_null<strings> (rs[config_c_loptions]),
- cast_null<strings> (rs[config_x_loptions]));
+ ci_ = &build2::cc::guess (x_lang,
+ xc,
+ cast_null<strings> (rs[config_c_poptions]),
+ cast_null<strings> (rs[config_x_poptions]),
+ cast_null<strings> (rs[config_c_coptions]),
+ cast_null<strings> (rs[config_x_coptions]),
+ cast_null<strings> (rs[config_c_loptions]),
+ cast_null<strings> (rs[config_x_loptions]));
+ const compiler_info& ci (*ci_);
// Split/canonicalize the target. First see if the user asked us to
// use config.sub.
@@ -262,6 +263,7 @@ namespace build2
{
tracer trace (x, "config_init");
+ const compiler_info& ci (*ci_);
const target_triplet& tt (cast<target_triplet> (rs[x_target]));
// Translate x_std value (if any) to the compiler option(s) (if any).
@@ -398,12 +400,12 @@ namespace build2
}
}
- rs.assign (x_path) = move (ci.path);
+ rs.assign (x_path) = process_path (ci.path, false /* init */);
rs.assign (x_sys_lib_dirs) = move (lib_dirs);
rs.assign (x_sys_inc_dirs) = move (inc_dirs);
- rs.assign (x_signature) = move (ci.signature);
- rs.assign (x_checksum) = move (ci.checksum);
+ rs.assign (x_signature) = ci.signature;
+ rs.assign (x_checksum) = ci.checksum;
// config.x.{p,c,l}options
// config.x.libs
@@ -440,7 +442,7 @@ namespace build2
variable_map h;
if (!ci.bin_pattern.empty ())
- h.assign ("config.bin.pattern") = move (ci.bin_pattern);
+ h.assign ("config.bin.pattern") = ci.bin_pattern;
load_module (rs, rs, "cc.core.config", loc, false, h);
}
diff --git a/build2/cc/module.hxx b/build2/cc/module.hxx
index 928e16c..de61611 100644
--- a/build2/cc/module.hxx
+++ b/build2/cc/module.hxx
@@ -52,20 +52,24 @@ namespace build2
size_t sys_lib_dirs_extra; // First extra path (size if none).
size_t sys_inc_dirs_extra; // First extra path (size if none).
- compiler_info ci; // Note: some members are moved from.
+ const compiler_info* ci_;
private:
+ // Defined in gcc.cxx.
+ //
dir_paths
- gcc_header_search_paths (process_path&, scope&) const; // gcc.cxx
+ gcc_header_search_paths (const process_path&, scope&) const;
dir_paths
- gcc_library_search_paths (process_path&, scope&) const; // gcc.cxx
+ gcc_library_search_paths (const process_path&, scope&) const;
+ // Defined in msvc.cxx.
+ //
dir_paths
- msvc_header_search_paths (process_path&, scope&) const; // msvc.cxx
+ msvc_header_search_paths (const process_path&, scope&) const;
dir_paths
- msvc_library_search_paths (process_path&, scope&) const; // msvc.cxx
+ msvc_library_search_paths (const process_path&, scope&) const;
private:
bool new_; // See guess() and init() for details.
diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx
index b418f78..1d94f66 100644
--- a/build2/cc/msvc.cxx
+++ b/build2/cc/msvc.cxx
@@ -86,7 +86,7 @@ namespace build2
// Extract system header search paths from MSVC.
//
dir_paths config_module::
- msvc_header_search_paths (process_path&, scope&) const
+ msvc_header_search_paths (const process_path&, scope&) const
{
// The compiler doesn't seem to have any built-in paths and all of them
// come from the INCLUDE environment variable.
@@ -105,7 +105,7 @@ namespace build2
// Extract system library search paths from MSVC.
//
dir_paths config_module::
- msvc_library_search_paths (process_path&, scope&) const
+ msvc_library_search_paths (const process_path&, scope&) const
{
// The linker doesn't seem to have any built-in paths and all of them
// come from the LIB environment variable.