This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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];