[PATCH] [RFA] [PR tree-optmization/69740] Schedule loop fixups when needed
Jeff Law
law@redhat.com
Fri Feb 26 07:50:00 GMT 2016
On 02/25/2016 03:00 AM, Richard Biener wrote:
>
> So I fail to see how only successor edges are relevant. Isn't the important
> case to catch whether we remove an edge marked EDGE_IRREDUCIBLE_LOOP?
> Even if the BB persists we might have exposed a new loop here.
>
> Note that it is not safe to look at {BB,EDGE}_IRREDUCIBLE_LOOP if the loop
> state does not have LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS set
> (the flags may be stale or missing). So it might be that we can't rely on
> non-loop passes modifying the CFG to handle this optimistically.
>
> Thus, how about (my main point) moving this to remove_edge instead, like
Yea. That works. The !loops_state_satisfies_p check will almost
certainly cause us to trigger loop cleanups more often, but I think it's
the right/safe thing to do to catch cases where we haven't go the
IRREDUCIBLE_LOOP flags set.
Bootstrapped and regression tested on x86_64-linux-gnu. OK for the trunk?
Thanks,
Jeff
-------------- next part --------------
PR tree-optimization/69740
* cfghooks.c (remove_edge): Request loop fixups if we delete
an edge that might turn an irreducible loop into a natural
loop.
PR tree-optimization/69740
* gcc.c-torture/compile/pr69740-1.c: New test.
* gcc.c-torture/compile/pr69740-2.c: New test.
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index bbb1017..f80e455 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -408,7 +408,14 @@ void
remove_edge (edge e)
{
if (current_loops != NULL)
- rescan_loop_exit (e, false, true);
+ {
+ rescan_loop_exit (e, false, true);
+
+ if (!loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ || (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ || (e->dest->flags & BB_IRREDUCIBLE_LOOP))
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
/* This is probably not needed, but it doesn't hurt. */
/* FIXME: This should be called via a remove_edge hook. */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c
new file mode 100644
index 0000000..ac867d8
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c
@@ -0,0 +1,12 @@
+char a;
+short b;
+void fn1() {
+ if (b)
+ ;
+ else {
+ int c[1] = {0};
+ l1:;
+ }
+ if (a)
+ goto l1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c
new file mode 100644
index 0000000..a89c9a0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c
@@ -0,0 +1,19 @@
+inline int foo(int *p1, int p2) {
+ int z = *p1;
+ while (z > p2)
+ p2 = 2;
+ return z;
+}
+int main() {
+ int i;
+ for (;;) {
+ int j, k;
+ i = foo(&k, 7);
+ if (k)
+ j = i;
+ else
+ k = j;
+ if (2 != j)
+ __builtin_abort();
+ }
+}
More information about the Gcc-patches
mailing list