Index: basic-block.h =================================================================== --- basic-block.h (revision 194362) +++ basic-block.h (working copy) @@ -35,7 +35,9 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigne /* Control flow edge information. */ struct GTY((user)) edge_def { - /* The two blocks at the ends of the edge. */ + /* The two blocks at the ends of the edge. The 'user' marker function + should ignore them for GC, because basic_blocks get visited via the + basic_block_info array in struct control_flow_graph. */ basic_block src; basic_block dest; @@ -177,23 +179,25 @@ struct GTY(()) gimple_bb_info { basic blocks. */ /* Basic block information indexed by block number. */ -struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def { +struct GTY (()) basic_block_def { /* The edges into and out of the block. */ vec *preds; vec *succs; /* Auxiliary info specific to a pass. */ - PTR GTY ((skip (""))) aux; + PTR GTY ((skip)) aux; /* Innermost loop containing the block. */ struct loop *loop_father; /* The dominance and postdominance information node. */ - struct et_node * GTY ((skip (""))) dom[2]; + struct et_node * GTY ((skip)) dom[2]; - /* Previous and next blocks in the chain. */ - basic_block prev_bb; - basic_block next_bb; + /* Previous and next blocks in the chain. Ignore them for GC, + they get visited via the basic_block_info array in struct + control_flow_graph. */ + basic_block GTY ((skip)) prev_bb; + basic_block GTY ((skip)) next_bb; union basic_block_il_dependent { struct gimple_bb_info GTY ((tag ("0"))) gimple; @@ -289,8 +293,8 @@ enum profile_status_d struct GTY(()) control_flow_graph { /* Block pointers for the exit and entry of a function. These are always the head and tail of the basic block list. */ - basic_block x_entry_block_ptr; - basic_block x_exit_block_ptr; + basic_block GTY ((skip)) x_entry_block_ptr; + basic_block GTY ((skip)) x_exit_block_ptr; /* Index by basic block number, get basic block struct info. */ vec *x_basic_block_info; Index: gimple.h =================================================================== --- gimple.h (revision 194362) +++ gimple.h (working copy) @@ -195,8 +195,10 @@ struct GTY((chain_next ("%h.next"))) gimple_statem unsigned num_ops; /* [ WORD 3 ] - Basic block holding this statement. */ - basic_block bb; + Basic block holding this statement. + Marking for GC happens via the basic_block_info array in + struct control_flow_graph. */ + basic_block GTY((skip)) bb; /* [ WORD 4-5 ] Linked lists of gimple statements. The next pointers form Index: gengtype.c =================================================================== --- gengtype.c (revision 194362) +++ gengtype.c (working copy) @@ -1289,6 +1289,10 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUS subfields->opt = create_string_option (subfields->opt, "desc", "CONSTANT_POOL_ADDRESS_P (&%0)"); + if (t == basic_block_tp) + subfields->opt = + create_string_option (subfields->opt, "skip", + ""); } if (i == SYMBOL_REF) Index: tree-cfg.c =================================================================== --- tree-cfg.c (revision 194362) +++ tree-cfg.c (working copy) @@ -8023,45 +8023,33 @@ extern void gt_ggc_mx (basic_block&); void gt_ggc_mx (edge_def *e) { - tree block = LOCATION_BLOCK (e->goto_locus); - gt_ggc_mx (e->src); - gt_ggc_mx (e->dest); + /* e->src and e->dest are not marked here. All basic blocks + are marked via the basic_block_info array in the CFG data + structure hanging from each struct function. */ + + /* So, only mark the other fields. */ if (current_ir_type () == IR_GIMPLE) gt_ggc_mx (e->insns.g); else gt_ggc_mx (e->insns.r); + + tree block = LOCATION_BLOCK (e->goto_locus); gt_ggc_mx (block); } -/* PCH support for edge_def. */ +/* PCH support, or rather lack thereof, for edge_def. + CFG data structures should never end up in a PCH. */ -extern void gt_pch_nx (tree&); -extern void gt_pch_nx (gimple&); -extern void gt_pch_nx (rtx&); -extern void gt_pch_nx (basic_block&); - void -gt_pch_nx (edge_def *e) +gt_pch_nx (edge_def *e ATTRIBUTE_UNUSED) { - tree block = LOCATION_BLOCK (e->goto_locus); - gt_pch_nx (e->src); - gt_pch_nx (e->dest); - if (current_ir_type () == IR_GIMPLE) - gt_pch_nx (e->insns.g); - else - gt_pch_nx (e->insns.r); - gt_pch_nx (block); + gcc_unreachable (); } void -gt_pch_nx (edge_def *e, gt_pointer_operator op, void *cookie) +gt_pch_nx (edge_def *e ATTRIBUTE_UNUSED, + gt_pointer_operator op ATTRIBUTE_UNUSED, + void *cookie ATTRIBUTE_UNUSED) { - tree block = LOCATION_BLOCK (e->goto_locus); - op (&(e->src), cookie); - op (&(e->dest), cookie); - if (current_ir_type () == IR_GIMPLE) - op (&(e->insns.g), cookie); - else - op (&(e->insns.r), cookie); - op (&(block), cookie); + gcc_unreachable (); }