On Fri, Dec 15, 2017 at 09:34:44AM +0100, Richard Biener wrote:
> I don't like this too much.  Iff then we should do "real" lazy
> computation, like adding a TREE_SIDE_EFFECTS_VALID flag on STATEMENT_LIST,
> keeping TREE_SIDE_EFFECTS up-to-date when easily possible and when doing
> the expensive thing cache the result.  That said, I'm not convinced
> this will fix -fcompare-debug issues for good.  Is it really necessary
> to introduce this IL difference so early and in such an intrusive way?
> 
> Can't we avoid adding # DEBUG BEGIN_STMT when there's not already
> a STATEMENT_LIST around for example?

The STATEMENT_LIST handling is a complete mess.

E.g.
tree
alloc_stmt_list (void)
{
  tree list;
  if (!vec_safe_is_empty (stmt_list_cache))
    {
      list = stmt_list_cache->pop ();
      memset (list, 0, sizeof (struct tree_base));
      TREE_SET_CODE (list, STATEMENT_LIST);
    }
  else
    list = make_node (STATEMENT_LIST);

Because make_node (STATEMENT_LIST) sets TREE_SIDE_EFFECTS, but the above
memset clears it, we start with inconsistent TREE_SIDE_EFFECTS from the
beginning.

I've tried to track TREE_SIDE_EFFECTS precisely, as below, but that seems to
break completely the statement expression handling, in particular
make check-gcc check-g++ RUNTESTFLAGS="compile.exp=20030530-3.c 
debug.exp='20020224-1.c 20030605-1.c' dg.exp='Wduplicated-branches-1.c 
compare2.c gnu89-const-expr-1.c pr64637.c pr68412-2.c stmt-expr-*.c pr56419.C' 
lto.exp=pr83388* noncompile.exp=971104-1.c dg-torture.exp=pr51071.c 
tree-ssa.exp='20030711-2.c 20030714-1.c 20030731-1.c' vect.exp=pr33833.c 
tm.exp=pr56419.C"
all FAILs because of that, e.g.
gcc/testsuite/gcc.c-torture/compile/20030530-3.c:14:8: error: void value not 
ignored as it ought to be
I've also tried to track instead of tracking TREE_SIDE_EFFECTS precisely
track just ignore DEBUG_BEGIN_STMTs in the processing, but that
unfortunately doesn't help for the testcase included in the patch (attached
patch).

2017-12-18  Jakub Jelinek  <ja...@redhat.com>

        PR debug/83419
        * tree-iterator.c (alloc_stmt_list): Clear TREE_SIDE_EFFECTS for a new
        node.
        (tsi_link_after): Set TREE_SIDE_EFFECTS when adding t with
        TREE_SIDE_EFFECTS.
        (tsi_link_before): Likewise.  Formatting fix.
        (tsi_delink): Recompute TREE_SIDE_EFFECTS on removal.
        * gimplify.c (gimplify_statement_list): Clear TREE_SIDE_EFFECTS.

        * gcc.dg/pr83419.c: New test.

--- gcc/tree-iterator.c.jj      2017-12-12 09:48:26.000000000 +0100
+++ gcc/tree-iterator.c 2017-12-18 10:13:58.776212769 +0100
@@ -41,7 +41,10 @@ alloc_stmt_list (void)
       TREE_SET_CODE (list, STATEMENT_LIST);
     }
   else
-    list = make_node (STATEMENT_LIST);
+    {
+      list = make_node (STATEMENT_LIST);
+      TREE_SIDE_EFFECTS (list) = 0;
+    }
   TREE_TYPE (list) = void_type_node;
   return list;
 }
@@ -137,7 +140,7 @@ tsi_link_before (tree_stmt_iterator *i,
       tail = head;
     }
 
-  if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
+  if (TREE_SIDE_EFFECTS (t))
     TREE_SIDE_EFFECTS (i->container) = 1;
 
   cur = i->ptr;
@@ -157,9 +160,9 @@ tsi_link_before (tree_stmt_iterator *i,
     {
       head->prev = STATEMENT_LIST_TAIL (i->container);
       if (head->prev)
-       head->prev->next = head;
+       head->prev->next = head;
       else
-       STATEMENT_LIST_HEAD (i->container) = head;
+       STATEMENT_LIST_HEAD (i->container) = head;
       STATEMENT_LIST_TAIL (i->container) = tail;
     }
 
@@ -214,7 +217,7 @@ tsi_link_after (tree_stmt_iterator *i, t
       tail = head;
     }
 
-  if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
+  if (TREE_SIDE_EFFECTS (t))
     TREE_SIDE_EFFECTS (i->container) = 1;
 
   cur = i->ptr;
@@ -275,10 +278,28 @@ tsi_delink (tree_stmt_iterator *i)
   else
     STATEMENT_LIST_TAIL (i->container) = prev;
 
-  if (!next && !prev)
-    TREE_SIDE_EFFECTS (i->container) = 0;
-
   i->ptr = next;
+
+  if (TREE_SIDE_EFFECTS (i->container))
+    {
+      while (next || prev)
+       {
+         if (next)
+           {
+             if (TREE_SIDE_EFFECTS (next->stmt))
+               break;
+             next = next->next;
+           }
+         if (prev)
+           {
+             if (TREE_SIDE_EFFECTS (prev->stmt))
+               break;
+             prev = prev->prev;
+           }
+       }
+      if (next == NULL && prev == NULL)
+       TREE_SIDE_EFFECTS (i->container) = 0;
+    }
 }
 
 /* Return the first expression in a sequence of COMPOUND_EXPRs, or in
--- gcc/gimplify.c.jj   2017-12-14 21:11:40.000000000 +0100
+++ gcc/gimplify.c      2017-12-18 10:17:07.922556324 +0100
@@ -1763,6 +1763,9 @@ gimplify_statement_list (tree *expr_p, g
 
   tree_stmt_iterator i = tsi_start (*expr_p);
 
+  /* No need to recompute TREE_SIDE_EFFECTS on removal, we are going to
+     delink everything.  */
+  TREE_SIDE_EFFECTS (*expr_p) = 0;
   while (!tsi_end_p (i))
     {
       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
--- gcc/testsuite/gcc.dg/pr83419.c.jj   2017-12-18 10:08:24.214911480 +0100
+++ gcc/testsuite/gcc.dg/pr83419.c      2017-12-18 10:08:24.214911480 +0100
@@ -0,0 +1,16 @@
+/* PR debug/83419 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+int a, b;
+void foo (int, ...);
+
+void
+bar (void)
+{
+  if (a || 1 == b)
+    foo (1);
+  else
+    0;
+  foo (1, 0);
+}


        Jakub
2017-12-18  Jakub Jelinek  <ja...@redhat.com>

        PR debug/83419
        * tree-iterator.c: Include options.h.
        (alloc_stmt_list): Clear TREE_SIDE_EFFECTS for a new node.
        (tsi_link_after): Set TREE_SIDE_EFFECTS when adding STATEMENT_LIST with
        TREE_SIDE_EFFECTS or non-DEBUG_BEGIN_STMT.
        (tsi_link_before): Likewise.  Formatting fix.
        (tsi_delink): Recompute TREE_SIDE_EFFECTS on removal.
        * gimplify.c (gimplify_statement_list): Clear TREE_SIDE_EFFECTS.

        * gcc.dg/pr83419.c: New test.

--- gcc/tree-iterator.c.jj      2017-12-12 09:48:26.000000000 +0100
+++ gcc/tree-iterator.c 2017-12-18 13:44:02.330719440 +0100
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.
 #include "coretypes.h"
 #include "tree.h"
 #include "tree-iterator.h"
+#include "options.h"
 
 
 /* This is a cache of STATEMENT_LIST nodes.  We create and destroy them
@@ -41,7 +42,10 @@ alloc_stmt_list (void)
       TREE_SET_CODE (list, STATEMENT_LIST);
     }
   else
-    list = make_node (STATEMENT_LIST);
+    {
+      list = make_node (STATEMENT_LIST);
+      TREE_SIDE_EFFECTS (list) = 0;
+    }
   TREE_TYPE (list) = void_type_node;
   return list;
 }
@@ -127,6 +131,8 @@ tsi_link_before (tree_stmt_iterator *i,
          gcc_assert (head == tail);
          return;
        }
+      if (TREE_SIDE_EFFECTS (t))
+       TREE_SIDE_EFFECTS (i->container) = 1;
     }
   else
     {
@@ -135,11 +141,10 @@ tsi_link_before (tree_stmt_iterator *i,
       head->next = NULL;
       head->stmt = t;
       tail = head;
+      if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
+       TREE_SIDE_EFFECTS (i->container) = 1;
     }
 
-  if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
-    TREE_SIDE_EFFECTS (i->container) = 1;
-
   cur = i->ptr;
 
   /* Link it into the list.  */
@@ -157,9 +162,9 @@ tsi_link_before (tree_stmt_iterator *i,
     {
       head->prev = STATEMENT_LIST_TAIL (i->container);
       if (head->prev)
-       head->prev->next = head;
+       head->prev->next = head;
       else
-       STATEMENT_LIST_HEAD (i->container) = head;
+       STATEMENT_LIST_HEAD (i->container) = head;
       STATEMENT_LIST_TAIL (i->container) = tail;
     }
 
@@ -204,6 +209,9 @@ tsi_link_after (tree_stmt_iterator *i, t
          gcc_assert (head == tail);
          return;
        }
+
+      if (TREE_SIDE_EFFECTS (t))
+       TREE_SIDE_EFFECTS (i->container) = 1;
     }
   else
     {
@@ -212,10 +220,10 @@ tsi_link_after (tree_stmt_iterator *i, t
       head->next = NULL;
       head->stmt = t;
       tail = head;
-    }
 
-  if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
-    TREE_SIDE_EFFECTS (i->container) = 1;
+      if (TREE_CODE (t) != DEBUG_BEGIN_STMT)
+       TREE_SIDE_EFFECTS (i->container) = 1;
+    }
 
   cur = i->ptr;
 
@@ -275,10 +283,30 @@ tsi_delink (tree_stmt_iterator *i)
   else
     STATEMENT_LIST_TAIL (i->container) = prev;
 
-  if (!next && !prev)
-    TREE_SIDE_EFFECTS (i->container) = 0;
-
   i->ptr = next;
+
+  if (!MAY_HAVE_DEBUG_MARKER_STMTS)
+    TREE_SIDE_EFFECTS (i->container) = 0;
+  else if (TREE_SIDE_EFFECTS (i->container))
+    {
+      while (next || prev)
+       {
+         if (next)
+           {
+             if (TREE_CODE (next->stmt) != DEBUG_BEGIN_STMT)
+               break;
+             next = next->next;
+           }
+         if (prev)
+           {
+             if (TREE_CODE (prev->stmt) != DEBUG_BEGIN_STMT)
+               break;
+             prev = prev->prev;
+           }
+       }
+      if (next == NULL && prev == NULL)
+       TREE_SIDE_EFFECTS (i->container) = 0;
+    }
 }
 
 /* Return the first expression in a sequence of COMPOUND_EXPRs, or in
--- gcc/gimplify.c.jj   2017-12-14 21:11:40.000000000 +0100
+++ gcc/gimplify.c      2017-12-18 10:17:07.922556324 +0100
@@ -1763,6 +1763,9 @@ gimplify_statement_list (tree *expr_p, g
 
   tree_stmt_iterator i = tsi_start (*expr_p);
 
+  /* No need to recompute TREE_SIDE_EFFECTS on removal, we are going to
+     delink everything.  */
+  TREE_SIDE_EFFECTS (*expr_p) = 0;
   while (!tsi_end_p (i))
     {
       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
--- gcc/testsuite/gcc.dg/pr83419.c.jj   2017-12-18 10:08:24.214911480 +0100
+++ gcc/testsuite/gcc.dg/pr83419.c      2017-12-18 10:08:24.214911480 +0100
@@ -0,0 +1,16 @@
+/* PR debug/83419 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+int a, b;
+void foo (int, ...);
+
+void
+bar (void)
+{
+  if (a || 1 == b)
+    foo (1);
+  else
+    0;
+  foo (1, 0);
+}

Reply via email to