C++ PATCH: Speed up no_linkage_check

Mark Mitchell mark@codesourcery.com
Mon Jul 19 14:42:00 GMT 2004


The no_linkage_check function was the primary user of
walk_tree_without_duplicates in the Qt test cases I've been examining.
That function has a lot of overhead (creating/destroying hash tables,
for example) and there's no need for walk_tree's generality.  This
patch replaces no_linkage_check with simpler code and speeds up the
test case I was examining by 1 to 2%.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-07-18  Mark Mitchell  <mark@codesourcery.com>

	* tree.c (no_linkage_helper): Remove.
	(no_linkage_check): Don't use walk_tree_without_duplicates.

Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.393
diff -c -5 -p -r1.393 tree.c
*** tree.c	16 Jul 2004 20:51:31 -0000	1.393
--- tree.c	19 Jul 2004 04:01:17 -0000
*************** static tree bot_replace (tree *, int *, 
*** 40,50 ****
  static tree build_cplus_array_type_1 (tree, tree);
  static int list_hash_eq (const void *, const void *);
  static hashval_t list_hash_pieces (tree, tree, tree);
  static hashval_t list_hash (const void *);
  static cp_lvalue_kind lvalue_p_1 (tree, int);
- static tree no_linkage_helper (tree *, int *, void *);
  static tree mark_local_for_remap_r (tree *, int *, void *);
  static tree cp_unsave_r (tree *, int *, void *);
  static tree build_target_expr (tree, tree);
  static tree count_trees_r (tree *, int *, void *);
  static tree verify_stmt_tree_r (tree *, int *, void *);
--- 40,49 ----
*************** tree
*** 1066,1107 ****
  find_tree (tree t, tree x)
  {
    return walk_tree_without_duplicates (&t, find_tree_r, x);
  }
  
- /* Passed to walk_tree.  Checks for the use of types with no linkage.  */
- 
- static tree
- no_linkage_helper (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- 		   void *data ATTRIBUTE_UNUSED)
- {
-   tree t = *tp;
- 
-   if (TYPE_P (t)
-       && (CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE)
-       && (decl_function_context (TYPE_MAIN_DECL (t))
- 	  || TYPE_ANONYMOUS_P (t)))
-     return t;
- 
-   return NULL_TREE;
- }
- 
  /* Check if the type T depends on a type with no linkage and if so, return
     it.  */
  
  tree
  no_linkage_check (tree t)
  {
    /* There's no point in checking linkage on template functions; we
       can't know their complete types.  */
    if (processing_template_decl)
      return NULL_TREE;
  
!   t = walk_tree_without_duplicates (&t, no_linkage_helper, NULL);
!   if (t != error_mark_node)
!     return t;
!   return NULL_TREE;
  }
  
  #ifdef GATHER_STATISTICS
  extern int depth_reached;
  #endif
--- 1065,1137 ----
  find_tree (tree t, tree x)
  {
    return walk_tree_without_duplicates (&t, find_tree_r, x);
  }
  
  /* Check if the type T depends on a type with no linkage and if so, return
     it.  */
  
  tree
  no_linkage_check (tree t)
  {
+   tree r;
+ 
    /* There's no point in checking linkage on template functions; we
       can't know their complete types.  */
    if (processing_template_decl)
      return NULL_TREE;
  
!   switch (TREE_CODE (t))
!     {
!     case RECORD_TYPE:
!       if (TYPE_PTRMEMFUNC_P (t))
! 	goto ptrmem;
!       /* Fall through.  */
!     case UNION_TYPE:
!       if (!CLASS_TYPE_P (t))
! 	return NULL_TREE;
!       /* Fall through.  */
!     case ENUMERAL_TYPE:
!       if (decl_function_context (TYPE_MAIN_DECL (t))
! 	  || TYPE_ANONYMOUS_P (t))
! 	return t;
!       return NULL_TREE;
! 
!     case ARRAY_TYPE:
!     case POINTER_TYPE:
!     case REFERENCE_TYPE:
!       return no_linkage_check (TREE_TYPE (t));
! 
!     case OFFSET_TYPE:
!     ptrmem:
!       r = no_linkage_check (TYPE_PTRMEM_POINTED_TO_TYPE (t));
!       if (r)
! 	return r;
!       return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t));
! 
!     case METHOD_TYPE:
!       r = no_linkage_check (TYPE_METHOD_BASETYPE (t));
!       if (r)
! 	return r;
!       /* Fall through.  */
!     case FUNCTION_TYPE:
!       {
! 	tree parm;
! 	for (parm = TYPE_ARG_TYPES (t); 
! 	     parm && parm != void_list_node; 
! 	     parm = TREE_CHAIN (parm))
! 	  {
! 	    r = no_linkage_check (TREE_VALUE (parm));
! 	    if (r)
! 	      return r;
! 	  }
! 	return no_linkage_check (TREE_TYPE (t));
!       }
! 
!     default:
!       return NULL_TREE;
!     }
  }
  
  #ifdef GATHER_STATISTICS
  extern int depth_reached;
  #endif



More information about the Gcc-patches mailing list