diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-08-11 11:07:09 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-08-11 11:07:09 +0200 |
commit | 037e5e9224648fdc9f3956d612fb476966847f5c (patch) | |
tree | 7c829f581fbd0caafd4a121c7f3a1ab60e3c5557 | |
parent | 67db22fcae32c8a8014866ef2ee55b6c7733c3f9 (diff) |
Optimize process_libraries() some more
-rw-r--r-- | libbuild2/cc/common.cxx | 56 | ||||
-rw-r--r-- | libbuild2/cc/common.hxx | 2 | ||||
-rw-r--r-- | libbuild2/cc/init.cxx | 3 | ||||
-rw-r--r-- | libbuild2/target.cxx | 14 | ||||
-rw-r--r-- | libbuild2/target.hxx | 7 |
5 files changed, 59 insertions, 23 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 diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index a686fc2..24ad01e 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -146,7 +146,9 @@ namespace build2 } pair<lookup, size_t> target:: - lookup_original (const variable& var, bool target_only) const + lookup_original (const variable& var, + bool target_only, + const scope* bs) const { pair<lookup_type, size_t> r (lookup_type (), 0); @@ -185,10 +187,12 @@ namespace build2 target_key tk (key ()); target_key gk (g != nullptr ? g->key () : target_key {}); - auto p (base_scope ().lookup_original ( - var, - &tk, - g != nullptr ? &gk : nullptr)); + if (bs == nullptr) + bs = &base_scope (); + + auto p (bs->lookup_original (var, + &tk, + g != nullptr ? &gk : nullptr)); r.first = move (p.first); r.second = r.first ? r.second + p.second : p.second; diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 01f01e1..de17fa8 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -446,10 +446,13 @@ namespace build2 } // If target_only is true, then only look in target and its target group - // without continuing in scopes. + // without continuing in scopes. As an optimization, the caller can also + // pass the base scope of the target, if already known. // pair<lookup_type, size_t> - lookup_original (const variable&, bool target_only = false) const; + lookup_original (const variable&, + bool target_only = false, + const scope* bs = nullptr) const; // Return a value suitable for assignment. See scope for details. // |