On Mon, 13 Jun 2016, Jakub Jelinek wrote:

> Hi!
> 
> Cross-jumping at GIMPLE level gives up e.g. because there are any labels
> at the beginning of the block (which is always the case for bbs referenced
> from switches).  While labels for non-local goto as well as computed goto
> are hard to handle, after all the edges are then EDGE_ABNORMAL that can't be
> redirected anyway, other labels can be handled very easily.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

Ok.

> In the PR, beyond this I'm also talking about switchconv pass not being able
> to know that some cases could be cross-jumped and thus use better conversion
> sequences.  Wonder if we shouldn't schedule either a full, or a limited
> version of tailmerging before switchconv, perhaps just use the
> infrastructure from tree-ssa-tail-merge.c to handle the easiest cases
> where the cross-jumping in the end would end up simplifying some of the
> switches.  Thoughts on this?

I'd like to postpone this until tail-merging got rid of its SCCVN
dependency (the proposed merge with the ICF machinery).

I also think that switch-conversion is a bit early in the pipeline,
I'd put it not before at least one VRP pass.  I know Martin put it
in early opts because it can reduce code-size and thus trigger
inlining but that can be said about most of the scalar opts we have
in the late pipeline as well.

Richard.

> 2016-06-13  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/71520
>       * tree-ssa-tail-merge.c (find_duplicate): Handle labels.
>       (replace_block_by): Move user labels from bb1 to bb2.
> 
>       * gcc.dg/tree-ssa/pr71520.c: New test.
> 
> --- gcc/tree-ssa-tail-merge.c.jj      2016-06-10 20:23:55.196164390 +0200
> +++ gcc/tree-ssa-tail-merge.c 2016-06-13 12:08:34.691985005 +0200
> @@ -1265,6 +1265,10 @@ find_duplicate (same_succ *same_succ, ba
>        gimple *stmt1 = gsi_stmt (gsi1);
>        gimple *stmt2 = gsi_stmt (gsi2);
>  
> +      if (gimple_code (stmt1) == GIMPLE_LABEL
> +       && gimple_code (stmt2) == GIMPLE_LABEL)
> +     break;
> +
>        if (!gimple_equal_p (same_succ, stmt1, stmt2))
>       return;
>  
> @@ -1277,6 +1281,20 @@ find_duplicate (same_succ *same_succ, ba
>        gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
>      }
>  
> +  while (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
> +    {
> +      tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
> +      if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
> +     return;
> +      gsi_prev (&gsi1);
> +    }
> +  while (!gsi_end_p (gsi2) && gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL)
> +    {
> +      tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)));
> +      if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
> +     return;
> +      gsi_prev (&gsi2);
> +    }
>    if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
>      return;
>  
> @@ -1555,6 +1573,23 @@ replace_block_by (basic_block bb1, basic
>        e2->probability = GCOV_COMPUTE_SCALE (e2->count, out_sum);
>      }
>  
> +  /* Move over any user labels from bb1 after the bb2 labels.  */
> +  gimple_stmt_iterator gsi1 = gsi_start_bb (bb1);
> +  if (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
> +    {
> +      gimple_stmt_iterator gsi2 = gsi_after_labels (bb2);
> +      while (!gsi_end_p (gsi1)
> +          && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
> +     {
> +       tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
> +       gcc_assert (!DECL_NONLOCAL (label) && !FORCED_LABEL (label));
> +       if (DECL_ARTIFICIAL (label))
> +         gsi_next (&gsi1);
> +       else
> +         gsi_move_before (&gsi1, &gsi2);
> +     }
> +    }
> +
>    /* Clear range info from all stmts in BB2 -- this transformation
>       could make them out of date.  */
>    reset_flow_sensitive_info_in_bb (bb2);
> --- gcc/testsuite/gcc.dg/tree-ssa/pr71520.c.jj        2016-06-13 
> 12:26:55.251630020 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr71520.c   2016-06-13 12:26:31.000000000 
> +0200
> @@ -0,0 +1,90 @@
> +/* PR tree-optimization/71520 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +void bar (int);
> +
> +void
> +foo (int x)
> +{
> +  switch (x)
> +    {
> +    case 1:
> +    case 12:
> +    case 28:
> +    case 174:
> +      bar (1);
> +      bar (2);
> +      break;
> +    case 3:
> +    case 7:
> +    case 78:
> +    case 96:
> +    case 121:
> +    default:
> +      bar (3);
> +      bar (4);
> +      bar (5);
> +      bar (6);
> +      break;
> +    case 8:
> +    case 13:
> +    case 27:
> +    case 19:
> +    case 118:
> +      bar (3);
> +      bar (4);
> +      bar (5);
> +      bar (6);
> +      break;
> +    case 4:
> +      bar (7);
> +      break;
> +    }
> +}
> +
> +void
> +baz (int x)
> +{
> +  switch (x)
> +    {
> +    case 1:
> +    case 12:
> +    case 28:
> +    case 174:
> +      bar (8);
> +      bar (9);
> +      break;
> +    case 3:
> +    case 7:
> +    case 78:
> +    case 96:
> +    case 121:
> +    default:
> +    lab1:
> +    lab2:
> +      bar (10);
> +      bar (11);
> +      bar (12);
> +      bar (13);
> +      break;
> +    case 8:
> +    case 13:
> +    case 27:
> +    case 19:
> +    case 118:
> +    lab3:
> +    lab4:
> +      bar (10);
> +      bar (11);
> +      bar (12);
> +      bar (13);
> +      break;
> +    case 4:
> +      bar (14);
> +      break;
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump-times "bar \\\(3\\\);" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bar \\\(10\\\);" 1 "optimized" } } */
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to