161 lines
6.0 KiB
Diff
161 lines
6.0 KiB
Diff
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
|
|
index 6b6c754ad86..58ba0948e79 100644
|
|
--- a/gcc/c-family/c-opts.c
|
|
+++ b/gcc/c-family/c-opts.c
|
|
@@ -989,6 +989,10 @@ c_common_post_options (const char **pfilename)
|
|
if (!global_options_set.x_flag_new_ttp)
|
|
flag_new_ttp = (cxx_dialect >= cxx17);
|
|
|
|
+ /* C++11 guarantees forward progress. */
|
|
+ if (!global_options_set.x_flag_finite_loops)
|
|
+ flag_finite_loops = (optimize >= 2 && cxx_dialect >= cxx11);
|
|
+
|
|
if (cxx_dialect >= cxx11)
|
|
{
|
|
/* If we're allowing C++0x constructs, don't warn about C++98
|
|
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
|
|
index 1c49a8b8c2d..18b404e292f 100644
|
|
--- a/gcc/cfgloop.h
|
|
+++ b/gcc/cfgloop.h
|
|
@@ -226,6 +226,10 @@ public:
|
|
/* True if the loop is part of an oacc kernels region. */
|
|
unsigned in_oacc_kernels_region : 1;
|
|
|
|
+ /* True if the loop is known to be finite. This is a localized
|
|
+ flag_finite_loops or similar pragmas state. */
|
|
+ unsigned finite_p : 1;
|
|
+
|
|
/* The number of times to unroll the loop. 0 means no information given,
|
|
just do what we always do. A value of 1 means do not unroll the loop.
|
|
A value of USHRT_MAX means unroll with no specific unrolling factor.
|
|
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
|
|
index c9375565f62..50c7267ec49 100644
|
|
--- a/gcc/cfgloopmanip.c
|
|
+++ b/gcc/cfgloopmanip.c
|
|
@@ -1023,6 +1023,7 @@ copy_loop_info (class loop *loop, class loop *target)
|
|
target->dont_vectorize = loop->dont_vectorize;
|
|
target->force_vectorize = loop->force_vectorize;
|
|
target->in_oacc_kernels_region = loop->in_oacc_kernels_region;
|
|
+ target->finite_p = loop->finite_p;
|
|
target->unroll = loop->unroll;
|
|
target->owned_clique = loop->owned_clique;
|
|
}
|
|
diff --git a/gcc/common.opt b/gcc/common.opt
|
|
index 4368910cb54..bb2ea4c905d 100644
|
|
--- a/gcc/common.opt
|
|
+++ b/gcc/common.opt
|
|
@@ -1490,7 +1490,7 @@ 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
|
|
+Common Report Var(flag_finite_loops) Optimization Init(0)
|
|
Assume that loops with an exit will terminate and not loop indefinitely.
|
|
|
|
ffixed-
|
|
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
|
index e9e1683e9a8..e3e652ff6c1 100644
|
|
--- a/gcc/doc/invoke.texi
|
|
+++ b/gcc/doc/invoke.texi
|
|
@@ -10432,7 +10432,8 @@ 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}.
|
|
+This option is enabled by default at @option{-O2} for C++ with -std=c++11
|
|
+or higher.
|
|
|
|
@item -ftree-dominator-opts
|
|
@opindex ftree-dominator-opts
|
|
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
|
|
index 9566e5ee102..244f5b8aa5c 100644
|
|
--- a/gcc/lto-streamer-in.c
|
|
+++ b/gcc/lto-streamer-in.c
|
|
@@ -821,6 +821,7 @@ input_cfg (class lto_input_block *ib, class data_in *data_in,
|
|
loop->owned_clique = streamer_read_hwi (ib);
|
|
loop->dont_vectorize = streamer_read_hwi (ib);
|
|
loop->force_vectorize = streamer_read_hwi (ib);
|
|
+ loop->finite_p = streamer_read_hwi (ib);
|
|
loop->simduid = stream_read_tree (ib, data_in);
|
|
|
|
place_new_loop (fn, loop);
|
|
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
|
|
index a219c1d0dd1..52ef94718db 100644
|
|
--- a/gcc/lto-streamer-out.c
|
|
+++ b/gcc/lto-streamer-out.c
|
|
@@ -1950,6 +1950,7 @@ output_cfg (struct output_block *ob, struct function *fn)
|
|
streamer_write_hwi (ob, loop->owned_clique);
|
|
streamer_write_hwi (ob, loop->dont_vectorize);
|
|
streamer_write_hwi (ob, loop->force_vectorize);
|
|
+ streamer_write_hwi (ob, loop->finite_p);
|
|
stream_write_tree (ob, loop->simduid, true);
|
|
}
|
|
|
|
diff --git a/gcc/opts.c b/gcc/opts.c
|
|
index 5dc7d65dedd..d4df8627bf7 100644
|
|
--- a/gcc/opts.c
|
|
+++ b/gcc/opts.c
|
|
@@ -478,7 +478,6 @@ 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 },
|
|
diff --git a/gcc/testsuite/gcc.dg/torture/pr94392.c b/gcc/testsuite/gcc.dg/torture/pr94392.c
|
|
new file mode 100644
|
|
index 00000000000..373f18ce983
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/torture/pr94392.c
|
|
@@ -0,0 +1,22 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-skip-if "finite loops" { *-*-* } { "-ffinite-loops" } } */
|
|
+/* { dg-skip-if "LTO optimizes the test" { *-*-* } { "-flto" } } */
|
|
+/* { dg-additional-options "-fdump-tree-optimized" } */
|
|
+
|
|
+int a, b;
|
|
+
|
|
+int
|
|
+main()
|
|
+{
|
|
+ while (1)
|
|
+ {
|
|
+ /* Try really hard. */
|
|
+ if (a != b)
|
|
+ return 1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* ISO C does not guarantee forward progress like C++ does so we
|
|
+ cannot assume the loop is finite and optimize it to return 1. */
|
|
+/* { dg-final { scan-tree-dump "if" "optimized" } } */
|
|
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
|
|
index f7b817d94e6..e99fb9ff5d1 100644
|
|
--- a/gcc/tree-cfg.c
|
|
+++ b/gcc/tree-cfg.c
|
|
@@ -324,6 +324,9 @@ replace_loop_annotate (void)
|
|
/* Then look into the latch, if any. */
|
|
if (loop->latch)
|
|
replace_loop_annotate_in_block (loop->latch, loop);
|
|
+
|
|
+ /* Push the global flag_finite_loops state down to individual loops. */
|
|
+ loop->finite_p = flag_finite_loops;
|
|
}
|
|
|
|
/* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */
|
|
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
|
|
index 6e6df0bfdb8..7d61ef080eb 100644
|
|
--- a/gcc/tree-ssa-loop-niter.c
|
|
+++ b/gcc/tree-ssa-loop-niter.c
|
|
@@ -2834,7 +2834,7 @@ finite_loop_p (class loop *loop)
|
|
return true;
|
|
}
|
|
|
|
- if (flag_finite_loops)
|
|
+ if (loop->finite_p)
|
|
{
|
|
unsigned i;
|
|
vec<edge> exits = get_loop_exit_edges (loop);
|