From 2ede341d59b4ab259caf808dfa65c0ac380ba347 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 8 Mar 2022 10:57:52 +0200 Subject: Improve performance of update during match for multiple targets --- libbuild2/algorithm.cxx | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'libbuild2/algorithm.cxx') diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index cbf0495..d72e95e 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -2119,6 +2119,75 @@ namespace build2 } } + bool + update_during_match (tracer& trace, + action a, + prerequisite_targets& pts, + uintptr_t mask) + { + // On the first pass detect and handle unchanged tragets. Note that we + // have to do it in a separate pass since we cannot call matched_state() + // once we've switched the phase. + // + context* ctx (nullptr); + + for (prerequisite_target& p: pts) + { + if ((p.include & mask) != 0) + { + if (p.target != nullptr) + { + const target& pt (*p.target); + + target_state os (pt.matched_state (a)); + + if (os != target_state::unchanged) + { + if (ctx == nullptr) + ctx = &pt.ctx; + + p.data = static_cast (os); + continue; + } + } + + p.data = 0; + } + } + + // If all unchanged, we are done. + // + if (ctx == nullptr) + return false; + + phase_switch ps (*ctx, run_phase::execute); + + bool r (false); + + for (prerequisite_target& p: pts) + { + if ((p.include & mask) != 0 && p.data != 0) + { + const target& pt (*p.target); + + target_state os (static_cast (p.data)); + target_state ns (execute_direct (a, pt)); + + if (ns != os && ns != target_state::unchanged) + { + l6 ([&]{trace << "updated " << pt + << "; old state " << os + << "; new state " << ns;}); + r = true; + } + + p.data = 0; + } + } + + return r; + } + static inline void blank_adhoc_member (const target*&) { -- cgit v1.1