This simplifies (and for me robustifies) finding of the final_bb.
The current code is somewhat odd in that it requires at least one
non-forwarder successor of a switch to transform.  The following
patch makes us simply pick the candidate from a random edge (I chose
the default edge) using either the successor or its successor if
the successor is a forwarder.

That fixes fallout of gcc.dg/tree-ssa/pr36881.c when removing
the early copyprop pass which happened to unconditionally run
a cfgcleanup.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2014-06-17  Richard Biener  <rguent...@suse.de>

        * tree-switch-conversion.c (collect_switch_conv_info): Simplify
        and allow all blocks to be forwarders.

Index: gcc/tree-switch-conversion.c
===================================================================
*** gcc/tree-switch-conversion.c        (revision 211727)
--- gcc/tree-switch-conversion.c        (working copy)
*************** collect_switch_conv_info (gimple swtch,
*** 640,654 ****
        info->other_count += e->count;
  
    /* See if there is one common successor block for all branch
!      targets.  If it exists, record it in FINAL_BB.  */
!   FOR_EACH_EDGE (e, ei, info->switch_bb->succs)
!     {
!       if (! single_pred_p (e->dest))
!       {
!         info->final_bb = e->dest;
!         break;
!       }
!     }
    if (info->final_bb)
      FOR_EACH_EDGE (e, ei, info->switch_bb->succs)
        {
--- 640,655 ----
        info->other_count += e->count;
  
    /* See if there is one common successor block for all branch
!      targets.  If it exists, record it in FINAL_BB.
!      Start with the destination of the default case as guess
!      or its destination in case it is a forwarder block.  */
!   if (! single_pred_p (e_default->dest))
!     info->final_bb = e_default->dest;
!   else if (single_succ_p (e_default->dest)
!          && ! single_pred_p (single_succ (e_default->dest)))
!     info->final_bb = single_succ (e_default->dest);
!   /* Require that all switch destinations are either that common
!      FINAL_BB or a forwarder to it.  */
    if (info->final_bb)
      FOR_EACH_EDGE (e, ei, info->switch_bb->succs)
        {

Reply via email to