re PR c++/64359 (alias_template_specialization_p & template_args_equal show up high in profile)

PR c++/64359
	* pt.c (iterative_hash_template_arg): Hash alias specializations
	differently from their TYPE_CANONICAL.
	(alias_template_specialization_p): Optimize.
	(template_args_equal): Optimize alias handling.
	(dependent_alias_template_spec_p): Only check innermost args.

From-SVN: r218995
This commit is contained in:
Jason Merrill 2014-12-21 00:00:43 -05:00 committed by Jason Merrill
parent d01cc136c1
commit b9fa057537
2 changed files with 41 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2014-12-20 Jason Merrill <jason@redhat.com>
PR c++/64359
* pt.c (iterative_hash_template_arg): Hash alias specializations
differently from their TYPE_CANONICAL.
(alias_template_specialization_p): Optimize.
(template_args_equal): Optimize alias handling.
(dependent_alias_template_spec_p): Only check innermost args.
2014-12-19 Kai Tietz <ktietz@redhat.com>
PR c++/61198

View File

@ -1674,6 +1674,18 @@ iterative_hash_template_arg (tree arg, hashval_t val)
switch (tclass)
{
case tcc_type:
if (alias_template_specialization_p (arg))
{
// We want an alias specialization that survived strip_typedefs
// to hash differently from its TYPE_CANONICAL, to avoid hash
// collisions that compare as different in template_args_equal.
// These could be dependent specializations that strip_typedefs
// left alone, or untouched specializations because
// coerce_template_parms returns the unconverted template
// arguments if it sees incomplete argument packs.
tree ti = TYPE_TEMPLATE_INFO (arg);
return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
}
if (TYPE_CANONICAL (arg))
return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
val);
@ -5314,13 +5326,19 @@ alias_type_or_template_p (tree t)
bool
alias_template_specialization_p (const_tree t)
{
if (t == NULL_TREE)
return false;
return (TYPE_P (t)
&& TYPE_TEMPLATE_INFO (t)
&& PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t))
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
/* It's an alias template specialization if it's an alias and its
TYPE_NAME is a specialization of a primary template. */
if (TYPE_ALIAS_P (t))
{
tree name = TYPE_NAME (t);
if (DECL_LANG_SPECIFIC (name))
if (tree ti = DECL_TEMPLATE_INFO (name))
{
tree tmpl = TI_TEMPLATE (ti);
return PRIMARY_TEMPLATE_P (tmpl);
}
}
return false;
}
/* Return TRUE iff T is a specialization of an alias template with
@ -5330,7 +5348,8 @@ bool
dependent_alias_template_spec_p (const_tree t)
{
return (alias_template_specialization_p (t)
&& any_dependent_template_arguments_p (TYPE_TI_ARGS (t)));
&& (any_dependent_template_arguments_p
(INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t)))));
}
/* Return the number of innermost template parameters in TMPL. */
@ -7283,16 +7302,12 @@ template_args_equal (tree ot, tree nt)
return false;
/* Don't treat an alias template specialization with dependent
arguments as equivalent to its underlying type when used as a
template argument; we need them to hash differently. */
bool ndep = dependent_alias_template_spec_p (nt);
++processing_template_decl;
bool odep = dependent_alias_template_spec_p (ot);
--processing_template_decl;
if (ndep != odep)
template argument; we need them to be distinct so that we
substitute into the specialization arguments at instantiation
time. And aliases can't be equivalent without being ==, so
we don't need to look any deeper. */
if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot))
return false;
else if (ndep)
return (TYPE_TI_TEMPLATE (nt) == TYPE_TI_TEMPLATE (ot)
&& template_args_equal (TYPE_TI_ARGS (nt), TYPE_TI_ARGS (ot)));
else
return same_type_p (ot, nt);
}