This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Speed up no_linkage_check
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 18 Jul 2004 21:05:27 -0700
- Subject: C++ PATCH: Speed up no_linkage_check
- Reply-to: mark at codesourcery dot com
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