aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-08-11 11:07:09 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-08-11 11:07:09 +0200
commit037e5e9224648fdc9f3956d612fb476966847f5c (patch)
tree7c829f581fbd0caafd4a121c7f3a1ab60e3c5557 /libbuild2/cc
parent67db22fcae32c8a8014866ef2ee55b6c7733c3f9 (diff)
Optimize process_libraries() some more
Diffstat (limited to 'libbuild2/cc')
-rw-r--r--libbuild2/cc/common.cxx56
-rw-r--r--libbuild2/cc/common.hxx2
-rw-r--r--libbuild2/cc/init.cxx3
3 files changed, 45 insertions, 16 deletions
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index 4b4aef8..d9afd21 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -99,13 +99,13 @@ namespace build2
bool exp)>& proc_opt, // *.export.
bool self /*= false*/, // Call proc_lib on l?
library_cache* cache,
- small_vector<const target*, 16>* chain) const
+ small_vector<const target*, 24>* chain) const
{
library_cache cache_storage;
if (cache == nullptr)
cache = &cache_storage;
- small_vector<const target*, 16> chain_storage;
+ small_vector<const target*, 24> chain_storage;
if (chain == nullptr)
{
chain = &chain_storage;
@@ -126,21 +126,30 @@ namespace build2
// See what type of library this is (C, C++, etc). Use it do decide
// which x.libs variable name to use. If it's unknown, then we only
// look into prerequisites. Note: lookup starting from rule-specific
- // variables (target should already be matched).
+ // variables (target should already be matched). Note also that for
+ // performance we use lookup_original() directly and only look in the
+ // target (so no target type/pattern-specific).
//
- const string* t (cast_null<string> (l.state[a][c_type]));
+ const string* t (
+ cast_null<string> (
+ l.state[a].lookup_original (c_type, true /* target_only */).first));
bool impl (proc_impl && proc_impl (l, la));
bool cc (false), same (false);
- lookup c_e_libs;
- lookup x_e_libs;
-
if (t != nullptr)
{
cc = (*t == "cc");
same = (!cc && *t == x);
+ }
+
+ const scope& bs (t == nullptr || cc ? top_bs : l.base_scope ());
+ lookup c_e_libs;
+ lookup x_e_libs;
+
+ if (t != nullptr)
+ {
// Note that we used to treat *.export.libs set on the liba/libs{}
// members as *.libs overrides rather than as member-specific
// interface dependencies. This difference in semantics proved to be
@@ -152,12 +161,25 @@ namespace build2
// be set to NULL or empty (this is why we check for the result
// being defined).
//
- c_e_libs = l[impl ? c_export_impl_libs : c_export_libs];
+ // Note: for performance we call lookup_original() directly (we know
+ // these variables are not overridable) and pass the base scope we
+ // have already resolved.
+ //
+ // @@ PERF: do target_only (helps a bit in non-installed case)?
+ //
+ {
+ const variable& v (impl ? c_export_impl_libs : c_export_libs);
+ c_e_libs = l.lookup_original (v, false, &bs).first;
+ }
if (!cc)
- x_e_libs = l[same
- ? (impl ? x_export_impl_libs : x_export_libs)
- : vp[*t + (impl ? ".export.impl_libs" : ".export.libs")]];
+ {
+ const variable& v (
+ same
+ ? (impl ? x_export_impl_libs : x_export_libs)
+ : vp[*t + (impl ? ".export.impl_libs" : ".export.libs")]);
+ x_e_libs = l.lookup_original (v, false, &bs).first;
+ }
// Process options first.
//
@@ -252,7 +274,6 @@ namespace build2
break;
}
- const scope& bs (t == nullptr || cc ? top_bs : l.base_scope ());
optional<optional<linfo>> li; // Calculate lazily.
const dir_paths* sysd (nullptr); // Resolve lazily.
@@ -275,7 +296,7 @@ namespace build2
{
li = (t == nullptr || cc)
? top_li
- : optional<linfo> (link_info (bs, link_type (l).type));
+ : optional<linfo> (link_info (bs, link_type (l).type)); // @@ PERF
};
// Only go into prerequisites (implementation) if instructed and we
@@ -558,10 +579,15 @@ namespace build2
// used to build the library. Since libraries in (non-export)
// *.libs are not targets, we don't need to recurse.
//
+ // Note: for performance we call lookup_original() directly
+ // (we know these variables are not overridable) and pass the
+ // base scope we have already resolved.
+ //
if (proc_lib)
{
- proc_imp (l[c_libs]);
- proc_imp (l[same ? x_libs : vp[*t + ".libs"]]);
+ const variable& v (same ? x_libs : vp[*t + ".libs"]);
+ proc_imp (l.lookup_original (c_libs, false, &bs).first);
+ proc_imp (l.lookup_original (v, false, &bs).first);
}
}
}
diff --git a/libbuild2/cc/common.hxx b/libbuild2/cc/common.hxx
index f15bf23..64de228 100644
--- a/libbuild2/cc/common.hxx
+++ b/libbuild2/cc/common.hxx
@@ -298,7 +298,7 @@ namespace build2
const function<bool (const target&, const string&, bool, bool)>&,
bool = false,
library_cache* = nullptr,
- small_vector<const target*, 16>* = nullptr) const;
+ small_vector<const target*, 24>* = nullptr) const;
const target*
search_library (action a,
diff --git a/libbuild2/cc/init.cxx b/libbuild2/cc/init.cxx
index f201d79..07f082f 100644
--- a/libbuild2/cc/init.cxx
+++ b/libbuild2/cc/init.cxx
@@ -133,6 +133,9 @@ namespace build2
// but specific language is not known. Used in the import installed
// logic.
//
+ // Note that this variable cannot be set via the target type/pattern-
+ // specific mechanism (see process_libraries()).
+ //
vp.insert<string> ("cc.type", v_t);
// If set and is true, then this (imported) library has been found in a