Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
I was digging into modules for another bug and remembered an earlier thought
that a possible further improvement for this PR would be to just mark the
ADL functions as reachable, not actual dependencies of the current entity.
This turns out to be as simple as removing the call to add_dependency; the
test still passes, but now the ADL functions are loaded lazily because they
have their own dependency groups instead of being tightly coupled to the
call site.
This provides a speed-up of about 24% on the performance test in this PR
with my debugging build of trunk.
PR c++/125334
gcc/cp/ChangeLog:
* module.cc (depset::hash::find_dependencies): Don't add_dependency
dependent ADL functions.
gcc/testsuite/ChangeLog:
* g++.dg/modules/adl-12_b.C: Check for lazy loading.
---
gcc/cp/module.cc | 6 ++++--
gcc/testsuite/g++.dg/modules/adl-12_b.C | 8 +++++++-
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 17390356b09..060d2ba344c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -15730,7 +15730,9 @@ depset::hash::find_dependencies (module_state *module)
tree lookup = lookup_arg_dependent (info.name, NULL_TREE,
info.args, true);
for (tree fn : lkp_range (lookup))
- add_dependency (make_dependency (fn, EK_DECL));
+ /* We don't need to add_dependency, just have
+ make_dependency build an ADL binding. */
+ make_dependency (fn, EK_DECL);
if (info.rewrite)
{
@@ -15738,7 +15740,7 @@ depset::hash::find_dependencies (module_state *module)
lookup = lookup_arg_dependent (rewrite_name,
NULL_TREE,
info.args, true);
for (tree fn : lkp_range (lookup))
- add_dependency (make_dependency (fn, EK_DECL));
+ make_dependency (fn, EK_DECL);
}
release_tree_vector (info.args);
}
diff --git a/gcc/testsuite/g++.dg/modules/adl-12_b.C
b/gcc/testsuite/g++.dg/modules/adl-12_b.C
index abe772d49c7..66d2af56d92 100644
--- a/gcc/testsuite/g++.dg/modules/adl-12_b.C
+++ b/gcc/testsuite/g++.dg/modules/adl-12_b.C
@@ -1,4 +1,4 @@
-// { dg-additional-options "-fmodules" }
+// { dg-additional-options "-fmodules -fdump-lang-module" }
// Example from [temp.dep.candidate]
namespace Q {
@@ -12,8 +12,12 @@ import M;
void test(Q::X x) {
g(x); // OK
+ // { dg-final { scan-lang-dump "Lazily binding '::Q::g_impl'" module } }
+ // { dg-final { scan-lang-dump "Lazily binding '::Q::operator-'" module } }
Partial<Q::X>::f<int>();
+ // { dg-final { scan-lang-dump "Lazily binding '::Q::go_partial'" module } }
Partial<Q::X>::o<int>();
+ // { dg-final { scan-lang-dump "Lazily binding '::Q::operator/'" module } }
incomplete(0); // OK
needs_completion(0); // { dg-bogus "required from here" "PR123235" { xfail
*-*-* } }
// { dg-prune-output "not declared in this scope" }
@@ -22,5 +26,7 @@ void test(Q::X x) {
rewrite_ops(0); // OK
rewrite_ops_error(0); // { dg-message "required from here" "" { target
c++20 } }
// { dg-prune-output "no match for" }
+ // { dg-final { scan-lang-dump {Lazily binding '::ops1::operator<=>'} module
{ target c++20 } } }
+ // { dg-final { scan-lang-dump {Lazily binding '::ops1::operator=='} module
{ target c++20 } } }
#endif
}
--
2.54.0