Re: [PATCH] Add GIMPLE switch support to loop unswitching

2022-05-25 Thread Michael Matz via Gcc-patches
Hello,

On Wed, 25 May 2022, Richard Biener via Gcc-patches wrote:

> I guess we might want to (warn about labels in the "toplevel"
> scope in switch statements).  So warn about
> 
> switch (x)
> {
> case 1:
> bar:
> };

That style is actually used quite some time in GCC itself.  Sometimes with 
statements between 'case 1:' and 'bar:'.

> Maybe we just want to warn when the label is otherwise unused?

We do with -Wunused-labels (part of -Wall).  The testcases simply aren't 
compiled with that.


Ciao,
Michael.


Re: [PATCH] Add GIMPLE switch support to loop unswitching

2022-05-25 Thread Richard Biener via Gcc-patches
On Wed, 25 May 2022, David Malcolm wrote:

> On Wed, 2022-05-25 at 10:36 +0200, Richard Biener via Gcc-patches
> wrote:
> > This patch adds support to unswitch loops with switch statements
> > based on invariant index.  It furthermore reworks the cost model
> > to allow an overall budget of statements to be created per original
> > loop by all unswitching opportunities in the loop.  Compared to
> > the original all unswitching opportunities in a loop are
> > pre-evaluated before the first transform which will allow future
> > changes to select the most profitable candidates first.
> > 
> > To efficiently support switch statements the pass now uses
> > ranger to simplify switch statements and conditions in loop
> > copies based on ranges extracted from the recorded set of
> > predicates unswitched.
> > 
> > Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.
> > 
> > Richard.
> > 
> 
> [...snip...]
> 
> > diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> > b/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> > new file mode 100644
> > index 000..5e4f16e2935
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> > @@ -0,0 +1,56 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-
> > optimized" } */
> > +
> > +int
> > +__attribute__((noipa))
> > +foo(double *a, double *b, double *c, double *d, double *r, int size,
> > int order)
> > +{
> > +  for (int i = 0; i < size; i++)
> > +  {
> > +    double tmp, tmp2;
> > +
> > +    switch(order)
> > +    {
> > +  case 0:
> > +    tmp = -8 * a[i];
> > +    tmp2 = 2 * b[i];
> > +    break;
> > +  case 1: 
> > +    tmp = 3 * a[i] -  2 * b[i];
> > +    tmp2 = 5 * b[i] - 2 * c[i];
> > +    break;
> > +  case 2:
> > +    tmp = 9 * a[i] +  2 * b[i] + c[i];
> > +    tmp2 = 4 * b[i] + 2 * c[i] + 8 * d[i];
> > +    break;
> > +  case 3:
> > +    tmp = 3 * a[i] +  2 * b[i] - c[i];
> > +    tmp2 = b[i] - 2 * c[i] + 8 * d[i];
> > +    break;
> > +  defaut:
> > +    __builtin_unreachable ();
> 
> I'm guessing "defaut:" here is a typo for "default:" i.e. it's an
> unused label named "defaut", when presumably you meant to have an
> unreachable default case.  Does this affect the loop unswitching logic?
> 
> I wonder if we warn for this (or if we can/should?)

I guess we might want to (warn about labels in the "toplevel"
scope in switch statements).  So warn about

switch (x)
{
case 1:
bar:
};

the 'case' might be missing here (if 'bar' is a valid enumeration
constant for example) but not about

switch (x)
{
case 1:
 {
bar:
 }
};

Maybe we just want to warn when the label is otherwise unused?

> Looking at the patch, it seems to also be present in:
>   gcc/testsuite/gcc.dg/loop-unswitch-11.c
>   gcc/testsuite/gcc.dg/loop-unswitch-14.c
> but I might have missed some.

Heh - how did you spot these but me not looking over the patch
multiple times ...

And no, it doesn't change behavior so I just pushed a fix.

Richard.

> 
> 
> Dave
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)


Re: [PATCH] Add GIMPLE switch support to loop unswitching

2022-05-25 Thread David Malcolm via Gcc-patches
On Wed, 2022-05-25 at 10:36 +0200, Richard Biener via Gcc-patches
wrote:
> This patch adds support to unswitch loops with switch statements
> based on invariant index.  It furthermore reworks the cost model
> to allow an overall budget of statements to be created per original
> loop by all unswitching opportunities in the loop.  Compared to
> the original all unswitching opportunities in a loop are
> pre-evaluated before the first transform which will allow future
> changes to select the most profitable candidates first.
> 
> To efficiently support switch statements the pass now uses
> ranger to simplify switch statements and conditions in loop
> copies based on ranges extracted from the recorded set of
> predicates unswitched.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.
> 
> Richard.
> 

[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> b/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> new file mode 100644
> index 000..5e4f16e2935
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/loop-unswitch-10.c
> @@ -0,0 +1,56 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-
> optimized" } */
> +
> +int
> +__attribute__((noipa))
> +foo(double *a, double *b, double *c, double *d, double *r, int size,
> int order)
> +{
> +  for (int i = 0; i < size; i++)
> +  {
> +    double tmp, tmp2;
> +
> +    switch(order)
> +    {
> +  case 0:
> +    tmp = -8 * a[i];
> +    tmp2 = 2 * b[i];
> +    break;
> +  case 1: 
> +    tmp = 3 * a[i] -  2 * b[i];
> +    tmp2 = 5 * b[i] - 2 * c[i];
> +    break;
> +  case 2:
> +    tmp = 9 * a[i] +  2 * b[i] + c[i];
> +    tmp2 = 4 * b[i] + 2 * c[i] + 8 * d[i];
> +    break;
> +  case 3:
> +    tmp = 3 * a[i] +  2 * b[i] - c[i];
> +    tmp2 = b[i] - 2 * c[i] + 8 * d[i];
> +    break;
> +  defaut:
> +    __builtin_unreachable ();

I'm guessing "defaut:" here is a typo for "default:" i.e. it's an
unused label named "defaut", when presumably you meant to have an
unreachable default case.  Does this affect the loop unswitching logic?

I wonder if we warn for this (or if we can/should?)

Looking at the patch, it seems to also be present in:
  gcc/testsuite/gcc.dg/loop-unswitch-11.c
  gcc/testsuite/gcc.dg/loop-unswitch-14.c
but I might have missed some.


Dave



[PATCH] Add GIMPLE switch support to loop unswitching

2022-05-25 Thread Richard Biener via Gcc-patches
This patch adds support to unswitch loops with switch statements
based on invariant index.  It furthermore reworks the cost model
to allow an overall budget of statements to be created per original
loop by all unswitching opportunities in the loop.  Compared to
the original all unswitching opportunities in a loop are
pre-evaluated before the first transform which will allow future
changes to select the most profitable candidates first.

To efficiently support switch statements the pass now uses
ranger to simplify switch statements and conditions in loop
copies based on ranges extracted from the recorded set of
predicates unswitched.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.

Richard.

gcc/ChangeLog:

* dbgcnt.def (DEBUG_COUNTER): Add loop_unswitch counter.
* params.opt (max-unswitch-level): Remove.
* doc/invoke.texi (max-unswitch-level): Likewise.
* tree-cfg.c (gimple_lv_add_condition_to_bb): Support not
gimplified expressions.
* tree-ssa-loop-unswitch.c (struct unswitch_predicate): New.
(tree_may_unswitch_on): Rename to ...
(find_unswitching_predicates_for_bb): ... this and handle
switch statements.
(get_predicates_for_bb): Likewise.
(set_predicates_for_bb): Likewise.
(init_loop_unswitch_info): Likewise.
(tree_ssa_unswitch_loops): Prepare stuff before calling
tree_unswitch_single_loop.
(tree_unswitch_single_loop): Rework the function using
pre-computed predicates and with a per original loop cost model.
(merge_last): New.
(add_predicate_to_path): Likewise.
(find_range_for_lhs): Likewise.
(simplify_using_entry_checks): Rename to ...
(evaluate_control_stmt_using_entry_checks): ... this, handle
switch statements and improve simplifications using ranger.
(simplify_loop_version): Rework using
evaluate_control_stmt_using_entry_checks.
(evaluate_bbs): New.
(evaluate_loop_insns_for_predicate): Likewise.
(tree_unswitch_loop): Adjust to allow switch statements and
pass in the edge to unswitch.
(clean_up_after_unswitching): New.
(pass_tree_unswitch::execute): Pass down fun.

gcc/testsuite/ChangeLog:

* gcc.dg/loop-unswitch-7.c: New test.
* gcc.dg/loop-unswitch-8.c: New test.
* gcc.dg/loop-unswitch-9.c: New test.
* gcc.dg/loop-unswitch-10.c: New test.
* gcc.dg/loop-unswitch-11.c: New test.
* gcc.dg/loop-unswitch-12.c: New test.
* gcc.dg/loop-unswitch-13.c: New test.
* gcc.dg/loop-unswitch-14.c: New test.
* gcc.dg/loop-unswitch-15.c: New test.
* gcc.dg/loop-unswitch-16.c: New test.
* gcc.dg/loop-unswitch-17.c: New test.
* gcc.dg/torture/20220518-1.c: New test.
* gcc.dg/torture/20220518-2.c: New test.
* gcc.dg/torture/20220525-1.c: New test.
* gcc.dg/alias-10.c: Adjust.
* gcc.dg/tree-ssa/loop-6.c: Likewise.
* gcc.dg/loop-unswitch-1.c: Likewise.

Co-authored-by: Richard Biener  
---
 gcc/dbgcnt.def|1 +
 gcc/doc/invoke.texi   |3 -
 gcc/params.opt|4 -
 gcc/testsuite/gcc.dg/alias-10.c   |2 +-
 gcc/testsuite/gcc.dg/loop-unswitch-1.c|2 +-
 gcc/testsuite/gcc.dg/loop-unswitch-10.c   |   56 ++
 gcc/testsuite/gcc.dg/loop-unswitch-11.c   |   45 +
 gcc/testsuite/gcc.dg/loop-unswitch-12.c   |   28 +
 gcc/testsuite/gcc.dg/loop-unswitch-13.c   |   35 +
 gcc/testsuite/gcc.dg/loop-unswitch-14.c   |   60 ++
 gcc/testsuite/gcc.dg/loop-unswitch-15.c   |   15 +
 gcc/testsuite/gcc.dg/loop-unswitch-16.c   |   22 +
 gcc/testsuite/gcc.dg/loop-unswitch-17.c   |   24 +
 gcc/testsuite/gcc.dg/loop-unswitch-7.c|   28 +
 gcc/testsuite/gcc.dg/loop-unswitch-8.c|   31 +
 gcc/testsuite/gcc.dg/loop-unswitch-9.c|   27 +
 gcc/testsuite/gcc.dg/torture/20220518-1.c |   39 +
 gcc/testsuite/gcc.dg/torture/20220518-2.c |   14 +
 gcc/testsuite/gcc.dg/torture/20220525-1.c |   33 +
 gcc/testsuite/gcc.dg/tree-ssa/loop-6.c|2 +-
 gcc/tree-cfg.cc   |7 +-
 gcc/tree-ssa-loop-unswitch.cc | 1062 -
 22 files changed, 1288 insertions(+), 252 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-10.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-11.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-12.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-13.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-14.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-15.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-16.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-17.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-7.c
 create mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-8.c
 create mode 100644