https://gcc.gnu.org/g:bb26018080699913959526c89ce2e618c97768ec

commit r17-1791-gbb26018080699913959526c89ce2e618c97768ec
Author: Jason Merrill <[email protected]>
Date:   Tue Jun 23 17:28:36 2026 -0400

    c++/modules: dependent ADL laziness [PR125334]
    
    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.

Diff:
---
 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 17390356b09c..060d2ba344c7 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 abe772d49c71..66d2af56d92c 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
 }

Reply via email to