This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] garbage collectable CFG
- From: Steven Bosscher <s dot bosscher at student dot tudelft dot nl>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jh at suse dot de
- Date: Mon, 8 Dec 2003 01:28:02 +0100
- Subject: [tree-ssa] garbage collectable CFG
Hi,
So here's a new "CFG in GGC" patch. Honza already posed one some time ago,
but I've had a patch for more than a month that went beyond his work (yeah, I
work about 20 times slower than Honza ;-). I originally planned to go for one
big rework, but that patch grew far larger than I intended, so I'm taking the
incremental path now.
This patch is almost the same as what Honza had. I added the pieces from my
own patch where I thought Honza's patch was just lacking. So credit for this
goes to Honza too. Pieces I've added:
- make the dom_children butmap GC-able
- make edge_def GC safe between commits on edges
(unlikely we ever need this, but who knows...)
- kill tree_bb_root and tree_phi_root
- make varrays for edges and basic blocks GC-able.
I also ran into a weird problem with regs.h being included twice when I was
playing with a different version this patch (included cfg_hooks.h at the top
of basic-block.h, which turned out to be unnecessary). So I added
safeguards there.
I've decided not to make _all_ bitmaps hanging from basic_block_def garbage
collectable because:
1. I have no clue where and for what they're used. I may have to
learn, but for now I'm happy with just making tree-ssa GC safe.
2. Honza indicated he wants to move stuff to an RTL bb annotation.
I can only applaud such work, and I hope he can find the time
soon. In the mean time, we know that what we have now is safe
and it doesn't make sense to me to rework all of this twice.
3. Like I said, "incremental"... ;-)
This was bootstrapped (c,c++,objc,f95) and tested on on i686-pc-linux-gnu.
I have not tested this with GC access checking since we know that previously
we didn't have mem leaks and therefore this change should
be safe.
OK for the branch?
Gr.
Steven
2003-12-07 Steven Bosscher <stevenb@suse.de>
Jan Hubicka <jh@suse.de>
* gengtype-lex.l (IWOrD): Add HOST_WIDEST_INT
* Makefile.in (function.o, reg-stack.o): Add missing dependency on
basic-block.h.
(GTFILES): Add basic-block.h and hwint.h.
* basic-block.h (struct edge_def): Add GTY markers, make garbage
collectable. Make `insns' field GC safe depending on the setting
of cfg_hooks.
(struct basic_block_def): Add GTY markers, make garbage collectable.
(tree_bb_root, tree_phi_root): Kill extern decls.
(ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Change from macro to variable
(entry_exit_blocks): Kill.
* cfg.c: Include ggc.h
(bb_pool, edge_pool, entry_exit_blocks): Kill.
(ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Define.
(init_flow): Do not create ppols; allocate entry/exit block.
(free_edge, alloc_block, expunge_block, unchecked_make_edge): Use GGC.
(compact_blocks): Don't update tree_bb_root and tree_phi_root.
* cfgrtl.c (rtl_merge_blocks): Clear head pointer.
* regs.h: Protect against multiple inclusion.
* tree-cfg.c (obstack_tree_ann_obstack, first_block_tree_and_obj,
tree_bb_root): Kill.
(build_tree_cfg, create_bb, remove_bb, delete_tree_cfg): Don't
touch tree_bb_root and tree_phi_root.
(create_block_annotations): Do not initialize obstack.
(free_block_annotations): Do not free obstack.
(create_block_annotation): Use GGC.
* tree-dfa.c (tree_phi_root): Kill.
* tree-flow.h (bb_ann, bb_ann_d): Declare. Add `phi_nodes' field.
* tree-phinodes.c (create_phi_node, add_phi_arg, remove_phi_node,
remove_all_phi_nodes_for): Use `phi_nodes' field in the bb
annotation instead of tree_phi_root.
* tree-flow-inline.h (phi_nodes, set_phi_nodes): Likewise.
(add_dom_child, clear_dom_children): Use GGC.
* tree-ssa-pre.c (code_motion): Use `phi_nodes' field in the bb
annotation instead of tree_phi_root.
* varray.h (union varray_data): Make basic_block_def and edge_def
varrays garbage collectable.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.151
diff -c -3 -p -r1.903.2.151 Makefile.in
*** Makefile.in 6 Dec 2003 12:31:26 -0000 1.903.2.151
--- Makefile.in 7 Dec 2003 23:00:55 -0000
*************** varasm.o : varasm.c $(CONFIG_H) $(SYSTEM
*** 1682,1688 ****
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
! $(TM_P_H) langhooks.h gt-function.h $(TARGET_H)
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
--- 1682,1688 ----
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
! $(TM_P_H) langhooks.h gt-function.h $(TARGET_H) basic-block.h
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
*************** recog.o : recog.c $(CONFIG_H) $(SYSTEM_H
*** 1942,1948 ****
$(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(RECOG_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
! varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
--- 1942,1948 ----
$(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(RECOG_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
! varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h basic-block.h
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2193,2201 ****
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
$(srcdir)/bitmap.h $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
! $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \
! $(srcdir)/c-common.h $(srcdir)/c-tree.h \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
$(srcdir)/dependence.c \
$(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
--- 2193,2201 ----
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
$(srcdir)/bitmap.h $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
! $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \
! $(srcdir)/c-common.h $(srcdir)/c-tree.h $(srcdir)/basic-block.h \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
$(srcdir)/dependence.c \
$(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.153.2.37
diff -c -3 -p -r1.153.2.37 basic-block.h
*** basic-block.h 1 Dec 2003 22:30:48 -0000 1.153.2.37
--- basic-block.h 7 Dec 2003 23:00:56 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
/* Head of register set linked list. */
typedef bitmap_head regset_head;
+
/* A pointer to a regset_head. */
typedef bitmap regset;
*************** do { \
*** 121,147 ****
typedef HOST_WIDEST_INT gcov_type;
/* Control flow edge information. */
! typedef struct edge_def {
/* Links through the predecessor and successor lists. */
! struct edge_def *pred_next, *succ_next;
/* The two blocks at the ends of the edge. */
! struct basic_block_def *src, *dest;
/* Instructions queued on the edge. */
! union {
! rtx r;
! tree t;
! } insns;
/* Auxiliary info specific to a pass. */
! void *aux;
int flags; /* see EDGE_* below */
int probability; /* biased by REG_BR_PROB_BASE */
gcov_type count; /* Expected number of executions calculated
in profile.c */
! } *edge;
#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
#define EDGE_ABNORMAL 2 /* Strange flow, like computed
--- 122,154 ----
typedef HOST_WIDEST_INT gcov_type;
/* Control flow edge information. */
! struct edge_def GTY((chain_next ("%h.pred_next")))
! {
/* Links through the predecessor and successor lists. */
! struct edge_def *pred_next;
! struct edge_def *succ_next;
/* The two blocks at the ends of the edge. */
! struct basic_block_def *src;
! struct basic_block_def *dest;
/* Instructions queued on the edge. */
! union edge_def_insns {
! rtx GTY ((tag ("1"))) r;
! tree GTY ((tag ("2"))) t;
! } GTY ((desc ("cfg_hooks == &rtl_cfg_hooks ? 1 : cfg_hooks == &tree_cfg_hooks ? 2 : 0"),
! descbits ("2"))) insns;
/* Auxiliary info specific to a pass. */
! PTR GTY ((skip (""))) aux;
int flags; /* see EDGE_* below */
int probability; /* biased by REG_BR_PROB_BASE */
gcov_type count; /* Expected number of executions calculated
in profile.c */
! };
!
! typedef struct edge_def *edge;
#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
#define EDGE_ABNORMAL 2 /* Strange flow, like computed
*************** struct bb_ann_d;
*** 203,249 ****
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;
/* Pointers to the first and last trees of the block. */
tree stmt_list;
/* 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;
--- 210,260 ----
basic blocks. */
/* Basic block information indexed by block number. */
! struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")))
! {
/* The first and last insns of the block. */
! rtx head;
! rtx end;
/* Pointers to the first and last trees of the block. */
tree stmt_list;
/* The edges into and out of the block. */
! edge pred;
! edge 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. */
! struct basic_block_def *prev_bb;
! struct basic_block_def *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 {
*** 255,265 ****
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
--- 266,278 ----
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 varray_type basic_block_info;
*** 289,299 ****
#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
- /* The root of statement_lists of basic blocks for the garbage collector.
- This is a hack; we really should GC the entire CFG structure. */
- extern GTY(()) varray_type tree_bb_root;
- extern GTY(()) varray_type tree_phi_root;
-
/* For iterating over basic blocks. */
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
for (BB = FROM; BB != TO; BB = BB->DIR)
--- 302,307 ----
*************** extern struct obstack flow_obstack;
*** 346,354 ****
#define INVALID_BLOCK (-3)
/* Similarly, block pointers for the edge list. */
! extern struct basic_block_def entry_exit_blocks[2];
! #define ENTRY_BLOCK_PTR (&entry_exit_blocks[0])
! #define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
--- 354,361 ----
#define INVALID_BLOCK (-3)
/* Similarly, block pointers for the edge list. */
! extern GTY(()) basic_block ENTRY_BLOCK_PTR;
! extern GTY(()) basic_block EXIT_BLOCK_PTR;
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfg.c,v
retrieving revision 1.34.2.17
diff -c -3 -p -r1.34.2.17 cfg.c
*** cfg.c 1 Dec 2003 22:30:48 -0000 1.34.2.17
--- cfg.c 7 Dec 2003 23:00:56 -0000
*************** Software Foundation, 59 Temple Place - S
*** 62,81 ****
#include "tm_p.h"
#include "obstack.h"
#include "alloc-pool.h"
/* The obstack on which the flow graph components are allocated. */
struct obstack flow_obstack;
static char *flow_firstobj;
- /* Basic block object pool. */
-
- static alloc_pool bb_pool;
-
- /* Edge object pool. */
-
- static alloc_pool edge_pool;
-
/* Number of basic blocks in the current function. */
int n_basic_blocks;
--- 62,74 ----
#include "tm_p.h"
#include "obstack.h"
#include "alloc-pool.h"
+ #include "ggc.h"
/* The obstack on which the flow graph components are allocated. */
struct obstack flow_obstack;
static char *flow_firstobj;
/* Number of basic blocks in the current function. */
int n_basic_blocks;
*************** int n_edges;
*** 93,144 ****
varray_type basic_block_info;
/* The special entry and exit blocks. */
!
! struct basic_block_def entry_exit_blocks[2]
! = {{NULL, /* head */
! NULL, /* end */
! NULL, /* stmt_list*/
! NULL, /* pred */
! NULL, /* succ */
! NULL, /* local_set */
! NULL, /* cond_local_set */
! NULL, /* global_live_at_start */
! NULL, /* global_live_at_end */
! NULL, /* aux */
! ENTRY_BLOCK, /* index */
! NULL, /* prev_bb */
! EXIT_BLOCK_PTR, /* next_bb */
! 0, /* loop_depth */
! NULL, /* loop_father */
! 0, /* count */
! 0, /* frequency */
! 0, /* flags */
! NULL, /* rbi */
! NULL /* tree_annotations */
! },
! {
! NULL, /* head */
! NULL, /* end */
! NULL, /* stmt_list */
! NULL, /* pred */
! NULL, /* succ */
! NULL, /* local_set */
! NULL, /* cond_local_set */
! NULL, /* global_live_at_start */
! NULL, /* global_live_at_end */
! NULL, /* aux */
! EXIT_BLOCK, /* index */
! ENTRY_BLOCK_PTR, /* prev_bb */
! NULL, /* next_bb */
! 0, /* loop_depth */
! NULL, /* loop_father */
! 0, /* count */
! 0, /* frequency */
! 0, /* flags */
! NULL, /* rbi */
! NULL /* tree_annotations */
! }
! };
void debug_flow_info (void);
static void free_edge (edge);
--- 86,92 ----
varray_type basic_block_info;
/* The special entry and exit blocks. */
! basic_block ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR;
void debug_flow_info (void);
static void free_edge (edge);
*************** init_flow (void)
*** 160,184 ****
}
else
{
- free_alloc_pool (bb_pool);
- free_alloc_pool (edge_pool);
obstack_free (&flow_obstack, flow_firstobj);
flow_firstobj = obstack_alloc (&flow_obstack, 0);
}
! bb_pool = create_alloc_pool ("Basic block pool",
! sizeof (struct basic_block_def), 100);
! edge_pool = create_alloc_pool ("Edge pool",
! sizeof (struct edge_def), 100);
}
/* Helper function for remove_edge and clear_edges. Frees edge structure
without actually unlinking it from the pred/succ lists. */
static void
! free_edge (edge e)
{
n_edges--;
! pool_free (edge_pool, e);
}
/* Free the memory associated with the edge structures. */
--- 108,133 ----
}
else
{
obstack_free (&flow_obstack, flow_firstobj);
flow_firstobj = obstack_alloc (&flow_obstack, 0);
}
!
! ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
! ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
! EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
! EXIT_BLOCK_PTR->index = EXIT_BLOCK;
! ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
! EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
}
/* Helper function for remove_edge and clear_edges. Frees edge structure
without actually unlinking it from the pred/succ lists. */
static void
! free_edge (edge e ATTRIBUTE_UNUSED)
{
n_edges--;
! /* ggc_free (e); */
}
/* Free the memory associated with the edge structures. */
*************** basic_block
*** 227,234 ****
alloc_block (void)
{
basic_block bb;
! bb = pool_alloc (bb_pool);
! memset (bb, 0, sizeof (*bb));
return bb;
}
--- 176,182 ----
alloc_block (void)
{
basic_block bb;
! bb = ggc_alloc_cleared (sizeof (*bb));
return bb;
}
*************** compact_blocks (void)
*** 258,293 ****
basic_block bb;
i = 0;
- if (tree_phi_root)
- FOR_EACH_BB (bb)
- bb->aux = VARRAY_TREE (tree_phi_root, bb->index);
FOR_EACH_BB (bb)
{
BASIC_BLOCK (i) = bb;
- if (tree_bb_root)
- {
- VARRAY_TREE (tree_bb_root, i) = bb->stmt_list;
- VARRAY_TREE (tree_phi_root, i) = bb->aux;
- }
bb->index = i;
i++;
}
- if (tree_phi_root)
- FOR_EACH_BB (bb)
- bb->aux = NULL;
if (i != n_basic_blocks)
abort ();
for (; i < last_basic_block; i++)
! {
! BASIC_BLOCK (i) = NULL;
! if (tree_bb_root)
! {
! VARRAY_TREE (tree_bb_root, i) = NULL_TREE;
! VARRAY_TREE (tree_phi_root, i) = NULL_TREE;
! }
! }
last_basic_block = n_basic_blocks;
}
--- 206,223 ----
basic_block bb;
i = 0;
FOR_EACH_BB (bb)
{
BASIC_BLOCK (i) = bb;
bb->index = i;
i++;
}
if (i != n_basic_blocks)
abort ();
for (; i < last_basic_block; i++)
! BASIC_BLOCK (i) = NULL;
last_basic_block = n_basic_blocks;
}
*************** expunge_block (basic_block b)
*** 300,306 ****
unlink_block (b);
BASIC_BLOCK (b->index) = NULL;
n_basic_blocks--;
! pool_free (bb_pool, b);
}
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
--- 230,236 ----
unlink_block (b);
BASIC_BLOCK (b->index) = NULL;
n_basic_blocks--;
! /* ggc_free (b); */
}
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
*************** edge
*** 311,318 ****
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
edge e;
! e = pool_alloc (edge_pool);
! memset (e, 0, sizeof (*e));
n_edges++;
e->succ_next = src->succ;
--- 241,247 ----
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
edge e;
! e = ggc_alloc_cleared (sizeof (*e));
n_edges++;
e->succ_next = src->succ;
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.57.2.19
diff -c -3 -p -r1.57.2.19 cfgrtl.c
*** cfgrtl.c 14 Nov 2003 00:24:28 -0000 1.57.2.19
--- cfgrtl.c 7 Dec 2003 23:00:57 -0000
*************** rtl_merge_blocks (basic_block a, basic_b
*** 623,633 ****
else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
del_first = NEXT_INSN (a_end);
- update_cfg_after_block_merging (a, b);
-
/* Delete everything marked above as well as crap that might be
hanging out between the two blocks. */
delete_insn_chain (del_first, del_last);
/* Reassociate the insns of B with A. */
if (!b_empty)
--- 623,634 ----
else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
del_first = NEXT_INSN (a_end);
/* Delete everything marked above as well as crap that might be
hanging out between the two blocks. */
+ b->head = NULL;
delete_insn_chain (del_first, del_last);
+
+ update_cfg_after_block_merging (a, b);
/* Reassociate the insns of B with A. */
if (!b_empty)
Index: gengtype-lex.l
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype-lex.l,v
retrieving revision 1.5.6.10
diff -c -3 -p -r1.5.6.10 gengtype-lex.l
*** gengtype-lex.l 18 Oct 2003 23:59:46 -0000 1.5.6.10
--- gengtype-lex.l 7 Dec 2003 23:00:58 -0000
*************** update_lineno (const char *l, size_t len
*** 47,53 ****
ID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
! IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t|CHAR_BITFIELD
ITYPE {IWORD}({WS}{IWORD})*
%x in_struct in_struct_comment in_comment in_yacc_escape
--- 47,53 ----
ID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
! IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|CHAR_BITFIELD
ITYPE {IWORD}({WS}{IWORD})*
%x in_struct in_struct_comment in_comment in_yacc_escape
Index: regs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regs.h,v
retrieving revision 1.25.8.4
diff -c -3 -p -r1.25.8.4 regs.h
*** regs.h 23 Jul 2003 16:59:53 -0000 1.25.8.4
--- regs.h 7 Dec 2003 23:00:58 -0000
*************** along with GCC; see the file COPYING. I
*** 19,24 ****
--- 19,26 ----
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+ #ifndef GCC_REGS_H
+ #define GCC_REGS_H
#include "varray.h"
#include "hard-reg-set.h"
*************** extern int caller_save_needed;
*** 221,223 ****
--- 223,227 ----
/* Allocate reg_n_info tables */
extern void allocate_reg_info (size_t, int, int);
+
+ #endif /* GCC_REGS_H */
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.232
diff -c -3 -p -r1.1.4.232 tree-cfg.c
*** tree-cfg.c 7 Dec 2003 20:18:55 -0000 1.1.4.232
--- tree-cfg.c 7 Dec 2003 23:01:00 -0000
*************** static dominance_info pdom_info = NULL;
*** 69,77 ****
static struct cfg_stats_d cfg_stats;
- static struct obstack block_tree_ann_obstack;
- static void *first_block_tree_ann_obj = 0;
-
/* Nonzero if we found a computed goto while building basic blocks. */
static bool found_computed_goto;
--- 69,74 ----
*************** static tree factored_computed_goto_label
*** 84,93 ****
the destination of computed gotos when unfactoring them. */
static tree factored_computed_goto;
- /* The root of statement_lists of basic blocks for the garbage collector.
- This is a hack; we really should GC the entire CFG structure. */
- varray_type tree_bb_root;
-
/* Basic blocks and flowgraphs. */
static basic_block create_bb (tree, basic_block);
static void create_blocks_annotations (void);
--- 81,86 ----
*************** build_tree_cfg (tree *fnbody)
*** 151,159 ****
VARRAY_BB_INIT (basic_block_info, initial_cfg_capacity, "basic_block_info");
memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
- VARRAY_TREE_INIT (tree_bb_root, initial_cfg_capacity, "tree_bb_root");
- VARRAY_TREE_INIT (tree_phi_root, initial_cfg_capacity, "tree_phi_root");
-
/* Build a mapping of labels to their associated blocks. */
VARRAY_BB_INIT (label_to_block_map, initial_cfg_capacity,
"label to block map");
--- 144,149 ----
*************** build_tree_cfg (tree *fnbody)
*** 176,183 ****
{
/* Adjust the size of the array. */
VARRAY_GROW (basic_block_info, n_basic_blocks);
- VARRAY_GROW (tree_bb_root, n_basic_blocks);
- VARRAY_GROW (tree_phi_root, n_basic_blocks);
/* Create block annotations. */
create_blocks_annotations ();
--- 166,171 ----
*************** factor_computed_gotos (void)
*** 288,305 ****
static void create_blocks_annotations (void)
{
basic_block bb;
- static int initialized;
-
- if (!initialized)
- {
- gcc_obstack_init (&block_tree_ann_obstack);
- initialized = 1;
- }
- /* Check whether TREE_ANNOTATIONS data are still allocated. */
- else if (first_block_tree_ann_obj)
- abort ();
-
- first_block_tree_ann_obj = obstack_alloc (&block_tree_ann_obstack, 0);
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
create_block_annotation (bb);
--- 276,281 ----
*************** static void create_blocks_annotations (v
*** 310,331 ****
static void create_block_annotation (basic_block bb)
{
/* Verify that the tree_annotations field is clear. */
! if (bb->tree_annotations || !first_block_tree_ann_obj)
abort ();
! bb->tree_annotations = obstack_alloc (&block_tree_ann_obstack,
! sizeof (struct bb_ann_d));
! memset (bb->tree_annotations, 0, sizeof (struct bb_ann_d));
}
/* Free the annotations for all the basic blocks. */
static void free_blocks_annotations (void)
{
- if (!first_block_tree_ann_obj)
- abort ();
- obstack_free (&block_tree_ann_obstack, first_block_tree_ann_obj);
- first_block_tree_ann_obj = NULL;
-
clear_blocks_annotations ();
}
--- 286,300 ----
static void create_block_annotation (basic_block bb)
{
/* Verify that the tree_annotations field is clear. */
! if (bb->tree_annotations)
abort ();
! bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
}
/* Free the annotations for all the basic blocks. */
static void free_blocks_annotations (void)
{
clear_blocks_annotations ();
}
*************** create_bb (tree stmt_list, basic_block a
*** 411,423 ****
{
size_t new_size = n_basic_blocks + (n_basic_blocks + 3) / 4;
VARRAY_GROW (basic_block_info, new_size);
- VARRAY_GROW (tree_bb_root, new_size);
- VARRAY_GROW (tree_phi_root, new_size);
}
/* Add the newly created block to the array. */
BASIC_BLOCK (n_basic_blocks) = bb;
- VARRAY_TREE (tree_bb_root, bb->index) = bb->stmt_list;
n_basic_blocks++;
last_basic_block++;
--- 380,389 ----
*************** remove_bb (basic_block bb)
*** 1488,1496 ****
if (pdom_info)
delete_from_dominance_info (pdom_info, bb);
- VARRAY_TREE (tree_bb_root, bb->index) = NULL_TREE;
- VARRAY_TREE (tree_phi_root, bb->index) = NULL_TREE;
-
/* Remove the basic block from the array. */
expunge_block (bb);
}
--- 1454,1459 ----
*************** delete_tree_cfg (void)
*** 2369,2376 ****
free_blocks_annotations ();
free_basic_block_vars (0);
- tree_bb_root = NULL;
- tree_phi_root = NULL;
label_to_block_map = NULL;
}
--- 2332,2337 ----
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.198
diff -c -3 -p -r1.1.4.198 tree-dfa.c
*** tree-dfa.c 5 Dec 2003 23:02:24 -0000 1.1.4.198
--- tree-dfa.c 7 Dec 2003 23:01:01 -0000
*************** Boston, MA 02111-1307, USA. */
*** 45,53 ****
#include "tree-alias-common.h"
#include "convert.h"
- /* The root of statement_lists of basic blocks for the garbage collector.
- This is a hack; we really should GC the entire CFG structure. */
- varray_type tree_phi_root;
/* Build and maintain data flow information for trees. */
/* Counters used to display DFA and SSA statistics. */
--- 45,50 ----
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.60
diff -c -3 -p -r1.1.2.60 tree-flow-inline.h
*** tree-flow-inline.h 6 Dec 2003 12:31:27 -0000 1.1.2.60
--- tree-flow-inline.h 7 Dec 2003 23:01:01 -0000
*************** phi_nodes (basic_block bb)
*** 275,281 ****
{
if (bb->index < 0)
return NULL;
! return VARRAY_TREE (tree_phi_root, bb->index);
}
/* Set list of phi nodes of a basic block BB to L. */
--- 275,281 ----
{
if (bb->index < 0)
return NULL;
! return bb_ann (bb)->phi_nodes;
}
/* Set list of phi nodes of a basic block BB to L. */
*************** set_phi_nodes (basic_block bb, tree l)
*** 285,291 ****
{
tree phi;
! VARRAY_TREE (tree_phi_root, bb->index) = l;
for (phi = l; phi; phi = TREE_CHAIN (phi))
set_bb_for_stmt (phi, bb);
}
--- 285,291 ----
{
tree phi;
! bb_ann (bb)->phi_nodes = l;
for (phi = l; phi; phi = TREE_CHAIN (phi))
set_bb_for_stmt (phi, bb);
}
*************** add_dom_child (basic_block bb, basic_blo
*** 326,332 ****
{
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);
}
--- 326,332 ----
{
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_
*** 346,353 ****
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;
}
--- 346,351 ----
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.166
diff -c -3 -p -r1.1.4.166 tree-flow.h
*** tree-flow.h 7 Dec 2003 10:07:45 -0000 1.1.4.166
--- tree-flow.h 7 Dec 2003 23:01:01 -0000
*************** static inline tree default_def (tree);
*** 303,310 ****
/*---------------------------------------------------------------------------
Block annotations stored in basic_block.tree_annotations
---------------------------------------------------------------------------*/
! struct bb_ann_d
{
/* Chain of EPHI nodes created in this block. */
tree ephi_nodes;
--- 303,313 ----
/*---------------------------------------------------------------------------
Block annotations stored in basic_block.tree_annotations
---------------------------------------------------------------------------*/
! struct bb_ann_d GTY(())
{
+ /* Chain of PHI nodes for this block. */
+ tree phi_nodes;
+
/* Chain of EPHI nodes created in this block. */
tree ephi_nodes;
Index: tree-phinodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-phinodes.c,v
retrieving revision 1.1.2.7
diff -c -3 -p -r1.1.2.7 tree-phinodes.c
*** tree-phinodes.c 5 Dec 2003 23:02:24 -0000 1.1.2.7
--- tree-phinodes.c 7 Dec 2003 23:01:01 -0000
*************** create_phi_node (tree var, basic_block b
*** 298,304 ****
/* Add the new PHI node to the list of PHI nodes for block BB. */
TREE_CHAIN (phi) = phi_nodes (bb);
! VARRAY_TREE (tree_phi_root, bb->index) = phi;
/* Associate BB to the PHI node. */
set_bb_for_stmt (phi, bb);
--- 298,304 ----
/* Add the new PHI node to the list of PHI nodes for block BB. */
TREE_CHAIN (phi) = phi_nodes (bb);
! bb_ann (bb)->phi_nodes = phi;
/* Associate BB to the PHI node. */
set_bb_for_stmt (phi, bb);
*************** add_phi_arg (tree *phi, tree def, edge e
*** 335,341 ****
/* Update the list head if replacing the first listed phi. */
if (phi_nodes (e->dest) == old_phi)
! VARRAY_TREE (tree_phi_root, e->dest->index) = *phi;
else
{
/* Traverse the list looking for the phi node to chain to. */
--- 335,341 ----
/* Update the list head if replacing the first listed phi. */
if (phi_nodes (e->dest) == old_phi)
! bb_ann (e->dest)->phi_nodes = *phi;
else
{
/* Traverse the list looking for the phi node to chain to. */
*************** remove_phi_node (tree phi, tree prev, ba
*** 438,444 ****
else if (phi == phi_nodes (bb))
{
/* Update the list head if removing the first element. */
! VARRAY_TREE (tree_phi_root, bb->index) = TREE_CHAIN (phi);
/* If we are deleting the PHI node, then we should release the
SSA_NAME node so that it can be reused. */
--- 438,444 ----
else if (phi == phi_nodes (bb))
{
/* Update the list head if removing the first element. */
! bb_ann (bb)->phi_nodes = TREE_CHAIN (phi);
/* If we are deleting the PHI node, then we should release the
SSA_NAME node so that it can be reused. */
*************** remove_all_phi_nodes_for (bitmap vars)
*** 504,510 ****
/* Make sure the last node in the new list has no successors. */
if (last_phi)
TREE_CHAIN (last_phi) = NULL_TREE;
! VARRAY_TREE (tree_phi_root, bb->index) = new_phi_list;
#if defined ENABLE_CHECKING
for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
--- 504,510 ----
/* Make sure the last node in the new list has no successors. */
if (last_phi)
TREE_CHAIN (last_phi) = NULL_TREE;
! bb_ann (bb)->phi_nodes = new_phi_list;
#if defined ENABLE_CHECKING
for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.114
diff -c -3 -p -r1.1.4.114 tree-ssa-pre.c
*** tree-ssa-pre.c 5 Dec 2003 23:02:24 -0000 1.1.4.114
--- tree-ssa-pre.c 7 Dec 2003 23:01:03 -0000
*************** code_motion (struct expr_info *ei)
*** 2647,2656 ****
{
bb = bb_for_stmt (use);
/* Add the new PHI node to the list of PHI nodes for block BB. */
! if (phi_nodes (bb) == NULL)
! VARRAY_TREE (tree_phi_root, bb->index) = EREF_TEMP (use);
! else
! chainon (phi_nodes (bb), EREF_TEMP (use));
VARRAY_PUSH_TREE (added_phis, EREF_TEMP (use));
}
else if (EPHI_IDENTITY (use))
--- 2647,2653 ----
{
bb = bb_for_stmt (use);
/* Add the new PHI node to the list of PHI nodes for block BB. */
! bb_ann (bb)->phi_nodes = chainon (phi_nodes (bb), EREF_TEMP (use));
VARRAY_PUSH_TREE (added_phis, EREF_TEMP (use));
}
else if (EPHI_IDENTITY (use))
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.28.2.7
diff -c -3 -p -r1.28.2.7 varray.h
*** varray.h 25 Oct 2003 17:48:24 -0000 1.28.2.7
--- varray.h 7 Dec 2003 23:01:03 -0000
*************** typedef union varray_data_tag GTY (()) {
*** 127,137 ****
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];
! struct edge_def *GTY ((length ("%0.num_elements"), skip (""),
tag ("VARRAY_DATA_EDGE"))) e[1];
tree *GTY ((length ("%0.num_elements"), skip (""),
tag ("VARRAY_DATA_TREE_PTR"))) tp[1];
--- 127,137 ----
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];
! struct edge_def *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_EDGE"))) e[1];
tree *GTY ((length ("%0.num_elements"), skip (""),
tag ("VARRAY_DATA_TREE_PTR"))) tp[1];