03/03: Keep dominance info up to date

Andrey Belevantsev abel@ispras.ru
Fri Oct 22 08:56:00 GMT 2010


Ping.  http://gcc.gnu.org/ml/gcc-patches/2010-10/msg00206.html
Andrey

On 04.10.2010 19:45, Andrey Belevantsev wrote:
> Hello,
>
> This main patch uses set_immediate_dominator and iterate_fix_dominators
> when updating control flow in selective scheduler. The difficulty I had is
> that when an unreachable block may be created, you need to defer the update
> until the block is removed, so sometimes we avoid updating dominance info
> in sel_redirect_edge_and_branch and postpone it to maybe_tidy_empty_bb
> instead. I will add testcase from PR 43603, and I need to minimize one from
> PR 44233.
>
> Bootstrapped with the other two patches, testing is in progress. Ok for
> trunk if it succeeds? Ok for 4.5/4.4 after a week or two?
>
> Andrey
>
> 2010-10-04 Andrey Belevantsev <abel@ispras.ru>
>
> PR target/43603
> PR target/44233
>
> * haifa-sched.c (sched_create_recovery_edges): Update
> dominator info.
> * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info
> after deleting an empty block.
> (sel_remove_bb): Update dominator info after removing a block.
> (sel_redirect_edge_and_branch_force): Assert that no unreachable
> blocks will be created. Update dominator info.
> (sel_redirect_edge_and_branch): Update dominator info when
> basic blocks do not become unreachable.
> (sel_remove_loop_preheader): Update dominator info.
>
>
> 03-update.diff
>
>
> diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
> index 8d7149f..6bf526e 100644
> --- a/gcc/haifa-sched.c
> +++ b/gcc/haifa-sched.c
> @@ -4452,6 +4452,8 @@ sched_create_recovery_edges (basic_block first_bb, basic_block rec,
>       edge_flags = 0;
>
>     make_single_succ_edge (rec, second_bb, edge_flags);
> +  if (dom_info_available_p (CDI_DOMINATORS))
> +    set_immediate_dominator (CDI_DOMINATORS, rec, first_bb);
>   }
>
>   /* This function creates recovery code for INSN.  If MUTATE_P is nonzero,
> diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
> index 3146a26..72b4892 100644
> --- a/gcc/sel-sched-ir.c
> +++ b/gcc/sel-sched-ir.c
> @@ -3544,6 +3544,7 @@ static bool
>   maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
>   {
>     basic_block succ_bb, pred_bb;
> +  VEC (basic_block, heap) *dom_bbs;
>     edge e;
>     edge_iterator ei;
>     bool rescan_p;
> @@ -3579,6 +3580,7 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
>     succ_bb = single_succ (bb);
>     rescan_p = true;
>     pred_bb = NULL;
> +  dom_bbs = NULL;
>
>     /* Redirect all non-fallthru edges to the next bb.  */
>     while (rescan_p)
> @@ -3591,6 +3593,12 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
>
>             if (!(e->flags&  EDGE_FALLTHRU))
>               {
> +              /* We will update dominators here only when we'll get
> +                 an unreachable block when redirecting, otherwise
> +                 sel_redirect_edge_and_branch will take care of it.  */
> +              if (e->dest != bb
> +&&  single_pred_p (e->dest))
> +                VEC_safe_push (basic_block, heap, dom_bbs, e->dest);
>                 recompute_toporder_p |= sel_redirect_edge_and_branch (e, succ_bb);
>                 rescan_p = true;
>                 break;
> @@ -3610,11 +3618,20 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p)
>         remove_empty_bb (bb, true);
>       }
>
> +
> +  if (!VEC_empty (basic_block, dom_bbs))
> +    {
> +      VEC_safe_push (basic_block, heap, dom_bbs, succ_bb);
> +      iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, false);
> +      VEC_free (basic_block, heap, dom_bbs);
> +    }
> +
>     if (recompute_toporder_p)
>       sel_recompute_toporder ();
>
>   #ifdef ENABLE_CHECKING
>     verify_backedges ();
> +  verify_dominators (CDI_DOMINATORS);
>   #endif
>
>     return true;
> @@ -5026,7 +5043,12 @@ sel_remove_bb (basic_block bb, bool remove_from_cfg_p)
>     bitmap_clear_bit (blocks_to_reschedule, idx);
>
>     if (remove_from_cfg_p)
> -    delete_and_free_basic_block (bb);
> +    {
> +      basic_block succ = single_succ (bb);
> +      delete_and_free_basic_block (bb);
> +      set_immediate_dominator (CDI_DOMINATORS, succ,
> +                               recompute_dominator (CDI_DOMINATORS, succ));
> +    }
>
>     rgn_setup_region (CONTAINING_RGN (idx));
>   }
> @@ -5361,12 +5383,15 @@ sel_merge_blocks (basic_block a, basic_block b)
>   void
>   sel_redirect_edge_and_branch_force (edge e, basic_block to)
>   {
> -  basic_block jump_bb, src;
> +  basic_block jump_bb, src, orig_dest = e->dest;
>     int prev_max_uid;
>     rtx jump;
>
> -  gcc_assert (!sel_bb_empty_p (e->src));
> -
> +  /* This function is now used only for bookkeeping code creation, where
> +     we'll never get the single pred of orig_dest block and thus will not
> +     hit unreachable blocks when updating dominator info.  */
> +  gcc_assert (!sel_bb_empty_p (e->src)
> +&&  !single_pred_p (orig_dest));
>     src = e->src;
>     prev_max_uid = get_max_uid ();
>     jump_bb = redirect_edge_and_branch_force (e, to);
> @@ -5383,6 +5408,10 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to)
>     jump = find_new_jump (src, jump_bb, prev_max_uid);
>     if (jump)
>       sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
> +  set_immediate_dominator (CDI_DOMINATORS, to,
> +			   recompute_dominator (CDI_DOMINATORS, to));
> +  set_immediate_dominator (CDI_DOMINATORS, orig_dest,
> +			   recompute_dominator (CDI_DOMINATORS, orig_dest));
>   }
>
>   /* A wrapper for redirect_edge_and_branch.  Return TRUE if blocks connected by
> @@ -5391,11 +5420,12 @@ bool
>   sel_redirect_edge_and_branch (edge e, basic_block to)
>   {
>     bool latch_edge_p;
> -  basic_block src;
> +  basic_block src, orig_dest = e->dest;
>     int prev_max_uid;
>     rtx jump;
>     edge redirected;
>     bool recompute_toporder_p = false;
> +  bool maybe_unreachable = single_pred_p (orig_dest);
>
>     latch_edge_p = (pipelining_p
>                     &&  current_loop_nest
> @@ -5426,6 +5456,15 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
>     if (jump)
>       sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
>
> +  /* Only update dominator info when we don't have unreachable blocks.
> +     Otherwise we'll update in maybe_tidy_empty_bb.  */
> +  if (!maybe_unreachable)
> +    {
> +      set_immediate_dominator (CDI_DOMINATORS, to,
> +                               recompute_dominator (CDI_DOMINATORS, to));
> +      set_immediate_dominator (CDI_DOMINATORS, orig_dest,
> +                               recompute_dominator (CDI_DOMINATORS, orig_dest));
> +    }
>     return recompute_toporder_p;
>   }
>
> @@ -6155,6 +6194,10 @@ sel_remove_loop_preheader (void)
>                     if (BB_END (prev_bb) == bb_note (prev_bb))
>                       free_data_sets (prev_bb);
>                   }
> +
> +              set_immediate_dominator (CDI_DOMINATORS, next_bb,
> +                                       recompute_dominator (CDI_DOMINATORS,
> +                                                            next_bb));
>               }
>           }
>         VEC_free (basic_block, heap, preheader_blocks);



More information about the Gcc-patches mailing list