This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch]c-decl.c: avoid linear search of all decls
- To: gcc-patches at gcc dot gnu dot org
- Subject: [Patch]c-decl.c: avoid linear search of all decls
- From: "Turly O'Connor" <turly at apple dot com>
- Date: Tue, 13 Mar 2001 18:28:23 -0800
- Cc: Stan Shebs <shebs at apple dot com>, Turly <turly at finderpop dot com>
Hey there,
This patch alters c-decl.c to maintain a _list_ of the incomplete
declarations requiring later "filling in", rather than just keeping
a count of incomplete decls and then searching ALL decls. This
can result in parse speed improvements for compilations with a
large number of decls. YMMV.
Bootstraps and doesn't alter testsuite results.
Have Fun!
--turly
2001-03-13 Turly O'Connor <turly@apple.com>
* c-decl.c (struct binding_level): Replace "int n_incomplete" with
"tree incomplete_list" to keep tabs on incomplete structs/unions.
(pushdecl): Populate the list if required.
(mark_binding_level): GC the list.
(finish_struct): Search incomplete_list rather than all decls.
Index: c-decl.c
===================================================================
RCS file: /cvs/repository/CoreTools/gcc3/gcc/c-decl.c,v
retrieving revision 1.1.1.6
diff -p -r1.1.1.6 c-decl.c
*** c-decl.c 2001/03/07 02:45:15 1.1.1.6
--- c-decl.c 2001/03/13 23:38:45
*************** struct binding_level
*** 210,218 ****
/* Nonzero means make a BLOCK if this level has any subblocks. */
char keep_if_subblocks;
! /* Number of decls in `names' that have incomplete
structure or union types. */
! int n_incomplete;
/* A list of decls giving the (reversed) specified order of parms,
not including any forward-decls in the parmlist.
--- 210,218 ----
/* Nonzero means make a BLOCK if this level has any subblocks. */
char keep_if_subblocks;
! /* List of decls in `names' that have incomplete
structure or union types. */
! tree incomplete_list;
/* A list of decls giving the (reversed) specified order of parms,
not including any forward-decls in the parmlist.
*************** static struct binding_level *global_bind
*** 239,245 ****
/* Binding level structures are initialized by copying this one. */
static struct binding_level clear_binding_level
! = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0,
0,
NULL};
/* Nonzero means unconditionally make a BLOCK for the next level
pushed. */
--- 239,245 ----
/* Binding level structures are initialized by copying this one. */
static struct binding_level clear_binding_level
! = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0,
NULL,
NULL};
/* Nonzero means unconditionally make a BLOCK for the next level
pushed. */
*************** pushdecl (x)
*** 2476,2488 ****
b->shadowed = tree_cons (name, oldlocal, b->shadowed);
}
! /* Keep count of variables in this level with incomplete type.
If the input is erroneous, we can have error_mark in the type
slot (e.g. "f(void a, ...)") - that doesn't count as an
incomplete type. */
if (TREE_TYPE (x) != error_mark_node
&& !COMPLETE_TYPE_P (TREE_TYPE (x)))
! ++b->n_incomplete;
}
/* Put decls on list in reverse order.
--- 2476,2488 ----
b->shadowed = tree_cons (name, oldlocal, b->shadowed);
}
! /* Keep list of variables in this level with incomplete type.
If the input is erroneous, we can have error_mark in the type
slot (e.g. "f(void a, ...)") - that doesn't count as an
incomplete type. */
if (TREE_TYPE (x) != error_mark_node
&& !COMPLETE_TYPE_P (TREE_TYPE (x)))
! b->incomplete_list = tree_cons (NULL_TREE, x, b->incomplete_list);
}
/* Put decls on list in reverse order.
*************** mark_binding_level (arg)
*** 2962,2967 ****
--- 2962,2968 ----
ggc_mark_tree (level->blocks);
ggc_mark_tree (level->this_block);
ggc_mark_tree (level->parm_order);
+ ggc_mark_tree (level->incomplete_list);
}
}
*************** finish_struct (t, fieldlist, attributes)
*** 5492,5512 ****
/* If this structure or union completes the type of any previous
variable declaration, lay it out and output its rtl. */
! if (current_binding_level->n_incomplete != 0)
{
! tree decl;
! for (decl = current_binding_level->names; decl; decl =
TREE_CHAIN (decl))
! {
if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
&& TREE_CODE (decl) != TYPE_DECL)
{
layout_decl (decl, 0);
! /* This is a no-op in c-lang.c or something real in
objc-actions.c. */
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0);
if (! toplevel)
expand_decl (decl);
! --current_binding_level->n_incomplete;
}
else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
--- 5493,5521 ----
/* If this structure or union completes the type of any previous
variable declaration, lay it out and output its rtl. */
! if (current_binding_level->incomplete_list != NULL_TREE)
{
! tree prev = NULL_TREE;
!
! for (x = current_binding_level->incomplete_list; x; x =
TREE_CHAIN (x))
! {
! tree decl = TREE_VALUE (x);
!
if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
&& TREE_CODE (decl) != TYPE_DECL)
{
layout_decl (decl, 0);
! /* This is a no-op in c-lang.c or real code in objc-act.c. */
maybe_objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0);
if (! toplevel)
expand_decl (decl);
!
! /* Unlink X from the incomplete list. */
! if (prev)
! TREE_CHAIN (prev) = TREE_CHAIN (x);
! else
! current_binding_level->incomplete_list = TREE_CHAIN (x);
}
else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)