diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-10-06 10:04:52 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-10-06 10:04:52 -0400 |
commit | 09df0d8b14dda66c5159a1b2cf85b73f26282152 (patch) | |
tree | 9758930d46b0e4aae5170aaf5343e542f89f46c1 /gcc/testsuite | |
parent | 3ec926d36fbf7cb3ff45759471139f3a71d1c4de (diff) | |
download | gcc-09df0d8b14dda66c5159a1b2cf85b73f26282152.zip gcc-09df0d8b14dda66c5159a1b2cf85b73f26282152.tar.gz gcc-09df0d8b14dda66c5159a1b2cf85b73f26282152.tar.bz2 |
c++: remove optimize_specialization_lookup_p
Roughly speaking, optimize_specialization_lookup_p returns true for a
non-template member function of a class template, e.g.
template<class T> struct A { int f(); };
The idea behind the optimization guarded by this predicate is that if
we want to look up the specialization A<T>::f [with T=int], then we can
just do a name lookup for f in A<int> and avoid having to add a
spec_entry for f in the decl_specializations table.
But the benefit of this optimization seems questionable because in
order to do the name lookup we first need to look up A<T> [with T=int]
in the type_specializations table, which is as expensive as the
decl_specializations lookup we're avoiding. And according to some
experiments (using stdc++.h, range-v3 and libstdc++ tests) the compiler
is slightly (<1%) _faster_ if we disable this optimization.
Additionally, this optimization means we won't record an explicit
specialization in decl_specializations for such a template either, which
is an unfortunate inconsistency that apparently breaks the below modules
testcase.
So since this optimization doesn't improve performance, and complicates
the explicit specialization story which causes issues with modules, this
patch proposes to remove it.
gcc/cp/ChangeLog:
* pt.cc (optimize_specialization_lookup_p): Remove.
(retrieve_specialization): Assume the above returns false
and simplify accordingly.
(register_specialization): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/modules/indirect-3_b.C: Expect that the entity
foo::TPL<0>::frob is tagged as a specialization instead
of as a declaration.
* g++.dg/modules/tpl-spec-8_a.H: New test.
* g++.dg/modules/tpl-spec-8_b.C: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/g++.dg/modules/indirect-3_b.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C | 8 |
3 files changed, 19 insertions, 1 deletions
diff --git a/gcc/testsuite/g++.dg/modules/indirect-3_b.C b/gcc/testsuite/g++.dg/modules/indirect-3_b.C index 5bdfc1d..038b01e 100644 --- a/gcc/testsuite/g++.dg/modules/indirect-3_b.C +++ b/gcc/testsuite/g++.dg/modules/indirect-3_b.C @@ -23,7 +23,7 @@ namespace bar // { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::TPL'@'foo' section} module } } // { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } -// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x0>'\n \[1\]=specialization declaration '::foo@foo:.::TPL<0x0>::TPL<0x0>'\n( \[.\]=[^\n]* '\n)* \[.\]=decl definition '::foo@foo:.::TPL<0x0>::frob<0x0>'\n} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x0>'\n \[1\]=specialization definition '::foo@foo:.::TPL<0x0>::frob<0x0>'\n \[2\]=specialization declaration '::foo@foo:.::TPL<0x0>::TPL<0x0>'} module } } // { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::X@foo:.::frob<0x0>'} module } } // { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::TPL<0x0>'} module } } diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H b/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H new file mode 100644 index 0000000..5309130 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-spec-8_a.H @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template<class T> +struct A { + static void f() { T::nonexistent; } +}; + +template<> +inline void A<int>::f() { } diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C b/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C new file mode 100644 index 0000000..f23eb37 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-spec-8_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +// { dg-do link } + +import "tpl-spec-8_a.H"; + +int main() { + A<int>::f(); +} |