Hello,

In these PRs we deal with the dependencies we are forced to make between a
debug insn and its previous insn (unless bb head).  In the latter case, if
such an insn has been moved, we fixup its movement so it aligns with the
sel-sched invariants.  We also carefully adjust seqnos in the case we had a
single debug insn left in the block.

Best,
Andrey

2018-04-03  Andrey Belevantsev  <a...@ispras.ru>

        PR rtl-optimization/80463
        PR rtl-optimization/83972
        PR rtl-optimization/83480

        * sel-sched-ir.c (has_dependence_note_mem_dep): Take into account the
correct producer for the insn.
        (tidy_control_flow): Fixup seqnos in case of debug insns.

        * gcc.dg/pr80463.c: New test.
        * g++.dg/pr80463.C: Likewise.
        * gcc.dg/pr83972.c: Likewise.

diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index a965d2ec42f..f6de96a7f3d 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3293,11 +3293,22 @@ has_dependence_note_mem_dep (rtx mem ATTRIBUTE_UNUSED,

 /* Note a dependence.  */
 static void
-has_dependence_note_dep (insn_t pro ATTRIBUTE_UNUSED,
+has_dependence_note_dep (insn_t pro,
                         ds_t ds ATTRIBUTE_UNUSED)
 {
-  if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
-                                      VINSN_INSN_RTX
(has_dependence_data.con)))
+  insn_t real_pro = has_dependence_data.pro;
+  insn_t real_con = VINSN_INSN_RTX (has_dependence_data.con);
+
+  /* We do not allow for debug insns to move through others unless they
+     are at the start of bb.  Such insns may create bookkeeping copies
+     that would not be able to move up breaking sel-sched invariants.
+     Detect that here and allow that movement if we allowed it before
+     in the first place.  */
+  if (DEBUG_INSN_P (real_con)
+      && INSN_UID (NEXT_INSN (pro)) == INSN_UID (real_con))
+    return;
+
+  if (!sched_insns_conditions_mutex_p (real_pro, real_con))
     {
       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];

@@ -3890,6 +3905,19 @@ tidy_control_flow (basic_block xbb, bool full_tidying)

       gcc_assert (EDGE_SUCC (xbb->prev_bb, 0)->flags & EDGE_FALLTHRU);

+      /* We could have skipped some debug insns which did not get removed
with the block,
+         and the seqnos could become incorrect.  Fix them up here.  */
+      if (MAY_HAVE_DEBUG_INSNS && (sel_bb_head (xbb) != first ||
sel_bb_end (xbb) != last))
+       {
+         if (!sel_bb_empty_p (xbb->prev_bb))
+           {
+             int prev_seqno = INSN_SEQNO (sel_bb_end (xbb->prev_bb));
+             if (prev_seqno > INSN_SEQNO (sel_bb_head (xbb)))
+               for (insn_t insn = sel_bb_head (xbb); insn != first; insn =
NEXT_INSN (insn))
+                 INSN_SEQNO (insn) = prev_seqno + 1;
+           }
+       }
+
       /* It can turn out that after removing unused jump, basic block
          that contained that jump, becomes empty too.  In such case
          remove it too.  */
diff --git a/gcc/testsuite/g++.dg/pr80463.C b/gcc/testsuite/g++.dg/pr80463.C
new file mode 100644
index 00000000000..5614c28ca45
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr80463.C
@@ -0,0 +1,20 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-g -fselective-scheduling2 -O2
-fvar-tracking-assignments" } */
+
+int *a;
+int b, c;
+void
+d ()
+{
+  for (int e; c; e++)
+    switch (e)
+      {
+      case 0:
+       a[e] = 1;
+      case 1:
+       b = 2;
+       break;
+      default:
+       a[e] = 3;
+      }
+}
diff --git a/gcc/testsuite/gcc.dg/pr80463.c b/gcc/testsuite/gcc.dg/pr80463.c
new file mode 100644
index 00000000000..cebf2fef1f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr80463.c
@@ -0,0 +1,54 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-g -O2 -fvar-tracking-assignments -fselective-scheduling2
-ftree-loop-vectorize -fnon-call-exceptions -fno-tree-vrp -fno-gcse-lm
-fno-tree-loop-im -fno-reorder-blocks-and-partition -fno-reorder-blocks
-fno-move-loop-invariants -w" } */
+
+short int t2;
+int cd, aa, ft;
+
+void
+dh (void)
+{
+  int qs = 0;
+
+  if (t2 < 1)
+    {
+      int bq = 0;
+
+      while (bq < 1)
+        {
+        }
+
+      while (t2 < 1)
+        {
+          if (t2 == 0)
+            {
+              bq = 0;
+              cd = !!cd;
+            }
+          else
+            {
+              bq = 1;
+              cd = bq > qs;
+            }
+
+          t2 += cd;
+          bq = (t2 / qs) == bq;
+
+          if (aa != ft)
+            {
+              qs %= 0;
+              while (bq != 0)
+                {
+ ro:
+                  ;
+                }
+            }
+
+          ++t2;
+        }
+
+ ia:
+      goto ro;
+    }
+
+  goto ia;
+}
diff --git a/gcc/testsuite/gcc.dg/pr83972.c b/gcc/testsuite/gcc.dg/pr83972.c
new file mode 100644
index 00000000000..b8de42cef0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr83972.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O1 -fschedule-insns -fselective-scheduling
-fsel-sched-pipelining -fvar-tracking-assignments -funroll-loops
-fno-tree-dominator-opts -w" } */
+
+int s7, p0;
+
+void
+i0 (int ke)
+{
+  while (ke < 1)
+    {
+      if (s7 == 0)
+        p0 = 0;
+      else
+        {
+          if (p0 == 0)
+            s7 = 0;
+
+          if (!!s7 || !!p0)
+            s7 = 0;
+          else
+            p0 = 0;
+        }
+
+      ++ke;
+    }
+}





Reply via email to