Patchwork rfa: shrink rtl_bb_info

login
register
mail settings
Submitter Michael Matz
Date May 3, 2012, 4:05 p.m.
Message ID <Pine.LNX.4.64.1205031757280.25409@wotan.suse.de>
Download mbox | patch
Permalink /patch/156737/
State New
Headers show

Comments

Michael Matz - May 3, 2012, 4:05 p.m.
Hi,

Richi made some good points about my last patch, related to struct 
rtl_bb_info.  Even though it's not that important to shrink it (only few 
BBs are in RTL mode) there's no need to waste space.  My last patch 
created an unused pointer-sized hole in RTL mode, which we can just as 
well use for members of rtl_bb_info.  I've simply chosen the first, head_, 
because it entails few overall churn due to the use of BB_HEAD macro 
(header/footer are used directly), and because it's, well, the first :)

We also thought about the visited member, but on review it's actually a 
silly member which we can also remove.  There's only three uses of it 
currently:

* cfglayout.c: set-only never used
* bb-reorder: duplicate_computed_gotos: used as bool flag
* bb-reorder: tracing, used not as flag, but as trace indicator

The first is useless, the second can be replaced by a proper bb->flags 
(BB_VISITED, newly introduced) and the third by an field in the 
side data structure that bb-reorder already employs.  Et voila, one word 
less for rtl_bb_info, making it overall one word smaller than before my 
last patch :)

The churn in the patch is due to the il.rtl --> il.x.rtl renaming.  I wish 
we would accept anonymous structs for our sources, but we don't.

Currently regstrapping on x86_64-linux, okay if that passes?


Ciao,
Michael.
-------------------------
2012-05-03  Michael Matz  <matz@suse.de>

	* basic-block.h (struct rtl_bb_info): Remove visited member and
	move head_ member to ...
	(struct basic_block_def.basic_block_il_dependent): ... the new
	member x, replacing but containing old member rtl.
	(enum bb_flags): New BB_VISITED flag.

	* jump.c (mark_all_labels): Adjust.
	* cfgcleanup.c (try_optimize_cfg): Adjust.
	* cfglayout.c (record_effective_endpoints): Adjust.
	(relink_block_chain): Ditto (and don't fiddle with visited).
	(fixup_reorder_chain): Adjust.
	(fixup_fallthru_exit_predecessor): Ditto.
	(cfg_layout_duplicate_bb): Ditto.
	* combine.c (update_cfg_for_uncondjump): Adjust.
	* bb-reorder.c (struct bbro_basic_block_data_def): Add visited
	member.
	(bb_visited_trace): New accessor.
	(mark_bb_visited): Move in front.
	(rotate_loop): Use bb_visited_trace.
	(find_traces_1_round): Ditto.
	(emit_barrier_after): Ditto.
	(copy_bb): Ditto, and initialize visited on resize.
	(reorder_basic_blocks): Initize visited member.
	(duplicate_computed_gotos): Clear bb flags at start, use
	BB_VISITED flags.

	* cfgrtl.c (try_redirect_by_replacing_jump): Adjust.
	(rtl_verify_flow_info_1): Ditto.
	(cfg_layout_split_block): Ditto.
	(cfg_layout_delete_block): Ditto.
	(cfg_layout_merge_blocks): Ditto.
	(init_rtl_bb_info): Adjust and initialize il.x.head_ member.
Richard Guenther - May 4, 2012, 7:16 a.m.
On Thu, May 3, 2012 at 6:05 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> Richi made some good points about my last patch, related to struct
> rtl_bb_info.  Even though it's not that important to shrink it (only few
> BBs are in RTL mode) there's no need to waste space.  My last patch
> created an unused pointer-sized hole in RTL mode, which we can just as
> well use for members of rtl_bb_info.  I've simply chosen the first, head_,
> because it entails few overall churn due to the use of BB_HEAD macro
> (header/footer are used directly), and because it's, well, the first :)
>
> We also thought about the visited member, but on review it's actually a
> silly member which we can also remove.  There's only three uses of it
> currently:
>
> * cfglayout.c: set-only never used
> * bb-reorder: duplicate_computed_gotos: used as bool flag
> * bb-reorder: tracing, used not as flag, but as trace indicator
>
> The first is useless, the second can be replaced by a proper bb->flags
> (BB_VISITED, newly introduced) and the third by an field in the
> side data structure that bb-reorder already employs.  Et voila, one word
> less for rtl_bb_info, making it overall one word smaller than before my
> last patch :)
>
> The churn in the patch is due to the il.rtl --> il.x.rtl renaming.  I wish
> we would accept anonymous structs for our sources, but we don't.

Well, as you touch all places that refer to header/footer why not
introduce macros to access them ...

> Currently regstrapping on x86_64-linux, okay if that passes?

Ok with the above change.

Thanks,
Richard.

>
> Ciao,
> Michael.
> -------------------------
> 2012-05-03  Michael Matz  <matz@suse.de>
>
>        * basic-block.h (struct rtl_bb_info): Remove visited member and
>        move head_ member to ...
>        (struct basic_block_def.basic_block_il_dependent): ... the new
>        member x, replacing but containing old member rtl.
>        (enum bb_flags): New BB_VISITED flag.
>
>        * jump.c (mark_all_labels): Adjust.
>        * cfgcleanup.c (try_optimize_cfg): Adjust.
>        * cfglayout.c (record_effective_endpoints): Adjust.
>        (relink_block_chain): Ditto (and don't fiddle with visited).
>        (fixup_reorder_chain): Adjust.
>        (fixup_fallthru_exit_predecessor): Ditto.
>        (cfg_layout_duplicate_bb): Ditto.
>        * combine.c (update_cfg_for_uncondjump): Adjust.
>        * bb-reorder.c (struct bbro_basic_block_data_def): Add visited
>        member.
>        (bb_visited_trace): New accessor.
>        (mark_bb_visited): Move in front.
>        (rotate_loop): Use bb_visited_trace.
>        (find_traces_1_round): Ditto.
>        (emit_barrier_after): Ditto.
>        (copy_bb): Ditto, and initialize visited on resize.
>        (reorder_basic_blocks): Initize visited member.
>        (duplicate_computed_gotos): Clear bb flags at start, use
>        BB_VISITED flags.
>
>        * cfgrtl.c (try_redirect_by_replacing_jump): Adjust.
>        (rtl_verify_flow_info_1): Ditto.
>        (cfg_layout_split_block): Ditto.
>        (cfg_layout_delete_block): Ditto.
>        (cfg_layout_merge_blocks): Ditto.
>        (init_rtl_bb_info): Adjust and initialize il.x.head_ member.
>
> Index: jump.c
> ===================================================================
> --- jump.c      (revision 187098)
> +++ jump.c      (working copy)
> @@ -275,13 +275,13 @@ mark_all_labels (rtx f)
>          /* In cfglayout mode, there may be non-insns between the
>             basic blocks.  If those non-insns represent tablejump data,
>             they contain label references that we must record.  */
> -         for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
> +         for (insn = bb->il.x.rtl->header; insn; insn = NEXT_INSN (insn))
>            if (INSN_P (insn))
>              {
>                gcc_assert (JUMP_TABLE_DATA_P (insn));
>                mark_jump_label (PATTERN (insn), insn, 0);
>              }
> -         for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
> +         for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
>            if (INSN_P (insn))
>              {
>                gcc_assert (JUMP_TABLE_DATA_P (insn));
> Index: cfgcleanup.c
> ===================================================================
> --- cfgcleanup.c        (revision 187098)
> +++ cfgcleanup.c        (working copy)
> @@ -2586,21 +2586,21 @@ try_optimize_cfg (int mode)
>
>                      if (current_ir_type () == IR_RTL_CFGLAYOUT)
>                        {
> -                         if (b->il.rtl->footer
> -                             && BARRIER_P (b->il.rtl->footer))
> +                         if (b->il.x.rtl->footer
> +                             && BARRIER_P (b->il.x.rtl->footer))
>                            FOR_EACH_EDGE (e, ei, b->preds)
>                              if ((e->flags & EDGE_FALLTHRU)
> -                                 && e->src->il.rtl->footer == NULL)
> +                                 && e->src->il.x.rtl->footer == NULL)
>                                {
> -                                 if (b->il.rtl->footer)
> +                                 if (b->il.x.rtl->footer)
>                                    {
> -                                     e->src->il.rtl->footer = b->il.rtl->footer;
> -                                     b->il.rtl->footer = NULL;
> +                                     e->src->il.x.rtl->footer = b->il.x.rtl->footer;
> +                                     b->il.x.rtl->footer = NULL;
>                                    }
>                                  else
>                                    {
>                                      start_sequence ();
> -                                     e->src->il.rtl->footer = emit_barrier ();
> +                                     e->src->il.x.rtl->footer = emit_barrier ();
>                                      end_sequence ();
>                                    }
>                                }
> Index: cfglayout.c
> ===================================================================
> --- cfglayout.c (revision 187098)
> +++ cfglayout.c (working copy)
> @@ -208,11 +208,11 @@ record_effective_endpoints (void)
>       rtx end;
>
>       if (PREV_INSN (BB_HEAD (bb)) && next_insn != BB_HEAD (bb))
> -       bb->il.rtl->header = unlink_insn_chain (next_insn,
> +       bb->il.x.rtl->header = unlink_insn_chain (next_insn,
>                                              PREV_INSN (BB_HEAD (bb)));
>       end = skip_insns_after_block (bb);
>       if (NEXT_INSN (BB_END (bb)) && BB_END (bb) != end)
> -       bb->il.rtl->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
> +       bb->il.x.rtl->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
>       next_insn = NEXT_INSN (BB_END (bb));
>     }
>
> @@ -633,9 +633,8 @@ reemit_insn_block_notes (void)
>
>
>  /* Link the basic blocks in the correct order, compacting the basic
> -   block queue while at it.  This also clears the visited flag on
> -   all basic blocks.  If STAY_IN_CFGLAYOUT_MODE is false, this function
> -   also clears the basic block header and footer fields.
> +   block queue while at it.  If STAY_IN_CFGLAYOUT_MODE is false, this
> +   function also clears the basic block header and footer fields.
>
>    This function is usually called after a pass (e.g. tracer) finishes
>    some transformations while in cfglayout mode.  The required sequence
> @@ -681,13 +680,12 @@ relink_block_chain (bool stay_in_cfglayo
>   prev_bb->next_bb = EXIT_BLOCK_PTR;
>   EXIT_BLOCK_PTR->prev_bb = prev_bb;
>
> -  /* Then, clean up the aux and visited fields.  */
> +  /* Then, clean up the aux fields.  */
>   FOR_ALL_BB (bb)
>     {
>       bb->aux = NULL;
> -      bb->il.rtl->visited = 0;
>       if (!stay_in_cfglayout_mode)
> -       bb->il.rtl->header = bb->il.rtl->footer = NULL;
> +       bb->il.x.rtl->header = bb->il.x.rtl->footer = NULL;
>     }
>
>   /* Maybe reset the original copy tables, they are not valid anymore
> @@ -723,14 +721,14 @@ fixup_reorder_chain (void)
>
>   for (bb = ENTRY_BLOCK_PTR->next_bb; bb; bb = (basic_block) bb->aux)
>     {
> -      if (bb->il.rtl->header)
> +      if (bb->il.x.rtl->header)
>        {
>          if (insn)
> -           NEXT_INSN (insn) = bb->il.rtl->header;
> +           NEXT_INSN (insn) = bb->il.x.rtl->header;
>          else
> -           set_first_insn (bb->il.rtl->header);
> -         PREV_INSN (bb->il.rtl->header) = insn;
> -         insn = bb->il.rtl->header;
> +           set_first_insn (bb->il.x.rtl->header);
> +         PREV_INSN (bb->il.x.rtl->header) = insn;
> +         insn = bb->il.x.rtl->header;
>          while (NEXT_INSN (insn))
>            insn = NEXT_INSN (insn);
>        }
> @@ -740,10 +738,10 @@ fixup_reorder_chain (void)
>        set_first_insn (BB_HEAD (bb));
>       PREV_INSN (BB_HEAD (bb)) = insn;
>       insn = BB_END (bb);
> -      if (bb->il.rtl->footer)
> +      if (bb->il.x.rtl->footer)
>        {
> -         NEXT_INSN (insn) = bb->il.rtl->footer;
> -         PREV_INSN (bb->il.rtl->footer) = insn;
> +         NEXT_INSN (insn) = bb->il.x.rtl->footer;
> +         PREV_INSN (bb->il.x.rtl->footer) = insn;
>          while (NEXT_INSN (insn))
>            insn = NEXT_INSN (insn);
>        }
> @@ -799,7 +797,7 @@ fixup_reorder_chain (void)
>                {
>                  gcc_assert (!onlyjump_p (bb_end_insn)
>                              || returnjump_p (bb_end_insn));
> -                 bb->il.rtl->footer = emit_barrier_after (bb_end_insn);
> +                 bb->il.x.rtl->footer = emit_barrier_after (bb_end_insn);
>                  continue;
>                }
>
> @@ -908,7 +906,6 @@ fixup_reorder_chain (void)
>       nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
>       if (nb)
>        {
> -         nb->il.rtl->visited = 1;
>          nb->aux = bb->aux;
>          bb->aux = nb;
>          /* Don't process this new block.  */
> @@ -1062,8 +1059,8 @@ fixup_fallthru_exit_predecessor (void)
>          bb = split_block (bb, NULL)->dest;
>          bb->aux = c->aux;
>          c->aux = bb;
> -         bb->il.rtl->footer = c->il.rtl->footer;
> -         c->il.rtl->footer = NULL;
> +         bb->il.x.rtl->footer = c->il.x.rtl->footer;
> +         c->il.x.rtl->footer = NULL;
>        }
>
>       while (c->aux != bb)
> @@ -1272,24 +1269,24 @@ cfg_layout_duplicate_bb (basic_block bb)
>                               EXIT_BLOCK_PTR->prev_bb);
>
>   BB_COPY_PARTITION (new_bb, bb);
> -  if (bb->il.rtl->header)
> +  if (bb->il.x.rtl->header)
>     {
> -      insn = bb->il.rtl->header;
> +      insn = bb->il.x.rtl->header;
>       while (NEXT_INSN (insn))
>        insn = NEXT_INSN (insn);
> -      insn = duplicate_insn_chain (bb->il.rtl->header, insn);
> +      insn = duplicate_insn_chain (bb->il.x.rtl->header, insn);
>       if (insn)
> -       new_bb->il.rtl->header = unlink_insn_chain (insn, get_last_insn ());
> +       new_bb->il.x.rtl->header = unlink_insn_chain (insn, get_last_insn ());
>     }
>
> -  if (bb->il.rtl->footer)
> +  if (bb->il.x.rtl->footer)
>     {
> -      insn = bb->il.rtl->footer;
> +      insn = bb->il.x.rtl->footer;
>       while (NEXT_INSN (insn))
>        insn = NEXT_INSN (insn);
> -      insn = duplicate_insn_chain (bb->il.rtl->footer, insn);
> +      insn = duplicate_insn_chain (bb->il.x.rtl->footer, insn);
>       if (insn)
> -       new_bb->il.rtl->footer = unlink_insn_chain (insn, get_last_insn ());
> +       new_bb->il.x.rtl->footer = unlink_insn_chain (insn, get_last_insn ());
>     }
>
>   return new_bb;
> Index: combine.c
> ===================================================================
> --- combine.c   (revision 187098)
> +++ combine.c   (working copy)
> @@ -2536,13 +2536,13 @@ update_cfg_for_uncondjump (rtx insn)
>       single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
>
>       /* Remove barriers from the footer if there are any.  */
> -      for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
> +      for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
>        if (BARRIER_P (insn))
>          {
>            if (PREV_INSN (insn))
>              NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
>            else
> -             bb->il.rtl->footer = NEXT_INSN (insn);
> +             bb->il.x.rtl->footer = NEXT_INSN (insn);
>            if (NEXT_INSN (insn))
>              PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
>          }
> Index: bb-reorder.c
> ===================================================================
> --- bb-reorder.c        (revision 187098)
> +++ bb-reorder.c        (working copy)
> @@ -133,6 +133,9 @@ typedef struct bbro_basic_block_data_def
>   /* Which trace is the bb in?  */
>   int in_trace;
>
> +  /* Which trace was this bb visited in?  */
> +  int visited;
> +
>   /* Which heap is BB in (if any)?  */
>   fibheap_t heap;
>
> @@ -183,6 +186,29 @@ static void connect_traces (int, struct
>  static bool copy_bb_p (const_basic_block, int);
>  static bool push_to_next_round_p (const_basic_block, int, int, int, gcov_type);
>
> +/* Return the trace number in which BB was visited.  */
> +
> +static int
> +bb_visited_trace (const_basic_block bb)
> +{
> +  gcc_assert (bb->index < array_size);
> +  return bbd[bb->index].visited;
> +}
> +
> +/* This function marks BB that it was visited in trace number TRACE.  */
> +
> +static void
> +mark_bb_visited (basic_block bb, int trace)
> +{
> +  bbd[bb->index].visited = trace;
> +  if (bbd[bb->index].heap)
> +    {
> +      fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
> +      bbd[bb->index].heap = NULL;
> +      bbd[bb->index].node = NULL;
> +    }
> +}
> +
>  /* Check to see if bb should be pushed into the next round of trace
>    collections or not.  Reasons for pushing the block forward are 1).
>    If the block is cold, we are doing partitioning, and there will be
> @@ -306,14 +332,14 @@ rotate_loop (edge back_edge, struct trac
>
>       FOR_EACH_EDGE (e, ei, bb->succs)
>        if (e->dest != EXIT_BLOCK_PTR
> -           && e->dest->il.rtl->visited != trace_n
> +           && bb_visited_trace (e->dest) != trace_n
>            && (e->flags & EDGE_CAN_FALLTHRU)
>            && !(e->flags & EDGE_COMPLEX))
>        {
>          if (is_preferred)
>            {
>              /* The best edge is preferred.  */
> -             if (!e->dest->il.rtl->visited
> +             if (!bb_visited_trace (e->dest)
>                  || bbd[e->dest->index].start_of_trace >= 0)
>                {
>                  /* The current edge E is also preferred.  */
> @@ -329,7 +355,7 @@ rotate_loop (edge back_edge, struct trac
>            }
>          else
>            {
> -             if (!e->dest->il.rtl->visited
> +             if (!bb_visited_trace (e->dest)
>                  || bbd[e->dest->index].start_of_trace >= 0)
>                {
>                  /* The current edge E is preferred.  */
> @@ -397,20 +423,6 @@ rotate_loop (edge back_edge, struct trac
>   return best_bb;
>  }
>
> -/* This function marks BB that it was visited in trace number TRACE.  */
> -
> -static void
> -mark_bb_visited (basic_block bb, int trace)
> -{
> -  bb->il.rtl->visited = trace;
> -  if (bbd[bb->index].heap)
> -    {
> -      fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
> -      bbd[bb->index].heap = NULL;
> -      bbd[bb->index].node = NULL;
> -    }
> -}
> -
>  /* One round of finding traces. Find traces for BRANCH_TH and EXEC_TH i.e. do
>    not include basic blocks their probability is lower than BRANCH_TH or their
>    frequency is lower than EXEC_TH into traces (or count is lower than
> @@ -496,8 +508,8 @@ find_traces_1_round (int branch_th, int
>              if (e->dest == EXIT_BLOCK_PTR)
>                continue;
>
> -             if (e->dest->il.rtl->visited
> -                 && e->dest->il.rtl->visited != *n_traces)
> +             if (bb_visited_trace (e->dest)
> +                 && bb_visited_trace (e->dest) != *n_traces)
>                continue;
>
>              if (BB_PARTITION (e->dest) != BB_PARTITION (bb))
> @@ -550,7 +562,7 @@ find_traces_1_round (int branch_th, int
>            {
>              if (e == best_edge
>                  || e->dest == EXIT_BLOCK_PTR
> -                 || e->dest->il.rtl->visited)
> +                 || bb_visited_trace (e->dest))
>                continue;
>
>              key = bb_to_key (e->dest);
> @@ -611,7 +623,7 @@ find_traces_1_round (int branch_th, int
>
>          if (best_edge) /* Suitable successor was found.  */
>            {
> -             if (best_edge->dest->il.rtl->visited == *n_traces)
> +             if (bb_visited_trace (best_edge->dest) == *n_traces)
>                {
>                  /* We do nothing with one basic block loops.  */
>                  if (best_edge->dest != bb)
> @@ -682,7 +694,7 @@ find_traces_1_round (int branch_th, int
>                    if (e != best_edge
>                        && (e->flags & EDGE_CAN_FALLTHRU)
>                        && !(e->flags & EDGE_COMPLEX)
> -                       && !e->dest->il.rtl->visited
> +                       && !bb_visited_trace (e->dest)
>                        && single_pred_p (e->dest)
>                        && !(e->flags & EDGE_CROSSING)
>                        && single_succ_p (e->dest)
> @@ -716,7 +728,7 @@ find_traces_1_round (int branch_th, int
>       FOR_EACH_EDGE (e, ei, bb->succs)
>        {
>          if (e->dest == EXIT_BLOCK_PTR
> -             || e->dest->il.rtl->visited)
> +             || bb_visited_trace (e->dest))
>            continue;
>
>          if (bbd[e->dest->index].heap)
> @@ -758,15 +770,11 @@ copy_bb (basic_block old_bb, edge e, bas
>   BB_COPY_PARTITION (new_bb, old_bb);
>
>   gcc_assert (e->dest == new_bb);
> -  gcc_assert (!e->dest->il.rtl->visited);
>
>   if (dump_file)
>     fprintf (dump_file,
>             "Duplicated bb %d (created bb %d)\n",
>             old_bb->index, new_bb->index);
> -  new_bb->il.rtl->visited = trace;
> -  new_bb->aux = bb->aux;
> -  bb->aux = new_bb;
>
>   if (new_bb->index >= array_size || last_basic_block > array_size)
>     {
> @@ -779,8 +787,9 @@ copy_bb (basic_block old_bb, edge e, bas
>       for (i = array_size; i < new_size; i++)
>        {
>          bbd[i].start_of_trace = -1;
> -         bbd[i].in_trace = -1;
>          bbd[i].end_of_trace = -1;
> +         bbd[i].in_trace = -1;
> +         bbd[i].visited = 0;
>          bbd[i].heap = NULL;
>          bbd[i].node = NULL;
>        }
> @@ -794,6 +803,11 @@ copy_bb (basic_block old_bb, edge e, bas
>        }
>     }
>
> +  gcc_assert (!bb_visited_trace (e->dest));
> +  mark_bb_visited (new_bb, trace);
> +  new_bb->aux = bb->aux;
> +  bb->aux = new_bb;
> +
>   bbd[new_bb->index].in_trace = trace;
>
>   return new_bb;
> @@ -1214,7 +1228,7 @@ static void
>  emit_barrier_after_bb (basic_block bb)
>  {
>   rtx barrier = emit_barrier_after (BB_END (bb));
> -  bb->il.rtl->footer = unlink_insn_chain (barrier, barrier);
> +  bb->il.x.rtl->footer = unlink_insn_chain (barrier, barrier);
>  }
>
>  /* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
> @@ -1929,8 +1943,9 @@ reorder_basic_blocks (void)
>   for (i = 0; i < array_size; i++)
>     {
>       bbd[i].start_of_trace = -1;
> -      bbd[i].in_trace = -1;
>       bbd[i].end_of_trace = -1;
> +      bbd[i].in_trace = -1;
> +      bbd[i].visited = 0;
>       bbd[i].heap = NULL;
>       bbd[i].node = NULL;
>     }
> @@ -2012,6 +2027,7 @@ duplicate_computed_gotos (void)
>   if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1)
>     return 0;
>
> +  clear_bb_flags ();
>   cfg_layout_initialize (0);
>
>   /* We are estimating the length of uncond jump insn only once
> @@ -2075,10 +2091,10 @@ duplicate_computed_gotos (void)
>   /* Duplicate computed gotos.  */
>   FOR_EACH_BB (bb)
>     {
> -      if (bb->il.rtl->visited)
> +      if (bb->flags & BB_VISITED)
>        continue;
>
> -      bb->il.rtl->visited = 1;
> +      bb->flags |= BB_VISITED;
>
>       /* BB must have one outgoing edge.  That edge must not lead to
>         the exit block or the next block.
> @@ -2096,7 +2112,7 @@ duplicate_computed_gotos (void)
>       new_bb = duplicate_block (single_succ (bb), single_succ_edge (bb), bb);
>       new_bb->aux = bb->aux;
>       bb->aux = new_bb;
> -      new_bb->il.rtl->visited = 1;
> +      new_bb->flags |= BB_VISITED;
>     }
>
>  done:
> Index: basic-block.h
> ===================================================================
> --- basic-block.h       (revision 187099)
> +++ basic-block.h       (working copy)
> @@ -102,17 +102,14 @@ extern const struct gcov_ctr_summary *pr
>  struct loop;
>
>  struct GTY(()) rtl_bb_info {
> -  /* The first and last insns of the block.  */
> -  rtx head_;
> +  /* The first insn of the block is embedded into bb->il.x.  */
> +  /* The last insn of the block.  */
>   rtx end_;
>
>   /* In CFGlayout mode points to insn notes/jumptables to be placed just before
>      and after the block.   */
>   rtx header;
>   rtx footer;
> -
> -  /* This field is used by the bb-reorder pass.  */
> -  int visited;
>  };
>
>  struct GTY(()) gimple_bb_info {
> @@ -169,7 +166,10 @@ struct GTY((chain_next ("%h.next_bb"), c
>
>   union basic_block_il_dependent {
>       struct gimple_bb_info GTY ((tag ("0"))) gimple;
> -      struct rtl_bb_info * GTY ((tag ("1"))) rtl;
> +      struct {
> +        rtx head_;
> +        struct rtl_bb_info * rtl;
> +      } GTY ((tag ("1"))) x;
>     } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
>
>   /* Expected number of executions: calculated in profile.c.  */
> @@ -260,7 +260,10 @@ enum bb_flags
>      df_set_bb_dirty, but not cleared by df_analyze, so it can be used
>      to test whether a block has been modified prior to a df_analyze
>      call.  */
> -  BB_MODIFIED = 1 << 12
> +  BB_MODIFIED = 1 << 12,
> +
> +  /* A general visited flag for passes to use.  */
> +  BB_VISITED = 1 << 13
>  };
>
>  /* Dummy flag for convenience in the hot/cold partitioning code.  */
> @@ -415,8 +418,8 @@ struct GTY(()) control_flow_graph {
>
>  /* Stuff for recording basic block info.  */
>
> -#define BB_HEAD(B)      (B)->il.rtl->head_
> -#define BB_END(B)       (B)->il.rtl->end_
> +#define BB_HEAD(B)      (B)->il.x.head_
> +#define BB_END(B)       (B)->il.x.rtl->end_
>
>  /* Special block numbers [markers] for entry and exit.
>    Neither of them is supposed to hold actual statements.  */
> Index: cfgrtl.c
> ===================================================================
> --- cfgrtl.c    (revision 187098)
> +++ cfgrtl.c    (working copy)
> @@ -837,7 +837,7 @@ try_redirect_by_replacing_jump (edge e,
>       /* Selectively unlink whole insn chain.  */
>       if (in_cfglayout)
>        {
> -         rtx insn = src->il.rtl->footer;
> +         rtx insn = src->il.x.rtl->footer;
>
>          delete_insn_chain (kill_from, BB_END (src), false);
>
> @@ -849,7 +849,7 @@ try_redirect_by_replacing_jump (edge e,
>                  if (PREV_INSN (insn))
>                    NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
>                  else
> -                   src->il.rtl->footer = NEXT_INSN (insn);
> +                   src->il.x.rtl->footer = NEXT_INSN (insn);
>                  if (NEXT_INSN (insn))
>                    PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
>                }
> @@ -1857,7 +1857,7 @@ rtl_verify_flow_info_1 (void)
>            err = 1;
>          }
>
> -      for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
> +      for (insn = bb->il.x.rtl->header; insn; insn = NEXT_INSN (insn))
>        if (!BARRIER_P (insn)
>            && BLOCK_FOR_INSN (insn) != NULL)
>          {
> @@ -1865,7 +1865,7 @@ rtl_verify_flow_info_1 (void)
>                   INSN_UID (insn), bb->index);
>            err = 1;
>          }
> -      for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
> +      for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
>        if (!BARRIER_P (insn)
>            && BLOCK_FOR_INSN (insn) != NULL)
>          {
> @@ -2597,8 +2597,8 @@ cfg_layout_split_block (basic_block bb,
>   rtx insn = (rtx) insnp;
>   basic_block new_bb = rtl_split_block (bb, insn);
>
> -  new_bb->il.rtl->footer = bb->il.rtl->footer;
> -  bb->il.rtl->footer = NULL;
> +  new_bb->il.x.rtl->footer = bb->il.x.rtl->footer;
> +  bb->il.x.rtl->footer = NULL;
>
>   return new_bb;
>  }
> @@ -2703,24 +2703,24 @@ cfg_layout_delete_block (basic_block bb)
>  {
>   rtx insn, next, prev = PREV_INSN (BB_HEAD (bb)), *to, remaints;
>
> -  if (bb->il.rtl->header)
> +  if (bb->il.x.rtl->header)
>     {
>       next = BB_HEAD (bb);
>       if (prev)
> -       NEXT_INSN (prev) = bb->il.rtl->header;
> +       NEXT_INSN (prev) = bb->il.x.rtl->header;
>       else
> -       set_first_insn (bb->il.rtl->header);
> -      PREV_INSN (bb->il.rtl->header) = prev;
> -      insn = bb->il.rtl->header;
> +       set_first_insn (bb->il.x.rtl->header);
> +      PREV_INSN (bb->il.x.rtl->header) = prev;
> +      insn = bb->il.x.rtl->header;
>       while (NEXT_INSN (insn))
>        insn = NEXT_INSN (insn);
>       NEXT_INSN (insn) = next;
>       PREV_INSN (next) = insn;
>     }
>   next = NEXT_INSN (BB_END (bb));
> -  if (bb->il.rtl->footer)
> +  if (bb->il.x.rtl->footer)
>     {
> -      insn = bb->il.rtl->footer;
> +      insn = bb->il.x.rtl->footer;
>       while (insn)
>        {
>          if (BARRIER_P (insn))
> @@ -2728,7 +2728,7 @@ cfg_layout_delete_block (basic_block bb)
>              if (PREV_INSN (insn))
>                NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
>              else
> -               bb->il.rtl->footer = NEXT_INSN (insn);
> +               bb->il.x.rtl->footer = NEXT_INSN (insn);
>              if (NEXT_INSN (insn))
>                PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
>            }
> @@ -2736,11 +2736,11 @@ cfg_layout_delete_block (basic_block bb)
>            break;
>          insn = NEXT_INSN (insn);
>        }
> -      if (bb->il.rtl->footer)
> +      if (bb->il.x.rtl->footer)
>        {
>          insn = BB_END (bb);
> -         NEXT_INSN (insn) = bb->il.rtl->footer;
> -         PREV_INSN (bb->il.rtl->footer) = insn;
> +         NEXT_INSN (insn) = bb->il.x.rtl->footer;
> +         PREV_INSN (bb->il.x.rtl->footer) = insn;
>          while (NEXT_INSN (insn))
>            insn = NEXT_INSN (insn);
>          NEXT_INSN (insn) = next;
> @@ -2751,7 +2751,7 @@ cfg_layout_delete_block (basic_block bb)
>        }
>     }
>   if (bb->next_bb != EXIT_BLOCK_PTR)
> -    to = &bb->next_bb->il.rtl->header;
> +    to = &bb->next_bb->il.x.rtl->header;
>   else
>     to = &cfg_layout_function_footer;
>
> @@ -2882,18 +2882,18 @@ cfg_layout_merge_blocks (basic_block a,
>     }
>
>   /* Possible line number notes should appear in between.  */
> -  if (b->il.rtl->header)
> +  if (b->il.x.rtl->header)
>     {
>       rtx first = BB_END (a), last;
>
> -      last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
> +      last = emit_insn_after_noloc (b->il.x.rtl->header, BB_END (a), a);
>       /* The above might add a BARRIER as BB_END, but as barriers
>         aren't valid parts of a bb, remove_insn doesn't update
>         BB_END if it is a barrier.  So adjust BB_END here.  */
>       while (BB_END (a) != first && BARRIER_P (BB_END (a)))
>        BB_END (a) = PREV_INSN (BB_END (a));
>       delete_insn_chain (NEXT_INSN (first), last, false);
> -      b->il.rtl->header = NULL;
> +      b->il.x.rtl->header = NULL;
>     }
>
>   /* In the case basic blocks are not adjacent, move them around.  */
> @@ -2924,20 +2924,20 @@ cfg_layout_merge_blocks (basic_block a,
>   df_bb_delete (b->index);
>
>   /* Possible tablejumps and barriers should appear after the block.  */
> -  if (b->il.rtl->footer)
> +  if (b->il.x.rtl->footer)
>     {
> -      if (!a->il.rtl->footer)
> -       a->il.rtl->footer = b->il.rtl->footer;
> +      if (!a->il.x.rtl->footer)
> +       a->il.x.rtl->footer = b->il.x.rtl->footer;
>       else
>        {
> -         rtx last = a->il.rtl->footer;
> +         rtx last = a->il.x.rtl->footer;
>
>          while (NEXT_INSN (last))
>            last = NEXT_INSN (last);
> -         NEXT_INSN (last) = b->il.rtl->footer;
> -         PREV_INSN (b->il.rtl->footer) = last;
> +         NEXT_INSN (last) = b->il.x.rtl->footer;
> +         PREV_INSN (b->il.x.rtl->footer) = last;
>        }
> -      b->il.rtl->footer = NULL;
> +      b->il.x.rtl->footer = NULL;
>     }
>
>   /* If B was a forwarder block, propagate the locus on the edge.  */
> @@ -3211,8 +3211,9 @@ rtl_extract_cond_bb_edges (basic_block b
>  void
>  init_rtl_bb_info (basic_block bb)
>  {
> -  gcc_assert (!bb->il.rtl);
> -  bb->il.rtl = ggc_alloc_cleared_rtl_bb_info ();
> +  gcc_assert (!bb->il.x.rtl);
> +  bb->il.x.head_ = NULL;
> +  bb->il.x.rtl = ggc_alloc_cleared_rtl_bb_info ();
>  }
>
>  /* Returns true if it is possible to remove edge E by redirecting

Patch

Index: jump.c
===================================================================
--- jump.c	(revision 187098)
+++ jump.c	(working copy)
@@ -275,13 +275,13 @@  mark_all_labels (rtx f)
 	  /* In cfglayout mode, there may be non-insns between the
 	     basic blocks.  If those non-insns represent tablejump data,
 	     they contain label references that we must record.  */
-	  for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
+	  for (insn = bb->il.x.rtl->header; insn; insn = NEXT_INSN (insn))
 	    if (INSN_P (insn))
 	      {
 		gcc_assert (JUMP_TABLE_DATA_P (insn));
 		mark_jump_label (PATTERN (insn), insn, 0);
 	      }
-	  for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
+	  for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
 	    if (INSN_P (insn))
 	      {
 		gcc_assert (JUMP_TABLE_DATA_P (insn));
Index: cfgcleanup.c
===================================================================
--- cfgcleanup.c	(revision 187098)
+++ cfgcleanup.c	(working copy)
@@ -2586,21 +2586,21 @@  try_optimize_cfg (int mode)
 
 		      if (current_ir_type () == IR_RTL_CFGLAYOUT)
 			{
-			  if (b->il.rtl->footer
-			      && BARRIER_P (b->il.rtl->footer))
+			  if (b->il.x.rtl->footer
+			      && BARRIER_P (b->il.x.rtl->footer))
 			    FOR_EACH_EDGE (e, ei, b->preds)
 			      if ((e->flags & EDGE_FALLTHRU)
-				  && e->src->il.rtl->footer == NULL)
+				  && e->src->il.x.rtl->footer == NULL)
 				{
-				  if (b->il.rtl->footer)
+				  if (b->il.x.rtl->footer)
 				    {
-				      e->src->il.rtl->footer = b->il.rtl->footer;
-				      b->il.rtl->footer = NULL;
+				      e->src->il.x.rtl->footer = b->il.x.rtl->footer;
+				      b->il.x.rtl->footer = NULL;
 				    }
 				  else
 				    {
 				      start_sequence ();
-				      e->src->il.rtl->footer = emit_barrier ();
+				      e->src->il.x.rtl->footer = emit_barrier ();
 				      end_sequence ();
 				    }
 				}
Index: cfglayout.c
===================================================================
--- cfglayout.c	(revision 187098)
+++ cfglayout.c	(working copy)
@@ -208,11 +208,11 @@  record_effective_endpoints (void)
       rtx end;
 
       if (PREV_INSN (BB_HEAD (bb)) && next_insn != BB_HEAD (bb))
-	bb->il.rtl->header = unlink_insn_chain (next_insn,
+	bb->il.x.rtl->header = unlink_insn_chain (next_insn,
 					      PREV_INSN (BB_HEAD (bb)));
       end = skip_insns_after_block (bb);
       if (NEXT_INSN (BB_END (bb)) && BB_END (bb) != end)
-	bb->il.rtl->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
+	bb->il.x.rtl->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
       next_insn = NEXT_INSN (BB_END (bb));
     }
 
@@ -633,9 +633,8 @@  reemit_insn_block_notes (void)
 
 
 /* Link the basic blocks in the correct order, compacting the basic
-   block queue while at it.  This also clears the visited flag on
-   all basic blocks.  If STAY_IN_CFGLAYOUT_MODE is false, this function
-   also clears the basic block header and footer fields.
+   block queue while at it.  If STAY_IN_CFGLAYOUT_MODE is false, this
+   function also clears the basic block header and footer fields.
 
    This function is usually called after a pass (e.g. tracer) finishes
    some transformations while in cfglayout mode.  The required sequence
@@ -681,13 +680,12 @@  relink_block_chain (bool stay_in_cfglayo
   prev_bb->next_bb = EXIT_BLOCK_PTR;
   EXIT_BLOCK_PTR->prev_bb = prev_bb;
 
-  /* Then, clean up the aux and visited fields.  */
+  /* Then, clean up the aux fields.  */
   FOR_ALL_BB (bb)
     {
       bb->aux = NULL;
-      bb->il.rtl->visited = 0;
       if (!stay_in_cfglayout_mode)
-	bb->il.rtl->header = bb->il.rtl->footer = NULL;
+	bb->il.x.rtl->header = bb->il.x.rtl->footer = NULL;
     }
 
   /* Maybe reset the original copy tables, they are not valid anymore
@@ -723,14 +721,14 @@  fixup_reorder_chain (void)
 
   for (bb = ENTRY_BLOCK_PTR->next_bb; bb; bb = (basic_block) bb->aux)
     {
-      if (bb->il.rtl->header)
+      if (bb->il.x.rtl->header)
 	{
 	  if (insn)
-	    NEXT_INSN (insn) = bb->il.rtl->header;
+	    NEXT_INSN (insn) = bb->il.x.rtl->header;
 	  else
-	    set_first_insn (bb->il.rtl->header);
-	  PREV_INSN (bb->il.rtl->header) = insn;
-	  insn = bb->il.rtl->header;
+	    set_first_insn (bb->il.x.rtl->header);
+	  PREV_INSN (bb->il.x.rtl->header) = insn;
+	  insn = bb->il.x.rtl->header;
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
 	}
@@ -740,10 +738,10 @@  fixup_reorder_chain (void)
 	set_first_insn (BB_HEAD (bb));
       PREV_INSN (BB_HEAD (bb)) = insn;
       insn = BB_END (bb);
-      if (bb->il.rtl->footer)
+      if (bb->il.x.rtl->footer)
 	{
-	  NEXT_INSN (insn) = bb->il.rtl->footer;
-	  PREV_INSN (bb->il.rtl->footer) = insn;
+	  NEXT_INSN (insn) = bb->il.x.rtl->footer;
+	  PREV_INSN (bb->il.x.rtl->footer) = insn;
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
 	}
@@ -799,7 +797,7 @@  fixup_reorder_chain (void)
 		{
 		  gcc_assert (!onlyjump_p (bb_end_insn)
 			      || returnjump_p (bb_end_insn));
-		  bb->il.rtl->footer = emit_barrier_after (bb_end_insn);
+		  bb->il.x.rtl->footer = emit_barrier_after (bb_end_insn);
 		  continue;
 		}
 
@@ -908,7 +906,6 @@  fixup_reorder_chain (void)
       nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
       if (nb)
 	{
-	  nb->il.rtl->visited = 1;
 	  nb->aux = bb->aux;
 	  bb->aux = nb;
 	  /* Don't process this new block.  */
@@ -1062,8 +1059,8 @@  fixup_fallthru_exit_predecessor (void)
 	  bb = split_block (bb, NULL)->dest;
 	  bb->aux = c->aux;
 	  c->aux = bb;
-	  bb->il.rtl->footer = c->il.rtl->footer;
-	  c->il.rtl->footer = NULL;
+	  bb->il.x.rtl->footer = c->il.x.rtl->footer;
+	  c->il.x.rtl->footer = NULL;
 	}
 
       while (c->aux != bb)
@@ -1272,24 +1269,24 @@  cfg_layout_duplicate_bb (basic_block bb)
 			       EXIT_BLOCK_PTR->prev_bb);
 
   BB_COPY_PARTITION (new_bb, bb);
-  if (bb->il.rtl->header)
+  if (bb->il.x.rtl->header)
     {
-      insn = bb->il.rtl->header;
+      insn = bb->il.x.rtl->header;
       while (NEXT_INSN (insn))
 	insn = NEXT_INSN (insn);
-      insn = duplicate_insn_chain (bb->il.rtl->header, insn);
+      insn = duplicate_insn_chain (bb->il.x.rtl->header, insn);
       if (insn)
-	new_bb->il.rtl->header = unlink_insn_chain (insn, get_last_insn ());
+	new_bb->il.x.rtl->header = unlink_insn_chain (insn, get_last_insn ());
     }
 
-  if (bb->il.rtl->footer)
+  if (bb->il.x.rtl->footer)
     {
-      insn = bb->il.rtl->footer;
+      insn = bb->il.x.rtl->footer;
       while (NEXT_INSN (insn))
 	insn = NEXT_INSN (insn);
-      insn = duplicate_insn_chain (bb->il.rtl->footer, insn);
+      insn = duplicate_insn_chain (bb->il.x.rtl->footer, insn);
       if (insn)
-	new_bb->il.rtl->footer = unlink_insn_chain (insn, get_last_insn ());
+	new_bb->il.x.rtl->footer = unlink_insn_chain (insn, get_last_insn ());
     }
 
   return new_bb;
Index: combine.c
===================================================================
--- combine.c	(revision 187098)
+++ combine.c	(working copy)
@@ -2536,13 +2536,13 @@  update_cfg_for_uncondjump (rtx insn)
       single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
 
       /* Remove barriers from the footer if there are any.  */
-      for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
+      for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
 	if (BARRIER_P (insn))
 	  {
 	    if (PREV_INSN (insn))
 	      NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
 	    else
-	      bb->il.rtl->footer = NEXT_INSN (insn);
+	      bb->il.x.rtl->footer = NEXT_INSN (insn);
 	    if (NEXT_INSN (insn))
 	      PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
 	  }
Index: bb-reorder.c
===================================================================
--- bb-reorder.c	(revision 187098)
+++ bb-reorder.c	(working copy)
@@ -133,6 +133,9 @@  typedef struct bbro_basic_block_data_def
   /* Which trace is the bb in?  */
   int in_trace;
 
+  /* Which trace was this bb visited in?  */
+  int visited;
+
   /* Which heap is BB in (if any)?  */
   fibheap_t heap;
 
@@ -183,6 +186,29 @@  static void connect_traces (int, struct
 static bool copy_bb_p (const_basic_block, int);
 static bool push_to_next_round_p (const_basic_block, int, int, int, gcov_type);
 
+/* Return the trace number in which BB was visited.  */
+
+static int
+bb_visited_trace (const_basic_block bb)
+{
+  gcc_assert (bb->index < array_size);
+  return bbd[bb->index].visited;
+}
+
+/* This function marks BB that it was visited in trace number TRACE.  */
+
+static void
+mark_bb_visited (basic_block bb, int trace)
+{
+  bbd[bb->index].visited = trace;
+  if (bbd[bb->index].heap)
+    {
+      fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
+      bbd[bb->index].heap = NULL;
+      bbd[bb->index].node = NULL;
+    }
+}
+
 /* Check to see if bb should be pushed into the next round of trace
    collections or not.  Reasons for pushing the block forward are 1).
    If the block is cold, we are doing partitioning, and there will be
@@ -306,14 +332,14 @@  rotate_loop (edge back_edge, struct trac
 
       FOR_EACH_EDGE (e, ei, bb->succs)
 	if (e->dest != EXIT_BLOCK_PTR
-	    && e->dest->il.rtl->visited != trace_n
+	    && bb_visited_trace (e->dest) != trace_n
 	    && (e->flags & EDGE_CAN_FALLTHRU)
 	    && !(e->flags & EDGE_COMPLEX))
 	{
 	  if (is_preferred)
 	    {
 	      /* The best edge is preferred.  */
-	      if (!e->dest->il.rtl->visited
+	      if (!bb_visited_trace (e->dest)
 		  || bbd[e->dest->index].start_of_trace >= 0)
 		{
 		  /* The current edge E is also preferred.  */
@@ -329,7 +355,7 @@  rotate_loop (edge back_edge, struct trac
 	    }
 	  else
 	    {
-	      if (!e->dest->il.rtl->visited
+	      if (!bb_visited_trace (e->dest)
 		  || bbd[e->dest->index].start_of_trace >= 0)
 		{
 		  /* The current edge E is preferred.  */
@@ -397,20 +423,6 @@  rotate_loop (edge back_edge, struct trac
   return best_bb;
 }
 
-/* This function marks BB that it was visited in trace number TRACE.  */
-
-static void
-mark_bb_visited (basic_block bb, int trace)
-{
-  bb->il.rtl->visited = trace;
-  if (bbd[bb->index].heap)
-    {
-      fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
-      bbd[bb->index].heap = NULL;
-      bbd[bb->index].node = NULL;
-    }
-}
-
 /* One round of finding traces. Find traces for BRANCH_TH and EXEC_TH i.e. do
    not include basic blocks their probability is lower than BRANCH_TH or their
    frequency is lower than EXEC_TH into traces (or count is lower than
@@ -496,8 +508,8 @@  find_traces_1_round (int branch_th, int
 	      if (e->dest == EXIT_BLOCK_PTR)
 		continue;
 
-	      if (e->dest->il.rtl->visited
-		  && e->dest->il.rtl->visited != *n_traces)
+	      if (bb_visited_trace (e->dest)
+		  && bb_visited_trace (e->dest) != *n_traces)
 		continue;
 
 	      if (BB_PARTITION (e->dest) != BB_PARTITION (bb))
@@ -550,7 +562,7 @@  find_traces_1_round (int branch_th, int
 	    {
 	      if (e == best_edge
 		  || e->dest == EXIT_BLOCK_PTR
-		  || e->dest->il.rtl->visited)
+		  || bb_visited_trace (e->dest))
 		continue;
 
 	      key = bb_to_key (e->dest);
@@ -611,7 +623,7 @@  find_traces_1_round (int branch_th, int
 
 	  if (best_edge) /* Suitable successor was found.  */
 	    {
-	      if (best_edge->dest->il.rtl->visited == *n_traces)
+	      if (bb_visited_trace (best_edge->dest) == *n_traces)
 		{
 		  /* We do nothing with one basic block loops.  */
 		  if (best_edge->dest != bb)
@@ -682,7 +694,7 @@  find_traces_1_round (int branch_th, int
 		    if (e != best_edge
 			&& (e->flags & EDGE_CAN_FALLTHRU)
 			&& !(e->flags & EDGE_COMPLEX)
-			&& !e->dest->il.rtl->visited
+			&& !bb_visited_trace (e->dest)
 			&& single_pred_p (e->dest)
 			&& !(e->flags & EDGE_CROSSING)
 			&& single_succ_p (e->dest)
@@ -716,7 +728,7 @@  find_traces_1_round (int branch_th, int
       FOR_EACH_EDGE (e, ei, bb->succs)
 	{
 	  if (e->dest == EXIT_BLOCK_PTR
-	      || e->dest->il.rtl->visited)
+	      || bb_visited_trace (e->dest))
 	    continue;
 
 	  if (bbd[e->dest->index].heap)
@@ -758,15 +770,11 @@  copy_bb (basic_block old_bb, edge e, bas
   BB_COPY_PARTITION (new_bb, old_bb);
 
   gcc_assert (e->dest == new_bb);
-  gcc_assert (!e->dest->il.rtl->visited);
 
   if (dump_file)
     fprintf (dump_file,
 	     "Duplicated bb %d (created bb %d)\n",
 	     old_bb->index, new_bb->index);
-  new_bb->il.rtl->visited = trace;
-  new_bb->aux = bb->aux;
-  bb->aux = new_bb;
 
   if (new_bb->index >= array_size || last_basic_block > array_size)
     {
@@ -779,8 +787,9 @@  copy_bb (basic_block old_bb, edge e, bas
       for (i = array_size; i < new_size; i++)
 	{
 	  bbd[i].start_of_trace = -1;
-	  bbd[i].in_trace = -1;
 	  bbd[i].end_of_trace = -1;
+	  bbd[i].in_trace = -1;
+	  bbd[i].visited = 0;
 	  bbd[i].heap = NULL;
 	  bbd[i].node = NULL;
 	}
@@ -794,6 +803,11 @@  copy_bb (basic_block old_bb, edge e, bas
 	}
     }
 
+  gcc_assert (!bb_visited_trace (e->dest));
+  mark_bb_visited (new_bb, trace);
+  new_bb->aux = bb->aux;
+  bb->aux = new_bb;
+
   bbd[new_bb->index].in_trace = trace;
 
   return new_bb;
@@ -1214,7 +1228,7 @@  static void
 emit_barrier_after_bb (basic_block bb)
 {
   rtx barrier = emit_barrier_after (BB_END (bb));
-  bb->il.rtl->footer = unlink_insn_chain (barrier, barrier);
+  bb->il.x.rtl->footer = unlink_insn_chain (barrier, barrier);
 }
 
 /* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
@@ -1929,8 +1943,9 @@  reorder_basic_blocks (void)
   for (i = 0; i < array_size; i++)
     {
       bbd[i].start_of_trace = -1;
-      bbd[i].in_trace = -1;
       bbd[i].end_of_trace = -1;
+      bbd[i].in_trace = -1;
+      bbd[i].visited = 0;
       bbd[i].heap = NULL;
       bbd[i].node = NULL;
     }
@@ -2012,6 +2027,7 @@  duplicate_computed_gotos (void)
   if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1)
     return 0;
 
+  clear_bb_flags ();
   cfg_layout_initialize (0);
 
   /* We are estimating the length of uncond jump insn only once
@@ -2075,10 +2091,10 @@  duplicate_computed_gotos (void)
   /* Duplicate computed gotos.  */
   FOR_EACH_BB (bb)
     {
-      if (bb->il.rtl->visited)
+      if (bb->flags & BB_VISITED)
 	continue;
 
-      bb->il.rtl->visited = 1;
+      bb->flags |= BB_VISITED;
 
       /* BB must have one outgoing edge.  That edge must not lead to
 	 the exit block or the next block.
@@ -2096,7 +2112,7 @@  duplicate_computed_gotos (void)
       new_bb = duplicate_block (single_succ (bb), single_succ_edge (bb), bb);
       new_bb->aux = bb->aux;
       bb->aux = new_bb;
-      new_bb->il.rtl->visited = 1;
+      new_bb->flags |= BB_VISITED;
     }
 
 done:
Index: basic-block.h
===================================================================
--- basic-block.h	(revision 187099)
+++ basic-block.h	(working copy)
@@ -102,17 +102,14 @@  extern const struct gcov_ctr_summary *pr
 struct loop;
 
 struct GTY(()) rtl_bb_info {
-  /* The first and last insns of the block.  */
-  rtx head_;
+  /* The first insn of the block is embedded into bb->il.x.  */
+  /* The last insn of the block.  */
   rtx end_;
 
   /* In CFGlayout mode points to insn notes/jumptables to be placed just before
      and after the block.   */
   rtx header;
   rtx footer;
-
-  /* This field is used by the bb-reorder pass.  */
-  int visited;
 };
 
 struct GTY(()) gimple_bb_info {
@@ -169,7 +166,10 @@  struct GTY((chain_next ("%h.next_bb"), c
 
   union basic_block_il_dependent {
       struct gimple_bb_info GTY ((tag ("0"))) gimple;
-      struct rtl_bb_info * GTY ((tag ("1"))) rtl;
+      struct {
+        rtx head_;
+        struct rtl_bb_info * rtl;
+      } GTY ((tag ("1"))) x;
     } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
 
   /* Expected number of executions: calculated in profile.c.  */
@@ -260,7 +260,10 @@  enum bb_flags
      df_set_bb_dirty, but not cleared by df_analyze, so it can be used
      to test whether a block has been modified prior to a df_analyze
      call.  */
-  BB_MODIFIED = 1 << 12
+  BB_MODIFIED = 1 << 12,
+
+  /* A general visited flag for passes to use.  */
+  BB_VISITED = 1 << 13
 };
 
 /* Dummy flag for convenience in the hot/cold partitioning code.  */
@@ -415,8 +418,8 @@  struct GTY(()) control_flow_graph {
 
 /* Stuff for recording basic block info.  */
 
-#define BB_HEAD(B)      (B)->il.rtl->head_
-#define BB_END(B)       (B)->il.rtl->end_
+#define BB_HEAD(B)      (B)->il.x.head_
+#define BB_END(B)       (B)->il.x.rtl->end_
 
 /* Special block numbers [markers] for entry and exit.
    Neither of them is supposed to hold actual statements.  */
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 187098)
+++ cfgrtl.c	(working copy)
@@ -837,7 +837,7 @@  try_redirect_by_replacing_jump (edge e,
       /* Selectively unlink whole insn chain.  */
       if (in_cfglayout)
 	{
-	  rtx insn = src->il.rtl->footer;
+	  rtx insn = src->il.x.rtl->footer;
 
 	  delete_insn_chain (kill_from, BB_END (src), false);
 
@@ -849,7 +849,7 @@  try_redirect_by_replacing_jump (edge e,
 		  if (PREV_INSN (insn))
 		    NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
 		  else
-		    src->il.rtl->footer = NEXT_INSN (insn);
+		    src->il.x.rtl->footer = NEXT_INSN (insn);
 		  if (NEXT_INSN (insn))
 		    PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
 		}
@@ -1857,7 +1857,7 @@  rtl_verify_flow_info_1 (void)
 	    err = 1;
 	  }
 
-      for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
+      for (insn = bb->il.x.rtl->header; insn; insn = NEXT_INSN (insn))
 	if (!BARRIER_P (insn)
 	    && BLOCK_FOR_INSN (insn) != NULL)
 	  {
@@ -1865,7 +1865,7 @@  rtl_verify_flow_info_1 (void)
 		   INSN_UID (insn), bb->index);
 	    err = 1;
 	  }
-      for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
+      for (insn = bb->il.x.rtl->footer; insn; insn = NEXT_INSN (insn))
 	if (!BARRIER_P (insn)
 	    && BLOCK_FOR_INSN (insn) != NULL)
 	  {
@@ -2597,8 +2597,8 @@  cfg_layout_split_block (basic_block bb,
   rtx insn = (rtx) insnp;
   basic_block new_bb = rtl_split_block (bb, insn);
 
-  new_bb->il.rtl->footer = bb->il.rtl->footer;
-  bb->il.rtl->footer = NULL;
+  new_bb->il.x.rtl->footer = bb->il.x.rtl->footer;
+  bb->il.x.rtl->footer = NULL;
 
   return new_bb;
 }
@@ -2703,24 +2703,24 @@  cfg_layout_delete_block (basic_block bb)
 {
   rtx insn, next, prev = PREV_INSN (BB_HEAD (bb)), *to, remaints;
 
-  if (bb->il.rtl->header)
+  if (bb->il.x.rtl->header)
     {
       next = BB_HEAD (bb);
       if (prev)
-	NEXT_INSN (prev) = bb->il.rtl->header;
+	NEXT_INSN (prev) = bb->il.x.rtl->header;
       else
-	set_first_insn (bb->il.rtl->header);
-      PREV_INSN (bb->il.rtl->header) = prev;
-      insn = bb->il.rtl->header;
+	set_first_insn (bb->il.x.rtl->header);
+      PREV_INSN (bb->il.x.rtl->header) = prev;
+      insn = bb->il.x.rtl->header;
       while (NEXT_INSN (insn))
 	insn = NEXT_INSN (insn);
       NEXT_INSN (insn) = next;
       PREV_INSN (next) = insn;
     }
   next = NEXT_INSN (BB_END (bb));
-  if (bb->il.rtl->footer)
+  if (bb->il.x.rtl->footer)
     {
-      insn = bb->il.rtl->footer;
+      insn = bb->il.x.rtl->footer;
       while (insn)
 	{
 	  if (BARRIER_P (insn))
@@ -2728,7 +2728,7 @@  cfg_layout_delete_block (basic_block bb)
 	      if (PREV_INSN (insn))
 		NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
 	      else
-		bb->il.rtl->footer = NEXT_INSN (insn);
+		bb->il.x.rtl->footer = NEXT_INSN (insn);
 	      if (NEXT_INSN (insn))
 		PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
 	    }
@@ -2736,11 +2736,11 @@  cfg_layout_delete_block (basic_block bb)
 	    break;
 	  insn = NEXT_INSN (insn);
 	}
-      if (bb->il.rtl->footer)
+      if (bb->il.x.rtl->footer)
 	{
 	  insn = BB_END (bb);
-	  NEXT_INSN (insn) = bb->il.rtl->footer;
-	  PREV_INSN (bb->il.rtl->footer) = insn;
+	  NEXT_INSN (insn) = bb->il.x.rtl->footer;
+	  PREV_INSN (bb->il.x.rtl->footer) = insn;
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
 	  NEXT_INSN (insn) = next;
@@ -2751,7 +2751,7 @@  cfg_layout_delete_block (basic_block bb)
 	}
     }
   if (bb->next_bb != EXIT_BLOCK_PTR)
-    to = &bb->next_bb->il.rtl->header;
+    to = &bb->next_bb->il.x.rtl->header;
   else
     to = &cfg_layout_function_footer;
 
@@ -2882,18 +2882,18 @@  cfg_layout_merge_blocks (basic_block a,
     }
 
   /* Possible line number notes should appear in between.  */
-  if (b->il.rtl->header)
+  if (b->il.x.rtl->header)
     {
       rtx first = BB_END (a), last;
 
-      last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
+      last = emit_insn_after_noloc (b->il.x.rtl->header, BB_END (a), a);
       /* The above might add a BARRIER as BB_END, but as barriers
 	 aren't valid parts of a bb, remove_insn doesn't update
 	 BB_END if it is a barrier.  So adjust BB_END here.  */
       while (BB_END (a) != first && BARRIER_P (BB_END (a)))
 	BB_END (a) = PREV_INSN (BB_END (a));
       delete_insn_chain (NEXT_INSN (first), last, false);
-      b->il.rtl->header = NULL;
+      b->il.x.rtl->header = NULL;
     }
 
   /* In the case basic blocks are not adjacent, move them around.  */
@@ -2924,20 +2924,20 @@  cfg_layout_merge_blocks (basic_block a,
   df_bb_delete (b->index);
 
   /* Possible tablejumps and barriers should appear after the block.  */
-  if (b->il.rtl->footer)
+  if (b->il.x.rtl->footer)
     {
-      if (!a->il.rtl->footer)
-	a->il.rtl->footer = b->il.rtl->footer;
+      if (!a->il.x.rtl->footer)
+	a->il.x.rtl->footer = b->il.x.rtl->footer;
       else
 	{
-	  rtx last = a->il.rtl->footer;
+	  rtx last = a->il.x.rtl->footer;
 
 	  while (NEXT_INSN (last))
 	    last = NEXT_INSN (last);
-	  NEXT_INSN (last) = b->il.rtl->footer;
-	  PREV_INSN (b->il.rtl->footer) = last;
+	  NEXT_INSN (last) = b->il.x.rtl->footer;
+	  PREV_INSN (b->il.x.rtl->footer) = last;
 	}
-      b->il.rtl->footer = NULL;
+      b->il.x.rtl->footer = NULL;
     }
 
   /* If B was a forwarder block, propagate the locus on the edge.  */
@@ -3211,8 +3211,9 @@  rtl_extract_cond_bb_edges (basic_block b
 void
 init_rtl_bb_info (basic_block bb)
 {
-  gcc_assert (!bb->il.rtl);
-  bb->il.rtl = ggc_alloc_cleared_rtl_bb_info ();
+  gcc_assert (!bb->il.x.rtl);
+  bb->il.x.head_ = NULL;
+  bb->il.x.rtl = ggc_alloc_cleared_rtl_bb_info ();
 }
 
 /* Returns true if it is possible to remove edge E by redirecting