diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-09-20 12:07:15 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-09-20 12:07:15 -0400 |
commit | 915574e538322aad5195bc3b6be2a4f85bbd2467 (patch) | |
tree | 23dff84f3051ac24ab4b3c1c5618895e6f74fe8d /gcc | |
parent | 1a554a2c9f33fdb3c170f1c37274037ece050114 (diff) | |
download | gcc-915574e538322aad5195bc3b6be2a4f85bbd2467.zip gcc-915574e538322aad5195bc3b6be2a4f85bbd2467.tar.gz gcc-915574e538322aad5195bc3b6be2a4f85bbd2467.tar.bz2 |
c++: further optimize tsubst_template_decl
This patch makes tsubst_template_decl use use_spec_table=false also in
the non-class non-function template case, to avoid computing 'argvec' and
doing a hash table lookup from tsubst_decl (when partially instantiating
a member variable/alias template).
This change reveals that for function templates, tsubst_template_decl
registers the partially instantiated TEMPLATE_DECL, whereas for other
non-class templates it registers the corresponding DECL_TEMPLATE_RESULT
which is an interesting inconsistency that I decided to preserve for now.
Trying to consistently register the TEMPLATE_DECL (or DECL_TEMPLATE_RESULT)
causes modules ICEs which I didn't look into.
In passing, in tsubst_function_decl I noticed 'argvec' is unused
when 'lambda_fntype' is set (since lambdas aren't recorded in the
specializations table), so we can avoid computing it in that case.
gcc/cp/ChangeLog:
* pt.cc (tsubst_function_decl): Don't bother computing 'argvec'
when 'lambda_fntype' is set.
(tsubst_template_decl): Make sure we return a TEMPLATE_DECL
during specialization lookup. In the non-class non-function
template case, use tsubst_decl directly with use_spec_table=false,
update DECL_TI_ARGS and call register_specialization like
tsubst_decl would have done if use_spec_table=true.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.cc | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 777ff59..8758e21 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -14370,7 +14370,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, /* Calculate the complete set of arguments used to specialize R. */ - if (use_spec_table) + if (use_spec_table && !lambda_fntype) { argvec = tsubst_template_args (DECL_TI_ARGS (DECL_TEMPLATE_RESULT @@ -14380,14 +14380,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, return error_mark_node; /* Check to see if we already have this specialization. */ - if (!lambda_fntype) - { - hash = spec_hasher::hash (gen_tmpl, argvec); - if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash)) - /* The spec for these args might be a partial instantiation of the - template, but here what we want is the FUNCTION_DECL. */ - return STRIP_TEMPLATE (spec); - } + hash = spec_hasher::hash (gen_tmpl, argvec); + if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash)) + /* The spec for these args might be a partial instantiation of the + template, but here what we want is the FUNCTION_DECL. */ + return STRIP_TEMPLATE (spec); } else argvec = args; @@ -14704,6 +14701,8 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, /* Type partial instantiations are stored as the type by lookup_template_class_1, not here as the template. */ spec = CLASSTYPE_TI_TEMPLATE (spec); + else if (TREE_CODE (spec) != TEMPLATE_DECL) + spec = DECL_TI_TEMPLATE (spec); return spec; } } @@ -14754,7 +14753,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, inner = tsubst_aggr_type (inner, args, complain, in_decl, /*entering*/1); else - inner = tsubst (inner, args, complain, in_decl); + inner = tsubst_decl (inner, args, complain, /*use_spec_table=*/false); } --processing_template_decl; if (inner == error_mark_node) @@ -14780,12 +14779,11 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, } else { - if (TREE_CODE (inner) == FUNCTION_DECL) - /* Set DECL_TI_ARGS to the full set of template arguments, which - tsubst_function_decl didn't do due to use_spec_table=false. */ - DECL_TI_ARGS (inner) = full_args; - DECL_TI_TEMPLATE (inner) = r; + /* Set DECL_TI_ARGS to the full set of template arguments, + which tsubst_function_decl / tsubst_decl didn't do due to + use_spec_table=false. */ + DECL_TI_ARGS (inner) = full_args; DECL_TI_ARGS (r) = DECL_TI_ARGS (inner); } @@ -14813,9 +14811,17 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; - if (TREE_CODE (decl) == FUNCTION_DECL && !lambda_fntype) - /* Record this non-type partial instantiation. */ - register_specialization (r, t, full_args, false, hash); + if (!lambda_fntype && !class_p) + { + /* Record this non-type partial instantiation. */ + /* FIXME we'd like to always register the TEMPLATE_DECL, or always + the DECL_TEMPLATE_RESULT, but it seems the modules code relies + on this current behavior. */ + if (TREE_CODE (inner) == FUNCTION_DECL) + register_specialization (r, t, full_args, false, hash); + else + register_specialization (inner, t, full_args, false, hash); + } return r; } |