This is the mail archive of the gcc@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]

Re: [tree-ssa] Garbage collector x bb annotations


Hello,

> >>>I have just run into the following problem: dom_children get 
> >>>released by
> >>>ggc_collect call in tree-ssa-pre.  Allocating them by ggc seems 
> >>>wrong to
> >>>me, since basic block annotations are allocated from obstack and
> >>>invisible to garbage collector.
> >>>
> >>Yeah.  But there's more than that, unfortunately.  All the fields in
> >>struct bb_ann_d are ggc allocated.  The real solution would be to
> >>finally convert basic blocks to ggc.  Volunteers?
> >
> >I may try (I need it anyway for tree-ssa-cfg branch).  The whole issue
> >is however quite ugly as this combines basically all allocation
> >mechanisms that are available in gcc (basic blocks themselves are pool
> >allocated).
> 
> They used to be obstack allocated, so consider yourself lucky :P.
> 
> You could add a "fields_only" flag and modify gengtype to not mark the 
> actual bb, only it's fields.

I am commiting patch implementing this into tree-ssa-cfg, since it is
a bit cleaner than what I did previously.

Zdenek

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.153.2.28.2.3
diff -c -3 -p -r1.153.2.28.2.3 basic-block.h
*** basic-block.h	6 Oct 2003 23:33:55 -0000	1.153.2.28.2.3
--- basic-block.h	9 Oct 2003 14:13:38 -0000
*************** struct bb_ann_d;
*** 200,246 ****
     basic blocks.  */
  
  /* Basic block information indexed by block number.  */
! typedef struct basic_block_def {
    /* The first and last insns of the block.  */
!   rtx head, end;
  
    /* The first and last trees of the block.  */
!   struct tree_container *head_tree, *end_tree;
  
    /* The edges into and out of the block.  */
!   edge pred, succ;
  
    /* Liveness info.  */
  
    /* The registers that are modified within this in block.  */
!   regset local_set;
    /* The registers that are conditionally modified within this block.
       In other words, registers that are set only as part of a
       COND_EXEC.  */
!   regset cond_local_set;
    /* The registers that are live on entry to this block.
  
       Note that in SSA form, global_live_at_start does not reflect the
       use of regs in phi functions, since the liveness of these regs
       may depend on which edge was taken into the block.  */
!   regset global_live_at_start;
    /* The registers that are live on exit from this block.  */
!   regset global_live_at_end;
  
    /* Auxiliary info specific to a pass.  */
!   void *aux;
  
    /* The index of this block.  */
    int index;
  
!   /* Previous and next blocks in the chain.  */
!   struct basic_block_def *prev_bb, *next_bb;
  
    /* The loop depth of this block.  */
    int loop_depth;
  
    /* Innermost loop containing the block.  */
!   struct loop *loop_father;
  
    /* Expected number of executions: calculated in profile.c.  */
    gcov_type count;
--- 200,253 ----
     basic blocks.  */
  
  /* Basic block information indexed by block number.  */
! struct basic_block_def GTY((fields_only ("")))
! {
    /* The first and last insns of the block.  */
!   rtx head;
!   rtx end;
  
    /* The first and last trees of the block.  */
!   struct tree_container *head_tree;
!   struct tree_container *end_tree;
  
    /* The edges into and out of the block.  */
!   struct edge_def * GTY((skip (""))) pred;
!   struct edge_def * GTY((skip (""))) succ;
  
    /* Liveness info.  */
  
    /* The registers that are modified within this in block.  */
!   bitmap GTY((skip (""))) local_set;
    /* The registers that are conditionally modified within this block.
       In other words, registers that are set only as part of a
       COND_EXEC.  */
!   bitmap GTY((skip (""))) cond_local_set;
    /* The registers that are live on entry to this block.
  
       Note that in SSA form, global_live_at_start does not reflect the
       use of regs in phi functions, since the liveness of these regs
       may depend on which edge was taken into the block.  */
!   bitmap GTY((skip (""))) global_live_at_start;
    /* The registers that are live on exit from this block.  */
!   bitmap GTY((skip (""))) global_live_at_end;
  
    /* Auxiliary info specific to a pass.  */
!   PTR GTY((skip (""))) aux;
  
    /* The index of this block.  */
    int index;
  
!   /* Previous and next blocks in the chain.  The GTY((skip (""))) is necessary,
!      since the basic blocks themselves are not marked and we would cause a quadratic
!      behavior otherwise.  */
!   struct basic_block_def * GTY((skip (""))) prev_bb;
!   struct basic_block_def * GTY((skip (""))) next_bb;
  
    /* The loop depth of this block.  */
    int loop_depth;
  
    /* Innermost loop containing the block.  */
!   struct loop * GTY((skip (""))) loop_father;
  
    /* Expected number of executions: calculated in profile.c.  */
    gcov_type count;
*************** typedef struct basic_block_def {
*** 252,262 ****
    int flags;
  
    /* Additional data maintained by cfg_layout routines.  */
!   struct reorder_block_def *rbi;
  
    /* Annotations used at the tree level.  */
    struct bb_ann_d *tree_annotations;
! } *basic_block;
  
  #define BB_FREQ_MAX 10000
  
--- 259,271 ----
    int flags;
  
    /* Additional data maintained by cfg_layout routines.  */
!   struct reorder_block_def * GTY((skip (""))) rbi;
  
    /* Annotations used at the tree level.  */
    struct bb_ann_d *tree_annotations;
! };
! 
! typedef struct basic_block_def *basic_block;
  
  #define BB_FREQ_MAX 10000
  
*************** extern int n_edges;
*** 282,288 ****
  
  /* Index by basic block number, get basic block struct info.  */
  
! extern varray_type basic_block_info;
  
  #define BASIC_BLOCK(N)  (VARRAY_BB (basic_block_info, (N)))
  
--- 291,297 ----
  
  /* Index by basic block number, get basic block struct info.  */
  
! extern GTY(()) varray_type basic_block_info;
  
  #define BASIC_BLOCK(N)  (VARRAY_BB (basic_block_info, (N)))
  
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfg.c,v
retrieving revision 1.34.2.11.2.4
diff -c -3 -p -r1.34.2.11.2.4 cfg.c
*** cfg.c	6 Oct 2003 23:33:55 -0000	1.34.2.11.2.4
--- cfg.c	9 Oct 2003 14:13:38 -0000
*************** compact_blocks (void)
*** 270,275 ****
--- 270,278 ----
    if (i != n_basic_blocks)
      abort ();
  
+   for (; i < last_basic_block; i++)
+     BASIC_BLOCK (i) = NULL;
+ 
    last_basic_block = n_basic_blocks;
  }
  
Index: cfgbuild.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgbuild.c,v
retrieving revision 1.25.2.10.2.1
diff -c -3 -p -r1.25.2.10.2.1 cfgbuild.c
*** cfgbuild.c	2 Oct 2003 22:02:04 -0000	1.25.2.10.2.1
--- cfgbuild.c	9 Oct 2003 14:13:38 -0000
*************** find_basic_blocks (rtx f, int nregs ATTR
*** 604,610 ****
        FOR_EACH_BB (bb)
  	bb->aux = NULL;
  
!       VARRAY_FREE (basic_block_info);
      }
  
    n_basic_blocks = count_basic_blocks (f);
--- 604,610 ----
        FOR_EACH_BB (bb)
  	bb->aux = NULL;
  
!       basic_block_info = NULL;
      }
  
    n_basic_blocks = count_basic_blocks (f);
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.534.2.15.2.1
diff -c -3 -p -r1.534.2.15.2.1 flow.c
*** flow.c	2 Oct 2003 22:02:16 -0000	1.534.2.15.2.1
--- flow.c	9 Oct 2003 14:13:38 -0000
*************** free_basic_block_vars (int keep_head_end
*** 797,803 ****
        if (basic_block_info)
  	{
  	  clear_edges ();
! 	  VARRAY_FREE (basic_block_info);
  	}
        n_basic_blocks = 0;
        last_basic_block = 0;
--- 797,803 ----
        if (basic_block_info)
  	{
  	  clear_edges ();
! 	  basic_block_info = NULL;
  	}
        n_basic_blocks = 0;
        last_basic_block = 0;
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.83.2.11.2.4
diff -c -3 -p -r1.83.2.11.2.4 function.h
*** function.h	6 Oct 2003 23:33:55 -0000	1.83.2.11.2.4
--- function.h	9 Oct 2003 14:13:39 -0000
*************** struct function GTY(())
*** 416,425 ****
    /* Array mapping insn uids to blocks.  */
    struct varray_head_tag *ib_boundaries_block;
  
-   /* Tree container cell list (so that garbage collector keeps them alive);
-      not really a great solution.  */
-   struct tree_container *tree_containers_root;
- 
    /* Collected bit flags.  */
  
    /* Nonzero if function being compiled needs to be given an address
--- 416,421 ----
Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.7.4.21.2.1
diff -c -3 -p -r1.7.4.21.2.1 gengtype.c
*** gengtype.c	2 Oct 2003 22:02:20 -0000	1.7.4.21.2.1
--- gengtype.c	9 Oct 2003 14:13:39 -0000
*************** struct write_types_data
*** 1345,1350 ****
--- 1345,1351 ----
    const char *param_prefix;
    const char *subfield_marker_routine;
    const char *marker_routine;
+   const char *test_routine;
    const char *reorder_note_routine;
    const char *comment;
  };
*************** walk_type (type_p t, struct walk_type_da
*** 1512,1517 ****
--- 1513,1520 ----
        use_params_p = 1;
      else if (strcmp (oo->name, "desc") == 0)
        desc = (const char *)oo->info;
+     else if (strcmp (oo->name, "fields_only") == 0)
+       ;
      else if (strcmp (oo->name, "dot") == 0)
        ;
      else if (strcmp (oo->name, "tag") == 0)
*************** write_func_for_structure  (type_p orig_s
*** 1916,1926 ****
--- 1919,1931 ----
  			   const struct write_types_data *wtd)
  {
    const char *fn = s->u.s.line.file;
+   const char *marker;
    int i;
    const char *chain_next = NULL;
    const char *chain_prev = NULL;
    options_p opt;
    struct walk_type_data d;
+   int fields_only = false;
  
    /* This is a hack, and not the good kind either.  */
    for (i = NUM_PARAM - 1; i >= 0; i--)
*************** write_func_for_structure  (type_p orig_s
*** 1932,1941 ****
    d.of = get_output_file_with_visibility (fn);
  
    for (opt = s->u.s.opt; opt; opt = opt->next)
!     if (strcmp (opt->name, "chain_next") == 0)
!       chain_next = (const char *) opt->info;
!     else if (strcmp (opt->name, "chain_prev") == 0)
!       chain_prev = (const char *) opt->info;
  
    if (chain_prev != NULL && chain_next == NULL)
      error_at_line (&s->u.s.line, "chain_prev without chain_next");
--- 1937,1950 ----
    d.of = get_output_file_with_visibility (fn);
  
    for (opt = s->u.s.opt; opt; opt = opt->next)
!     {
!       if (strcmp (opt->name, "chain_next") == 0)
! 	chain_next = (const char *) opt->info;
!       else if (strcmp (opt->name, "chain_prev") == 0)
! 	chain_prev = (const char *) opt->info;
!       else if (strcmp (opt->name, "fields_only") == 0)
! 	fields_only = true;
!     }
  
    if (chain_prev != NULL && chain_next == NULL)
      error_at_line (&s->u.s.line, "chain_prev without chain_next");
*************** write_func_for_structure  (type_p orig_s
*** 1970,1978 ****
    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)
      {
!       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
        if (wtd->param_prefix)
  	{
  	  oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
--- 1979,1992 ----
    if (chain_next != NULL)
      oprintf (d.of, "  %s %s * xlimit = x;\n",
  	     s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+   if (fields_only)
+     marker = wtd->test_routine;
+   else
+     marker = wtd->marker_routine;
+ 
    if (chain_next == NULL)
      {
!       oprintf (d.of, "  if (%s (x", marker);
        if (wtd->param_prefix)
  	{
  	  oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
*************** write_func_for_structure  (type_p orig_s
*** 1982,1988 ****
      }
    else
      {
!       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
        if (wtd->param_prefix)
  	{
  	  oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
--- 1996,2002 ----
      }
    else
      {
!       oprintf (d.of, "  while (%s (xlimit", marker);
        if (wtd->param_prefix)
  	{
  	  oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
*************** write_func_for_structure  (type_p orig_s
*** 2006,2013 ****
  	  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)
  	    {
  	      oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
--- 2020,2026 ----
  	  oprintf (d.of, ");\n");
  	  oprintf (d.of, "        if (xprev == NULL) break;\n");
  	  oprintf (d.of, "        x = xprev;\n");
! 	  oprintf (d.of, "        (void) %s (xprev", marker);
  	  if (wtd->param_prefix)
  	    {
  	      oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
*************** write_types (type_p structures, type_p p
*** 2134,2147 ****
  
  static const struct write_types_data ggc_wtd =
  {
!   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
    "GC marker procedures.  "
  };
  
  static const struct write_types_data pch_wtd =
  {
    "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
!   "gt_pch_note_reorder",
    "PCH type-walking procedures.  "
  };
  
--- 2147,2160 ----
  
  static const struct write_types_data ggc_wtd =
  {
!   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", "ggc_test", NULL,
    "GC marker procedures.  "
  };
  
  static const struct write_types_data pch_wtd =
  {
    "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
!   "gt_pch_test", "gt_pch_note_reorder",
    "PCH type-walking procedures.  "
  };
  
*************** main(int argc ATTRIBUTE_UNUSED, char **a
*** 2915,2920 ****
--- 2928,2934 ----
    do_scalar_typedef ("uint8", &pos);
    do_scalar_typedef ("jword", &pos);
    do_scalar_typedef ("JCF_u2", &pos);
+   do_scalar_typedef ("gcov_type", &pos);
  
    do_typedef ("PTR", create_pointer (create_scalar_type ("void",
  							 strlen ("void"))),
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.44.2.8
diff -c -3 -p -r1.44.2.8 ggc.h
*** ggc.h	23 Jul 2003 16:59:48 -0000	1.44.2.8
--- ggc.h	9 Oct 2003 14:13:39 -0000
*************** extern const struct ggc_cache_tab * cons
*** 97,102 ****
--- 97,108 ----
  #define ggc_test_and_set_mark(EXPR) \
    ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
  
+ #define ggc_test(EXPR) \
+   ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1)
+ 
+ #define gt_pch_test(EXPR, C, F) \
+   ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1)
+ 
  #define ggc_mark(EXPR)				\
    do {						\
      const void *const a__ = (EXPR);		\
Index: tree-flatten.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flatten.c,v
retrieving revision 1.1.2.6
diff -c -3 -p -r1.1.2.6 tree-flatten.c
*** tree-flatten.c	6 Oct 2003 23:33:55 -0000	1.1.2.6
--- tree-flatten.c	9 Oct 2003 14:13:39 -0000
*************** tree_cell_alloc (tree t)
*** 57,64 ****
  
    nw->stmt = t;
    nw->prev = nw->next = NULL;
-   nw->next_in_gc_chain = cfun->tree_containers_root;
-   cfun->tree_containers_root = nw;
  
    return nw;
  }
--- 57,62 ----
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.47.2.3
diff -c -3 -p -r1.1.2.47.2.3 tree-flow-inline.h
*** tree-flow-inline.h	6 Oct 2003 23:33:55 -0000	1.1.2.47.2.3
--- tree-flow-inline.h	9 Oct 2003 14:13:39 -0000
*************** add_dom_child (basic_block bb, basic_blo
*** 317,323 ****
  {
    bb_ann_t ann = bb_ann (bb);
    if (ann->dom_children == NULL)
!     ann->dom_children = BITMAP_XMALLOC ();
    bitmap_set_bit (ann->dom_children, child_bb->index);
  }
  
--- 317,323 ----
  {
    bb_ann_t ann = bb_ann (bb);
    if (ann->dom_children == NULL)
!     ann->dom_children = BITMAP_GGC_ALLOC ();
    bitmap_set_bit (ann->dom_children, child_bb->index);
  }
  
*************** remove_dom_child (basic_block bb, basic_
*** 337,347 ****
  static inline void
  clear_dom_children (basic_block bb)
  {
!   if (bb_ann (bb)->dom_children)
!     {
!       BITMAP_XFREE (bb_ann (bb)->dom_children);
!       bb_ann (bb)->dom_children = NULL;
!     }
  }
  
  static inline bitmap
--- 337,343 ----
  static inline void
  clear_dom_children (basic_block bb)
  {
!   bb_ann (bb)->dom_children = NULL;
  }
  
  static inline bitmap
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.101.2.5
diff -c -3 -p -r1.1.4.101.2.5 tree-flow.h
*** tree-flow.h	6 Oct 2003 23:33:55 -0000	1.1.4.101.2.5
--- tree-flow.h	9 Oct 2003 14:13:39 -0000
*************** struct tree_container GTY (())
*** 40,46 ****
  {
    struct tree_container *prev;
    struct tree_container *next;
-   struct tree_container *next_in_gc_chain;
    tree stmt;
  };
  
--- 40,45 ----
*************** static inline tree default_def (tree);
*** 296,302 ****
  /*---------------------------------------------------------------------------
  		  Block annotations stored in basic_block.tree_annotations
  ---------------------------------------------------------------------------*/
! struct bb_ann_d
  {
    /* Chain of PHI nodes created in this block.  */
    tree phi_nodes;
--- 295,301 ----
  /*---------------------------------------------------------------------------
  		  Block annotations stored in basic_block.tree_annotations
  ---------------------------------------------------------------------------*/
! struct bb_ann_d GTY((fields_only ("")))
  {
    /* Chain of PHI nodes created in this block.  */
    tree phi_nodes;
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.21.2.4
diff -c -3 -p -r1.1.2.21.2.4 tree-ssa-dom.c
*** tree-ssa-dom.c	6 Oct 2003 23:33:56 -0000	1.1.2.21.2.4
--- tree-ssa-dom.c	9 Oct 2003 14:13:39 -0000
*************** tree_ssa_dominator_optimize (tree fndecl
*** 276,282 ****
    htab_delete (avail_exprs);
  
    VARRAY_FREE (edges_to_redirect);
-   VARRAY_FREE (redirection_targets);
  
    timevar_pop (TV_TREE_SSA_DOMINATOR_OPTS);
  }
--- 276,281 ----
Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.15.2.5.2.1
diff -c -3 -p -r1.15.2.5.2.1 varray.c
*** varray.c	2 Oct 2003 22:02:33 -0000	1.15.2.5.2.1
--- varray.c	9 Oct 2003 14:13:39 -0000
*************** static const struct {
*** 55,61 ****
    { sizeof (struct bitmap_head_def *), 1 },
    { sizeof (struct reg_info_def *), 0 },
    { sizeof (struct const_equiv_data), 0 },
!   { sizeof (struct basic_block_def *), 0 },
    { sizeof (struct elt_list *), 1 },
    { sizeof (struct edge_def *), 0 },
    { sizeof (tree *), 1 },
--- 55,61 ----
    { sizeof (struct bitmap_head_def *), 1 },
    { sizeof (struct reg_info_def *), 0 },
    { sizeof (struct const_equiv_data), 0 },
!   { sizeof (struct basic_block_def *), 1 },
    { sizeof (struct elt_list *), 1 },
    { sizeof (struct edge_def *), 0 },
    { sizeof (tree *), 1 },
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.28.2.4.2.1
diff -c -3 -p -r1.28.2.4.2.1 varray.h
*** varray.h	2 Oct 2003 22:02:33 -0000	1.28.2.4.2.1
--- varray.h	9 Oct 2003 14:13:39 -0000
*************** typedef union varray_data_tag GTY (()) {
*** 124,130 ****
  				tag ("VARRAY_DATA_REG")))	reg[1];
    struct const_equiv_data GTY ((length ("%0.num_elements"),
  			tag ("VARRAY_DATA_CONST_EQUIV")))	const_equiv[1];
!   struct basic_block_def *GTY ((length ("%0.num_elements"), skip (""),
  				tag ("VARRAY_DATA_BB")))	bb[1];
    struct elt_list	 *GTY ((length ("%0.num_elements"),
  				tag ("VARRAY_DATA_TE")))	te[1];
--- 124,130 ----
  				tag ("VARRAY_DATA_REG")))	reg[1];
    struct const_equiv_data GTY ((length ("%0.num_elements"),
  			tag ("VARRAY_DATA_CONST_EQUIV")))	const_equiv[1];
!   struct basic_block_def *GTY ((length ("%0.num_elements"),
  				tag ("VARRAY_DATA_BB")))	bb[1];
    struct elt_list	 *GTY ((length ("%0.num_elements"),
  				tag ("VARRAY_DATA_TE")))	te[1];


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