This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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));
   }
  while (1)
    {
      switch (TREE_CODE (&((*x)).generic) == IDENTIFIER_NODE)
        {
.....
        }
      if (x == xlast)
        break;
      x = (C_LANG_TREE_NODE_CHAIN_NEXT (&(*x).generic));
    }
}
So we visit last element always.

Regtested/bootstrapped i686-pc-gnu-linux, additionally 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	29 Nov 2003 12:36:27 -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,1987 ****
--- 1982,1995 ----
      }
    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, "  while (%s (xlimit", wtd->marker_routine);
        if (wtd->param_prefix)
  	{
*************** write_func_for_structure  (type_p orig_s
*** 1989,2012 ****
  	  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)
  	    {
--- 1997,2022 ----
  	  output_mangled_typename (d.of, orig_s);
  	}
        oprintf (d.of, "))\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");
        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");
  
--- 2024,2032 ----
  	      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 ****
--- 2036,2043 ----
  
    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");


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]