This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa] Allow next field to point to the same field
> > >
> > >
> > > On Fri, 28 Nov 2003, Jan Hubicka wrote:
> > >
> > > > Hi,
> > > > the chain filed is special because GGC is aware of fact that the chain
> > > > is used as linked list:
> > > > union lang_tree_node
> > > > GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
> > > > chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *)TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
> > > >
> > > > The use of the field in SSA_NAME_DEF_STMT breaks this expectation and
> > > > confuses GGC when multiple SSA_NAMES point to same DEF_STMT.
> > > >
> > > > The attached patch fixes it by avoiding the overload of chain and ading
> > > > separate field for this, but I am open for further suggestions.
> > > >
> > > > Bootstrapped/regtested i686-pc-gnu-linux in isolation
> > > > and additionally x86_64-linux in combination with two patches sent
> > > > earlier.
> > > > Honza
> > >
> > > Just to make sure nothing bad happens, have you tried all these patches
> > > together with GCAC checking on?
> > Yes. Together with patch that calls ggc_collect in between each of
> > tree-ssa passes.
> >
> > Concerning this particular patch, while looking into the code I am
> > getting to believe that I've just worked around bug I fixed later. Once
> > I am done with the other patches, I will give ggc_collect a try and
> > return to it if still fails.
> > For double linked lists the situation is somewhat different...
> OK, got it :)
>
> the problem is when linked chain ends up by node linking to itself. In current
> scheme, the xlimit does not point to first element we don't point to first
> already visited element, but to the last element we should visit. The attached
> patch changes loop to:
> void
> gt_ggc_mx_lang_tree_node (void *x_p)
> {
> union lang_tree_node * x = (union lang_tree_node *)x_p;
> union lang_tree_node * xlast = x, * xlimit = x;
> if (!ggc_test_and_set_mark (x))
> return;
> while (ggc_test_and_set_mark (xlimit))
> {
> xlast = xlimit;
> xlimit = (C_LANG_TREE_NODE_CHAIN_NEXT (&(*xlimit).generic));
> }
And this effectivly disables the next pointer feature (xlimit is always
marked). I meant to replace this with do-while loop as done by the
attached patch. It has passed testing on i686-pc-gnu-linux. Testing
with gcac,gc is in progress but it appears to be all fine.
Loop look like this now:
void
gt_ggc_mx_lang_tree_node (void *x_p)
{
union lang_tree_node * x = (union lang_tree_node *)x_p;
union lang_tree_node * xlast = x, * xlimit = x;
if (!ggc_test_and_set_mark (x))
return;
do
{
xlast = xlimit;
xlimit = (C_LANG_TREE_NODE_CHAIN_NEXT (&(*xlimit).generic));
}
while (ggc_test_and_set_mark (xlimit));
while (1)
{
switch (TREE_CODE (&((*x)).generic) == IDENTIFIER_NODE)
{
.....
}
if (x == xlast)
break;
x = (C_LANG_TREE_NODE_CHAIN_NEXT (&(*x).generic));
}
}
Regtested/bootstrapped i686-pc-gnu-linux, bootstrapped C only with --enable-checking=gc,gcac
OK?
2003-11-29 Jan Hubicka <jh@suse.cz>
* gengtype.c (write_func_for_structure): Allow linked chains to end up
by reference to itself.
Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.7.4.24
diff -c -3 -p -r1.7.4.24 gengtype.c
*** gengtype.c 25 Nov 2003 02:09:47 -0000 1.7.4.24
--- gengtype.c 30 Nov 2003 00:23:54 -0000
*************** write_func_for_structure (type_p orig_s
*** 1968,1974 ****
chain_next == NULL ? "const " : "",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next != NULL)
! oprintf (d.of, " %s %s * xlimit = x;\n",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next == NULL)
{
--- 1968,1974 ----
chain_next == NULL ? "const " : "",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next != NULL)
! oprintf (d.of, " %s %s * xlast = x, * xlimit = x;\n",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next == NULL)
{
*************** write_func_for_structure (type_p orig_s
*** 1982,2012 ****
}
else
{
! oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
if (wtd->param_prefix)
{
! oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
output_mangled_typename (d.of, orig_s);
}
oprintf (d.of, "))\n");
! oprintf (d.of, " xlimit = (");
d.prev_val[2] = "*xlimit";
output_escaped_param (&d, chain_next, "chain_next");
oprintf (d.of, ");\n");
if (chain_prev != NULL)
{
! oprintf (d.of, " if (x != xlimit)\n");
! oprintf (d.of, " for (;;)\n");
! oprintf (d.of, " {\n");
! oprintf (d.of, " %s %s * const xprev = (",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
d.prev_val[2] = "*x";
output_escaped_param (&d, chain_prev, "chain_prev");
oprintf (d.of, ");\n");
! oprintf (d.of, " if (xprev == NULL) break;\n");
! oprintf (d.of, " x = xprev;\n");
! oprintf (d.of, " (void) %s (xprev",
wtd->marker_routine);
if (wtd->param_prefix)
{
--- 1982,2023 ----
}
else
{
! oprintf (d.of, " if (!%s (x", wtd->marker_routine);
if (wtd->param_prefix)
{
! oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
output_mangled_typename (d.of, orig_s);
}
oprintf (d.of, "))\n");
! oprintf (d.of, " return;\n");
! oprintf (d.of, " do\n");
! oprintf (d.of, " {\n");
! oprintf (d.of, " xlast = xlimit;\n");
! oprintf (d.of, " xlimit = (");
d.prev_val[2] = "*xlimit";
output_escaped_param (&d, chain_next, "chain_next");
oprintf (d.of, ");\n");
+ oprintf (d.of, " }\n");
+ oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
+ if (wtd->param_prefix)
+ {
+ oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
+ output_mangled_typename (d.of, orig_s);
+ }
+ oprintf (d.of, "));\n");
if (chain_prev != NULL)
{
! oprintf (d.of, " for (;;)\n");
! oprintf (d.of, " {\n");
! oprintf (d.of, " %s %s * const xprev = (",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
d.prev_val[2] = "*x";
output_escaped_param (&d, chain_prev, "chain_prev");
oprintf (d.of, ");\n");
! oprintf (d.of, " if (xprev == NULL) break;\n");
! oprintf (d.of, " x = xprev;\n");
! oprintf (d.of, " (void) %s (xprev",
wtd->marker_routine);
if (wtd->param_prefix)
{
*************** write_func_for_structure (type_p orig_s
*** 2014,2022 ****
output_mangled_typename (d.of, orig_s);
}
oprintf (d.of, ");\n");
! oprintf (d.of, " }\n");
}
! oprintf (d.of, " while (x != xlimit)\n");
}
oprintf (d.of, " {\n");
--- 2025,2033 ----
output_mangled_typename (d.of, orig_s);
}
oprintf (d.of, ");\n");
! oprintf (d.of, " }\n");
}
! oprintf (d.of, " while (1)\n");
}
oprintf (d.of, " {\n");
*************** write_func_for_structure (type_p orig_s
*** 2026,2031 ****
--- 2037,2044 ----
if (chain_next != NULL)
{
+ oprintf (d.of, " if (x == xlast)\n");
+ oprintf (d.of, " break;\n");
oprintf (d.of, " x = (");
output_escaped_param (&d, chain_next, "chain_next");
oprintf (d.of, ");\n");