diff options
author | Jan Hubicka <jh@suse.cz> | 2021-08-11 15:01:39 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2021-08-11 15:01:39 +0200 |
commit | 9851a1631f2915fafdc733539b6c8b5fb81e7ae5 (patch) | |
tree | 6ec5d79b94267126a39a6ce0c68e22be7c40c170 /gcc | |
parent | d7e91f4894f6a1a2daeec5cbe1e912bb896b9f7a (diff) | |
download | gcc-9851a1631f2915fafdc733539b6c8b5fb81e7ae5.zip gcc-9851a1631f2915fafdc733539b6c8b5fb81e7ae5.tar.gz gcc-9851a1631f2915fafdc733539b6c8b5fb81e7ae5.tar.bz2 |
Fix min_flags handling in mod-ref
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-modref.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/modref-dse.c | 38 |
2 files changed, 62 insertions, 11 deletions
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 <vec <escape_map>> &map) + vec <vec <escape_map>> &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 <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); } } @@ -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; +} |