]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: optimize specialization of nested templated classes
authorPatrick Palka <ppalka@redhat.com>
Fri, 10 Jun 2022 20:09:48 +0000 (16:09 -0400)
committerPatrick Palka <ppalka@redhat.com>
Fri, 10 Jun 2022 20:09:48 +0000 (16:09 -0400)
commitcb7fd1ea85feea7ef65328330fc2577a95e99400
tree24a8ec0e9d7d7b6ab46e4f2211841a66ae4be44a
parente6d369bbdb4eb5f03eec233ef9905013a735fd71
c++: optimize specialization of nested templated classes

When substituting a class template specialization, tsubst_aggr_type
substitutes the TYPE_CONTEXT before passing it to lookup_template_class.
This appears to be unnecessary, however, because the the initial value
of lookup_template_class's context parameter is unused outside of the
IDENTIFIER_NODE case, and l_t_c performs its own substitution of the
context, anyway.  So this patch removes the redundant substitution in
tsubst_aggr_type.  Doing so causes us to ICE on template/nested5.C
because during lookup_template_class for A<T>::C::D<S> with T=E and S=S,
we substitute and complete the context A<T>::C with T=E, which in turn
registers the desired dependent specialization of D for us which we end
up trying to register twice.  This patch fixes this by checking the
specializations table again after completion of the context.

This patch also implements a couple of other optimizations:

  * In lookup_template_class, if the context of the partially
    instantiated template is already non-dependent, then we could
    reuse that instead of substituting the context of the most
    general template.
  * During tsubst_decl for the TYPE_DECL for an injected-class-name,
    we can avoid substituting its TREE_TYPE.  We can also avoid
    template argument substitution/coercion for this TYPE_DECL, and
    for class-scope non-template VAR_/TYPE_DECLs more generally.

Together these optimizations improve memory usage for the range-v3
file test/view/zip.cc by about 5%.

gcc/cp/ChangeLog:

* pt.cc (lookup_template_class): Remove dead stores to
context parameter.  Don't substitute the context of the
most general template if that of the partially instantiated
template is already non-dependent.  Check the specializations
table again after completing the context of a nested dependent
specialization.
(tsubst_aggr_type) <case RECORD_TYPE>: Don't substitute
TYPE_CONTEXT or pass it to lookup_template_class.
(tsubst_decl) <case TYPE_DECL, case TYPE_DECL>: Avoid substituting
the TREE_TYPE for DECL_SELF_REFERENCE_P.  Avoid template argument
substitution or coercion in some cases.
gcc/cp/pt.cc