]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix min_flags handling in mod-ref
authorJan Hubicka <jh@suse.cz>
Wed, 11 Aug 2021 13:01:39 +0000 (15:01 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 7 Apr 2022 10:45:19 +0000 (12:45 +0200)
gcc/ChangeLog:

2021-08-11  Jan Hubicka  <hubicka@ucw.cz>
    Alexandre Oliva  <oliva@adacore.com>

* ipa-modref.c (modref_lattice::dump): Fix escape_point's min_flags
dumping.
(modref_lattice::merge_deref): Fix handling of indirect scape points.
(update_escape_summary_1): Likewise.
(update_escape_summary): Likewise.
(ipa_merge_modref_summary_after_inlining): Likewise.

gcc/testsuite/ChangeLog:

* c-c++-common/modref-dse.c: New test.

(cherry picked from commit 9851a1631f2915fafdc733539b6c8b5fb81e7ae5)

gcc/ipa-modref.c
gcc/testsuite/c-c++-common/modref-dse.c [new file with mode: 0644]

index 597ed6ef7fa0b3b13b5fbb333bb7049f4869a61a..0fe168e04f18e76be18d3423e38038fc706bc405 100644 (file)
@@ -1392,7 +1392,7 @@ modref_lattice::dump (FILE *out, int indent) const
          fprintf (out, "%*s  Arg %i (%s) min flags", indent, "",
                   escape_points[i].arg,
                   escape_points[i].direct ? "direct" : "indirect");
-         dump_eaf_flags (out, flags, false);
+         dump_eaf_flags (out, escape_points[i].min_flags, false);
          fprintf (out, " in call ");
          print_gimple_stmt (out, escape_points[i].call, 0);
        }
@@ -1489,10 +1489,18 @@ modref_lattice::merge_deref (const modref_lattice &with, bool ignore_stores)
   if (!flags)
     return changed;
   for (unsigned int i = 0; i < with.escape_points.length (); i++)
-    changed |= add_escape_point (with.escape_points[i].call,
-                                with.escape_points[i].arg,
-                                with.escape_points[i].min_flags,
-                                false);
+    {
+      int min_flags = with.escape_points[i].min_flags;
+
+      if (with.escape_points[i].direct)
+       min_flags = deref_flags (min_flags, ignore_stores);
+      else if (ignore_stores)
+       min_flags |= EAF_NOCLOBBER | EAF_NOESCAPE | EAF_NODIRECTESCAPE;
+      changed |= add_escape_point (with.escape_points[i].call,
+                                  with.escape_points[i].arg,
+                                  min_flags,
+                                  false);
+    }
   return changed;
 }
 
@@ -3001,7 +3009,8 @@ struct escape_map
 
 static void
 update_escape_summary_1 (cgraph_edge *e,
-                        vec <vec <escape_map>> &map)
+                        vec <vec <escape_map>> &map,
+                        bool ignore_stores)
 {
   escape_summary *sum = escape_summaries->get (e);
   if (!sum)
@@ -3019,6 +3028,9 @@ update_escape_summary_1 (cgraph_edge *e,
        continue;
       FOR_EACH_VEC_ELT (map[ee->parm_index], j, em)
        {
+         int min_flags = ee->min_flags;
+         if (ee->direct && !em->direct)
+           min_flags = deref_flags (min_flags, ignore_stores);
          struct escape_entry entry = {em->parm_index, ee->arg,
                                       ee->min_flags,
                                       ee->direct & em->direct};
@@ -3033,18 +3045,19 @@ update_escape_summary_1 (cgraph_edge *e,
 
 static void
 update_escape_summary (cgraph_node *node,
-                      vec <vec <escape_map>> &map)
+                      vec <vec <escape_map>> &map,
+                      bool ignore_stores)
 {
   if (!escape_summaries)
     return;
   for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
-    update_escape_summary_1 (e, map);
+    update_escape_summary_1 (e, map, ignore_stores);
   for (cgraph_edge *e = node->callees; e; e = e->next_callee)
     {
       if (!e->inline_failed)
-       update_escape_summary (e->callee, map);
+       update_escape_summary (e->callee, map, ignore_stores);
       else
-       update_escape_summary_1 (e, map);
+       update_escape_summary_1 (e, map, ignore_stores);
     }
 }
 
@@ -3169,7 +3182,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
        if (needed)
          emap[ee->arg].safe_push (entry);
       }
-  update_escape_summary (edge->callee, emap);
+  update_escape_summary (edge->callee, emap, ignore_stores);
   for (i = 0; (int)i < max_escape + 1; i++)
     emap[i].release ();
   if (sum)
diff --git a/gcc/testsuite/c-c++-common/modref-dse.c b/gcc/testsuite/c-c++-common/modref-dse.c
new file mode 100644 (file)
index 0000000..5f64e8f
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dse2-details" } */
+/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse2" } } */
+
+struct foo { unsigned long bar; };
+
+unsigned y;
+
+static int __attribute__ ((__noinline__, __noclone__))
+wrapped (struct foo *p, int i);
+
+static int wrapper (struct foo *p);
+
+static int __attribute__ ((__noclone__))
+wrapper (struct foo *p) {
+  return wrapped (p, 1);
+}
+
+static int __attribute__ ((__noinline__, __noclone__))
+dind (struct foo **pp);
+
+int __attribute__ ((__noclone__, __no_reorder__))
+xfn () {
+  struct foo x = { 0xBADC0FFE };
+  struct foo *p = &x;
+  return dind (&p);
+}
+
+static int __attribute__ ((__noinline__, __no_reorder__))
+wrapped (struct foo *p, int i) {
+  return p->bar + i == y++;
+}
+
+static int __attribute__ ((__noinline__, __noclone__, __no_reorder__))
+dind (struct foo **pp) {
+  wrapper (*pp);
+  return 0;
+}