PR tree-optimization/89713 - Assume loop with an exit is finite

gcc/ChangeLog:

        * doc/invoke.texi (-ffinite-loops): Document new option.
        * common.opt (-ffinite-loops): New option.
        * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Mark
        IFN_GOACC_LOOP calls as necessary.
        * tree-ssa-loop-niter.c (finite_loop_p): Assume loop with an exit
        is finite.
        * omp-offload.c (oacc_xform_loop): Skip lowering if return value of
        IFN_GOACC_LOOP call is not used.
        * opts.c (default_options_table): Enable -ffinite-loops at -O2+.

gcc/testsuite/ChangeLog:

        * g++.dg/tree-ssa/empty-loop.C: New test.
        * gcc.dg/tree-ssa/dce-2.c: New test.
        * gcc.dg/const-1.c: Add -fno-finite-loops option.
        * gcc.dg/graphite/graphite.exp: Likewise.
        * gcc.dg/loop-unswitch-1.c: Likewise.
        * gcc.dg/predict-9.c: Likewise.
        * gcc.dg/pure-2.c: Likewise.
        * gcc.dg/tree-ssa/20040211-1.c: Likewise.
        * gcc.dg/tree-ssa/loop-10.c: Likewise.
        * gcc.dg/tree-ssa/split-path-6.c: Likewise.
        * gcc.dg/tree-ssa/ssa-thread-12.c: Likewise.

libgomp/ChangeLog:

        * testsuite/libgomp.oacc-c-c++-common/pr84955-1.c: New test.

From-SVN: r272234
This commit is contained in:
Feng Xue 2019-06-13 04:17:42 +00:00 committed by Feng Xue
parent 9b884225bf
commit c29c92c789
21 changed files with 201 additions and 10 deletions

View File

@ -1,3 +1,16 @@
2019-06-13 Feng Xue <fxue@os.amperecomputing.com>
PR tree-optimization/89713
* doc/invoke.texi (-ffinite-loops): Document new option.
* common.opt (-ffinite-loops): New option.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Mark
IFN_GOACC_LOOP calls as necessary.
* tree-ssa-loop-niter.c (finite_loop_p): Assume loop with an exit
is finite.
* omp-offload.c (oacc_xform_loop): Skip lowering if return value of
IFN_GOACC_LOOP call is not used.
* opts.c (default_options_table): Enable -ffinite-loops at -O2+.
2019-06-13 Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
PR target/88838

View File

@ -1437,6 +1437,10 @@ ffinite-math-only
Common Report Var(flag_finite_math_only) Optimization SetByCombined
Assume no NaNs or infinities are generated.
ffinite-loops
Common Report Var(flag_finite_loops) Optimization
Assume that loops with an exit will terminate and not loop indefinitely.
ffixed-
Common Joined RejectNegative Var(common_deferred_options) Defer
-ffixed-<register> Mark <register> as being unavailable to the compiler.

View File

@ -413,6 +413,7 @@ Objective-C and Objective-C++ Dialects}.
-fdevirtualize-at-ltrans -fdse @gol
-fearly-inlining -fipa-sra -fexpensive-optimizations -ffat-lto-objects @gol
-ffast-math -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
-ffinite-loops @gol
-fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol
-fgcse -fgcse-after-reload -fgcse-las -fgcse-lm -fgraphite-identity @gol
-fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol
@ -8303,6 +8304,7 @@ also turns on the following optimization flags:
-fdelete-null-pointer-checks @gol
-fdevirtualize -fdevirtualize-speculatively @gol
-fexpensive-optimizations @gol
-ffinite-loops @gol
-fgcse -fgcse-lm @gol
-fhoist-adjacent-loads @gol
-finline-small-functions @gol
@ -9524,6 +9526,15 @@ that may set @code{errno} but are otherwise free of side effects. This flag is
enabled by default at @option{-O2} and higher if @option{-Os} is not also
specified.
@item -ffinite-loops
@opindex ffinite-loops
@opindex fno-finite-loops
Assume that a loop with an exit will eventually take the exit and not loop
indefinitely. This allows the compiler to remove loops that otherwise have
no side-effects, not considering eventual endless looping as such.
This option is enabled by default at @option{-O2}.
@item -ftree-dominator-opts
@opindex ftree-dominator-opts
Perform a variety of simple scalar cleanups (constant/copy

View File

@ -300,7 +300,7 @@ oacc_xform_loop (gcall *call)
tree chunk_size = NULL_TREE;
unsigned mask = (unsigned) TREE_INT_CST_LOW (gimple_call_arg (call, 5));
tree lhs = gimple_call_lhs (call);
tree type = TREE_TYPE (lhs);
tree type = NULL_TREE;
tree diff_type = TREE_TYPE (range);
tree r = NULL_TREE;
gimple_seq seq = NULL;
@ -308,6 +308,15 @@ oacc_xform_loop (gcall *call)
unsigned outer_mask = mask & (~mask + 1); // Outermost partitioning
unsigned inner_mask = mask & ~outer_mask; // Inner partitioning (if any)
/* Skip lowering if return value of IFN_GOACC_LOOP call is not used. */
if (!lhs)
{
gsi_replace_with_seq (&gsi, seq, true);
return;
}
type = TREE_TYPE (lhs);
#ifdef ACCEL_COMPILER
chunk_size = gimple_call_arg (call, 4);
if (integer_minus_onep (chunk_size) /* Force static allocation. */

View File

@ -494,6 +494,7 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ffinite_loops, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },

View File

@ -1,3 +1,18 @@
2019-06-13 Feng Xue <fxue@os.amperecomputing.com>
PR tree-optimization/89713
* g++.dg/tree-ssa/empty-loop.C: New test.
* gcc.dg/tree-ssa/dce-2.c: New test.
* gcc.dg/const-1.c: Add -fno-finite-loops option.
* gcc.dg/graphite/graphite.exp: Likewise.
* gcc.dg/loop-unswitch-1.c: Likewise.
* gcc.dg/predict-9.c: Likewise.
* gcc.dg/pure-2.c: Likewise.
* gcc.dg/tree-ssa/20040211-1.c: Likewise.
* gcc.dg/tree-ssa/loop-10.c: Likewise.
* gcc.dg/tree-ssa/split-path-6.c: Likewise.
* gcc.dg/tree-ssa/ssa-thread-12.c: Likewise.
2019-06-13 Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
PR target/88838

View File

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-cddce2 -ffinite-loops" } */
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
using namespace std;
int foo (vector<string> &v, list<string> &l, set<string> &s, map<int, string> &m)
{
for (vector<string>::iterator it = v.begin (); it != v.end (); ++it)
it->length();
for (list<string>::iterator it = l.begin (); it != l.end (); ++it)
it->length();
for (map<int, string>::iterator it = m.begin (); it != m.end (); ++it)
it->first + it->second.length();
for (set<string>::iterator it0 = s.begin (); it0 != s.end(); ++it0)
for (vector<string>::reverse_iterator it1 = v.rbegin(); it1 != v.rend(); ++it1)
{
it0->length();
it1->length();
}
return 0;
}
/* { dg-final { scan-tree-dump-not "if" "cddce2"} } */

View File

@ -1,5 +1,5 @@
/* { dg-do compile { target nonpic } } */
/* { dg-options "-O2 -Wsuggest-attribute=const" } */
/* { dg-options "-O2 -Wsuggest-attribute=const -fno-finite-loops" } */
extern int extern_const(int a) __attribute__ ((const));

View File

@ -56,7 +56,7 @@ set vect_files [lsort [glob -nocomplain $srcdir/$subdir/vect-*.c ] ]
# Tests to be compiled.
set dg-do-what-default compile
dg-runtest $scop_files "" "-O2 -fgraphite -fdump-tree-graphite-all"
dg-runtest $scop_files "" "-O2 -fgraphite -fdump-tree-graphite-all -fno-finite-loops"
dg-runtest $id_files "" "-O2 -fgraphite-identity -ffast-math -fdump-tree-graphite-details"
# Tests to be run.

View File

@ -1,6 +1,6 @@
/* For PR rtl-optimization/27735 */
/* { dg-do compile } */
/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details" } */
/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details -fno-finite-loops" } */
void set_color(void);
void xml_colorize_line(unsigned int *p, int state)

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate" } */
/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate -fno-finite-loops" } */
extern int global;
extern int global2;

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Wsuggest-attribute=pure" } */
/* { dg-options "-O2 -Wsuggest-attribute=pure -fno-finite-loops" } */
/* { dg-add-options bind_pic_locally } */
extern int extern_const(int a) __attribute__ ((pure));

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-cddce2" } */
/* { dg-options "-O2 -fdump-tree-cddce2 -fno-finite-loops" } */
struct rtx_def;
typedef struct rtx_def *rtx;

View File

@ -0,0 +1,37 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-cddce1 -ffinite-loops" } */
typedef struct list {
char pad[15];
struct list *next;
} list;
int data;
list *head, *tail;
int __attribute__((pure)) pfn (int);
int foo (unsigned u, int s)
{
unsigned i;
list *p;
int j;
for (i = 0; i < u; i += 2)
;
for (p = head; p; p = p->next)
;
for (j = data; j & s; j = pfn (j + 3))
;
for (p = head; p != tail; p = p->next)
for (j = data + 1; j > s; j = pfn (j + 2))
;
return 0;
}
/* { dg-final { scan-tree-dump-not "if" "cddce1"} } */

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-options "-O2 -fdump-tree-optimized -fno-finite-loops" } */
/* { dg-require-effective-target int32plus } */
int bar (void);

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w" } */
/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w -fno-finite-loops" } */
struct __sFILE
{

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details" } */
/* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details -fno-finite-loops" } */
/* { dg-final { scan-tree-dump "FSM" "thread2" } } */
/* { dg-final { scan-tree-dump "FSM" "thread3" } } */
/* { dg-final { scan-tree-dump "FSM" "thread4" { xfail *-*-* } } } */

View File

@ -245,6 +245,17 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
mark_stmt_necessary (stmt, true);
return;
}
/* IFN_GOACC_LOOP calls are necessary in that they are used to
represent parameter (i.e. step, bound) of a lowered OpenACC
partitioned loop. But this kind of partitioned loop might not
survive from aggressive loop removal for it has loop exit and
is assumed to be finite. Therefore, we need to explicitly mark
these calls. (An example is libgomp.oacc-c-c++-common/pr84955.c) */
if (gimple_call_internal_p (stmt, IFN_GOACC_LOOP))
{
mark_stmt_necessary (stmt, true);
return;
}
if (!gimple_call_lhs (stmt))
return;
break;

View File

@ -2830,6 +2830,27 @@ finite_loop_p (struct loop *loop)
loop->num);
return true;
}
if (flag_finite_loops)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);
edge ex;
/* If the loop has a normal exit, we can assume it will terminate. */
FOR_EACH_VEC_ELT (exits, i, ex)
if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_FAKE)))
{
exits.release ();
if (dump_file)
fprintf (dump_file, "Assume loop %i to be finite: it has an exit "
"and -ffinite-loops is on.\n", loop->num);
return true;
}
exits.release ();
}
return false;
}

View File

@ -1,3 +1,8 @@
2019-06-13 Feng Xue <fxue@os.amperecomputing.com>
PR tree-optimization/89713
* testsuite/libgomp.oacc-c-c++-common/pr84955-1.c: New test.
2019-06-11 Jakub Jelinek <jakub@redhat.com>
PR target/90811

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-cddce2 -ffinite-loops" } */
int
f1 (void)
{
int i, j;
#pragma acc parallel loop tile(2,3)
for (i = 1; i < 10; i++)
for (j = 1; j < 10; j++)
for (;;)
;
return i + j;
}
int
f2 (void)
{
int i, j, k;
#pragma acc parallel loop tile(2,3)
for (i = 1; i < 10; i++)
for (j = 1; j < 10; j++)
for (k = 1; k < 10; k++)
;
return i + j;
}
/* { dg-final { scan-tree-dump-not "if" "cddce2"} } */