From 9851a1631f2915fafdc733539b6c8b5fb81e7ae5 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 11 Aug 2021 15:01:39 +0200 Subject: [PATCH] Fix min_flags handling in mod-ref gcc/ChangeLog: 2021-08-11 Jan Hubicka Alexandre Oliva * 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. --- gcc/ipa-modref.c | 35 ++++++++++++++++++++---------- gcc/testsuite/c-c++-common/modref-dse.c | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/modref-dse.c diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index 7b849c1..c65b2f6 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -1406,7 +1406,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); } @@ -1503,10 +1503,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; } @@ -3019,7 +3027,8 @@ struct escape_map static void update_escape_summary_1 (cgraph_edge *e, - vec > &map) + vec > &map, + bool ignore_stores) { escape_summary *sum = escape_summaries->get (e); if (!sum) @@ -3037,6 +3046,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}; @@ -3051,18 +3063,19 @@ update_escape_summary_1 (cgraph_edge *e, static void update_escape_summary (cgraph_node *node, - vec > &map) + vec > &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); } } @@ -3187,7 +3200,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 index 0000000..5f64e8f --- /dev/null +++ b/gcc/testsuite/c-c++-common/modref-dse.c @@ -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; +} -- 2.7.4