From: Richard Biener <rguenther@suse.de>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org, "Joseph S. Myers" <joseph@codesourcery.com>
Subject: Re: [PATCH][RFC] c/94392 - only enable -ffinite-loops for C++
Date: Thu, 2 Apr 2020 11:12:48 +0200 (CEST) [thread overview]
Message-ID: <nycvar.YFH.7.76.2004021110110.830@zhemvz.fhfr.qr> (raw)
In-Reply-To: <0f331251-85c6-2cfe-e7aa-54bc7966ce57@redhat.com>
On Wed, 1 Apr 2020, Jason Merrill wrote:
> On 4/1/20 9:36 AM, Richard Biener wrote:
> > This does away with enabling -ffinite-loops at -O2+ for all languages
> > and instead enables it selectively for C++ only.
> >
> > Jason, I didn't find a reference as to when the forward progress
> > guarantee was introduced to C++ so I randomly chose C++11, is that
> > correct?
>
> C++11 says "Implementations should ensure that all unblocked threads
> eventually make progress."
>
> C++17 adds the "Forward progress" section that says
>
> "The implementation may assume that any thread will eventually do one of the
> following:
> — terminate,
> — make a call to a library I/O function,
> — perform an access through a volatile glvalue, or
> — perform a synchronization operation or an atomic operation.
> [Note: This is intended to allow compiler transformations such as removal of
> empty loops, even when termination cannot be proven. — end note]"
OK, so I assume using C++11 as in the patch is fine.
I'm retesting the following currently which factors in Honzas comments
turning -ffinite-loops into a per-loop setting at CFG construction time
(the same place where we'd handle #pragma induced ANNOTATE_EXPRs for
such feature - for GCC11 we might implement the C side this way which has
more restrictive wording where such forward progress can be assumed)
Thanks,
Richard.
[PATCH] c/94392 - only enable -ffinite-loops for C++
This does away with enabling -ffinite-loops at -O2+ for all languages
and instead enables it selectively for C++ only.
It also makes -ffinite-loops loop-private at CFG construction time
fixing correctness issues with inlining.
2020-04-02 Richard Biener <rguenther@suse.de>
PR c/94392
* c-opts.c (c_common_post_options): Enable -ffinite-loops
for -O2 and C++11 or newer.
* common.opt (ffinite-loops): Initialize to zero.
* opts.c (default_options_table): Remove OPT_ffinite_loops
entry.
* cfgloop.h (loop::finite_p): New member.
* cfgloopmanip.c (copy_loop_info): Copy finite_p.
* ipa-icf-gimple.c (func_checker::compare_loops): Compare
finite_p.
* lto-streamer-in.c (input_cfg): Stream finite_p.
* lto-streamer-out.c (output_cfg): Likewise.
* tree-cfg.c (replace_loop_annotate): Initialize finite_p
from flag_finite_loops at CFG build time.
* tree-ssa-loop-niter.c (finite_loop_p): Check the loops
finite_p flag instead of flag_finite_loops.
* doc/invoke.texi (ffinite-loops): Adjust documentation of
default setting.
* gcc.dg/torture/pr94392.c: New testcase.
---
gcc/c-family/c-opts.c | 4 ++++
gcc/cfgloop.h | 4 ++++
gcc/cfgloopmanip.c | 1 +
gcc/common.opt | 2 +-
gcc/doc/invoke.texi | 3 ++-
gcc/ipa-icf-gimple.c | 2 ++
gcc/lto-streamer-in.c | 1 +
gcc/lto-streamer-out.c | 1 +
gcc/opts.c | 1 -
gcc/testsuite/gcc.dg/torture/pr94392.c | 22 ++++++++++++++++++++++
gcc/tree-cfg.c | 3 +++
gcc/tree-ssa-loop-niter.c | 2 +-
12 files changed, 42 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr94392.c
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)
SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_new_ttp,
cxx_dialect >= cxx17);
+ /* C++11 guarantees forward progress. */
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set, 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 412750c1fc9..142bfeacead 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/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 3e5b2d4bd6d..d306fec56ce 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -395,6 +395,8 @@ func_checker::compare_loops (basic_block bb1, basic_block bb2)
return return_false_with_msg ("dont_vectorize");
if (l1->force_vectorize != l2->force_vectorize)
return return_false_with_msg ("force_vectorize");
+ if (l1->finite_p != l2->finite_p)
+ return return_false_with_msg ("finite_p");
if (l1->unroll != l2->unroll)
return return_false_with_msg ("unroll");
if (!compare_variable_decl (l1->simduid, l2->simduid))
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);
--
2.13.7
next prev parent reply other threads:[~2020-04-02 9:12 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-17 4:17 [PATCH] Remove empty loop with assumed finiteness (PR tree-optimization/89713) Feng Xue OS
2019-05-17 16:47 ` Jeff Law
2019-05-17 18:50 ` Richard Biener
2019-05-18 14:00 ` Marc Glisse
2019-05-20 7:50 ` Richard Biener
2019-05-20 8:27 ` Feng Xue OS
2019-05-20 9:19 ` Richard Biener
2019-05-20 9:48 ` Feng Xue OS
2019-05-20 11:54 ` Richard Biener
2019-05-20 14:00 ` Feng Xue OS
2019-05-20 14:04 ` Richard Biener
2019-05-20 14:51 ` Feng Xue OS
2019-05-21 10:12 ` Richard Biener
2019-05-21 14:24 ` Richard Biener
2019-05-22 13:44 ` Michael Matz
2019-05-24 16:02 ` [PATCH V3] " Feng Xue OS
2019-05-24 9:15 ` [PATCH V2] " Feng Xue OS
2019-05-29 11:16 ` Richard Biener
2019-06-04 6:49 ` [PATCH V4] " Feng Xue OS
2019-06-04 8:24 ` Marc Glisse
2019-06-04 15:16 ` [PATCH V5] " Feng Xue OS
2019-06-04 15:24 ` [PATCH V6] " Feng Xue OS
2019-06-05 11:05 ` Richard Biener
2019-06-06 10:00 ` [PATCH V7] " Feng Xue OS
2019-06-11 2:40 ` [PATCH V8] " Feng Xue OS
2019-06-12 9:43 ` Richard Biener
2019-06-15 12:05 ` [committed][nvptx, libgomp] Update pr85381-{2,4}.c test-cases Tom de Vries
2019-05-20 13:04 ` [PATCH] Remove empty loop with assumed finiteness (PR tree-optimization/89713) Marc Glisse
2019-05-20 13:26 ` Richard Biener
2019-05-20 14:49 ` Michael Matz
2019-05-21 8:06 ` Marc Glisse
2020-04-01 13:36 ` [PATCH][RFC] c/94392 - only enable -ffinite-loops for C++ Richard Biener
2020-04-01 13:47 ` Jakub Jelinek
2020-04-01 13:52 ` Richard Biener
2020-04-01 15:56 ` Jan Hubicka
2020-04-01 16:59 ` Richard Biener
2020-04-01 19:15 ` Jason Merrill
2020-04-02 9:12 ` Richard Biener [this message]
2020-04-02 9:17 ` Jakub Jelinek
2020-04-02 9:41 ` Richard Biener
2020-04-03 8:29 ` Revert "[nvptx, libgomp] Update pr85381-{2, 4}.c test-cases" [PR89713, PR94392] (was: [PATCH][RFC] c/94392 - only enable -ffinite-loops for C++) Thomas Schwinge
2020-04-03 9:36 ` Revert "[nvptx, libgomp] Update pr85381-{2,4}.c " Richard Biener
2020-04-03 10:34 ` Jakub Jelinek
2020-10-30 14:09 ` Revert "[nvptx, libgomp] Update pr85381-{2, 4}.c " Thomas Schwinge
2020-10-30 14:16 ` Revert "[nvptx, libgomp] Update pr85381-{2,4}.c " Jakub Jelinek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=nycvar.YFH.7.76.2004021110110.830@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
--cc=joseph@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).