The following makes the C++ FEs heavy use of build_qualified_type
cheaper.  When looking at a tramp3d -fsyntax-only compile you can
see that for 470.000 build_qualified_type calls we end up
with 9.492.205 calls to check_qualified_type (thus we visit around
20 variant type candidates) ending up finding it in all but
15.300 cases that end up in build_variant_type_copy.

That's of course because the FE uses this machinery to do things like

bool
same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
{
  if (type1 == error_mark_node || type2 == error_mark_node)
    return false;

  type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
  type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
  return same_type_p (type1, type2);

but so it be.  The improvement is to re-organize get_qualified_type
to put found type variants on the head of the variant list.  This
improves the number of calls to check_qualified_type to 1.215.030
thus around 2.5 candidates.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Comments?  OK?

Richard.

2019-04-16  Richard Biener  <rguent...@suse.de>

        * tree.c (get_qualified_type): Put found type variants at the
        head of the variant list.

Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (revision 270387)
+++ gcc/tree.c  (working copy)
@@ -6451,17 +6451,28 @@ check_aligned_type (const_tree cand, con
 tree
 get_qualified_type (tree type, int type_quals)
 {
-  tree t;
-
   if (TYPE_QUALS (type) == type_quals)
     return type;
 
+  tree mv = TYPE_MAIN_VARIANT (type);
+  if (check_qualified_type (mv, type, type_quals))
+    return mv;
+
   /* Search the chain of variants to see if there is already one there just
      like the one we need to have.  If so, use that existing one.  We must
      preserve the TYPE_NAME, since there is code that depends on this.  */
-  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-    if (check_qualified_type (t, type, type_quals))
-      return t;
+  for (tree *tp = &TYPE_NEXT_VARIANT (mv); *tp; tp = &TYPE_NEXT_VARIANT (*tp))
+    if (check_qualified_type (*tp, type, type_quals))
+      {
+       /* Put the found variant at the head of the variant list so
+          frequently searched variants get found faster.  The C++ FE
+          benefits greatly from this.  */
+       tree t = *tp;
+       *tp = TYPE_NEXT_VARIANT (t);
+       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv);
+       TYPE_NEXT_VARIANT (mv) = t;
+       return t;
+      }
 
   return NULL_TREE;
 }

Reply via email to