From: Aldy Hernandez <aldyh@redhat.com>
To: Richard Biener <richard.guenther@gmail.com>
Cc: GCC patches <gcc-patches@gcc.gnu.org>,
Jeff Law <jeffreyalaw@gmail.com>,
"MacLeod, Andrew" <amacleod@redhat.com>
Subject: Re: [PATCH] Reset relations when crossing backedges.
Date: Fri, 21 Jan 2022 11:29:52 +0100 [thread overview]
Message-ID: <CAGm3qMUUif_YBA8NCwJr0TVk8H616Wo8A-nNv3BY+JFEYtpnNg@mail.gmail.com> (raw)
In-Reply-To: <CAFiYyc28uQq78y7YoOs5Wvk_yMkxzY5CbHMaV2VKEnXW7vWDPg@mail.gmail.com>
On Fri, Jan 21, 2022 at 10:43 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Fri, Jan 21, 2022 at 9:30 AM Aldy Hernandez via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > As discussed in PR103721, the problem here is that we are crossing a
> > backedge and causing us to use relations from a previous iteration of a
> > loop.
> >
> > This handles the testcases in both PR103721 and PR104067 which are variants
> > of the same thing.
> >
> > Tested on x86-64 Linux with the usual regstrap as well as verifying the
> > thread count before and after the patch. The number of threads is
> > reduced by a miniscule amount.
> >
> > I assume we need release manager approval at this point? OK for trunk?
>
> Not for regression fixes.
OK, I've pushed it to fix the P1s. We can continue refining the
solution in a follow-up patch.
>
> Btw, I wonder whether you have to treat irreducible regions in the same
> way more generally - which edges are marked as backedge there depends
> on which edge into the region was visited first. I also wonder how we
Jeff, Andrew??
> I also wonder how we guarantee that all users of the resolve mode have backedges marked
> properly? Also note that CFG manipulation routines in general do not
> keep backedge markings up-to-date so incremental modification and
> resolving queries might not mix.
>
> It's a bit unfortunate that we can't query the CFG on whether backedges
> are marked.
Ughh. The call to mark_dfs_back_edges is currently in the backward
threader. Perhaps we could put it in the path_range_query
constructor? That way other users of path_range_query can benefit
(loop_ch for instance, though it doesn't use it in a way that crosses
backedges so perhaps it's unaffected). Does that sound reasonable?
Aldy
>
> If you're only dealing with non-irreducible regions you can use a
> dominance query to identify a backedge. Oh, and irreducible regions
> are also not marked (but at least CFG manipulation tries to conservatively
> keep that info up-to-date).
>
> > gcc/ChangeLog:
> >
> > PR 103721/tree-optimization
>
> swapped, it should be PR tree-optimization/103721
>
> > * gimple-range-path.cc
> > (path_range_query::relations_may_be_invalidated): New.
> > (path_range_query::compute_ranges_in_block): Reset relations if
> > they may be invalidated.
> > (path_range_query::maybe_register_phi_relation): Exit if relations
> > may be invalidated on incoming edge.
> > (path_range_query::compute_phi_relations): Pass incoming PHI edge
> > to maybe_register_phi_relation.
> > * gimple-range-path.h (relations_may_be_invalidated): New.
> > (maybe_register_phi_relation): Pass edge instead of tree.
> > * tree-ssa-threadbackward.cc (back_threader::back_threader):
> > * value-relation.cc (path_oracle::path_oracle): Call
> > mark_dfs_back_edges.
> > (path_oracle::register_relation): Add SSA names to m_registered
> > bitmap.
> > (path_oracle::reset_path): Clear m_registered bitmap.
> > * value-relation.h (path_oracle::set_root_oracle): New.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.dg/pr103721-2.c: New test.
> > * gcc.dg/pr103721.c: New test.
> > ---
> > gcc/gimple-range-path.cc | 48 +++++++++++++++++++++++++++----
> > gcc/gimple-range-path.h | 3 +-
> > gcc/testsuite/gcc.dg/pr103721-2.c | 28 ++++++++++++++++++
> > gcc/testsuite/gcc.dg/pr103721.c | 25 ++++++++++++++++
> > gcc/tree-ssa-threadbackward.cc | 4 +++
> > gcc/value-relation.cc | 4 +--
> > gcc/value-relation.h | 1 +
> > 7 files changed, 104 insertions(+), 9 deletions(-)
> > create mode 100644 gcc/testsuite/gcc.dg/pr103721-2.c
> > create mode 100644 gcc/testsuite/gcc.dg/pr103721.c
> >
> > diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
> > index a1bcca0b5fb..3ee4989f4b0 100644
> > --- a/gcc/gimple-range-path.cc
> > +++ b/gcc/gimple-range-path.cc
> > @@ -400,6 +400,19 @@ path_range_query::compute_ranges_in_phis (basic_block bb)
> > bitmap_ior_into (m_has_cache_entry, phi_set);
> > }
> >
> > +// Return TRUE if relations may be invalidated after crossing edge E.
> > +
> > +bool
> > +path_range_query::relations_may_be_invalidated (edge e)
> > +{
> > + // As soon as the path crosses a back edge, we can encounter
> > + // definitions of SSA_NAMEs that may have had a use in the path
> > + // already, so this will then be a new definition. The relation
> > + // code is all designed around seeing things in dominator order, and
> > + // crossing a back edge in the path violates this assumption.
> > + return (e->flags & EDGE_DFS_BACK);
> > +}
> > +
> > // Compute ranges defined in the current block, or exported to the
> > // next block.
> >
> > @@ -440,6 +453,22 @@ path_range_query::compute_ranges_in_block (basic_block bb)
> > // Solve imports that are exported to the next block.
> > basic_block next = next_bb ();
> > edge e = find_edge (bb, next);
> > +
> > + if (m_resolve && relations_may_be_invalidated (e))
> > + {
> > + if (DEBUG_SOLVER)
> > + fprintf (dump_file,
> > + "Resetting relations as they may be invalidated in %d->%d.\n",
> > + e->src->index, e->dest->index);
> > +
> > + path_oracle *p = get_path_oracle ();
> > + p->reset_path ();
> > + // ?? Instead of nuking the root oracle altogether, we could
> > + // reset the path oracle to search for relations from the top of
> > + // the loop with the root oracle. Something for future development.
> > + p->set_root_oracle (nullptr);
> > + }
> > +
> > EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
> > {
> > tree name = ssa_name (i);
> > @@ -742,9 +771,19 @@ path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
> > return true;
> > }
> >
> > +// If possible, register the relation on the incoming edge E into PHI.
> > +
> > void
> > -path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
> > +path_range_query::maybe_register_phi_relation (gphi *phi, edge e)
> > {
> > + tree arg = gimple_phi_arg_def (phi, e->dest_idx);
> > +
> > + if (!gimple_range_ssa_p (arg))
> > + return;
> > +
> > + if (relations_may_be_invalidated (e))
> > + return;
> > +
> > basic_block bb = gimple_bb (phi);
> > tree result = gimple_phi_result (phi);
> >
> > @@ -754,7 +793,7 @@ path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
> > return;
> >
> > if (dump_file && (dump_flags & TDF_DETAILS))
> > - fprintf (dump_file, " from bb%d:", bb->index);
> > + fprintf (dump_file, "maybe_register_phi_relation in bb%d:", bb->index);
> >
> > get_path_oracle ()->killing_def (result);
> > m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result);
> > @@ -787,10 +826,7 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
> > for (size_t i = 0; i < nargs; ++i)
> > if (e_in == gimple_phi_arg_edge (phi, i))
> > {
> > - tree arg = gimple_phi_arg_def (phi, i);
> > -
> > - if (gimple_range_ssa_p (arg))
> > - maybe_register_phi_relation (phi, arg);
> > + maybe_register_phi_relation (phi, e_in);
> > break;
> > }
> > }
> > diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
> > index f090b7c2727..1820626161f 100644
> > --- a/gcc/gimple-range-path.h
> > +++ b/gcc/gimple-range-path.h
> > @@ -63,10 +63,11 @@ private:
> > void ssa_range_in_phi (irange &r, gphi *phi);
> > void compute_outgoing_relations (basic_block bb, basic_block next);
> > void compute_phi_relations (basic_block bb, basic_block prev);
> > - void maybe_register_phi_relation (gphi *, tree arg);
> > + void maybe_register_phi_relation (gphi *, edge e);
> > bool add_to_imports (tree name, bitmap imports);
> > bool import_p (tree name);
> > bool ssa_defined_in_bb (tree name, basic_block bb);
> > + bool relations_may_be_invalidated (edge);
> >
> > // Path navigation.
> > void set_path (const vec<basic_block> &);
> > diff --git a/gcc/testsuite/gcc.dg/pr103721-2.c b/gcc/testsuite/gcc.dg/pr103721-2.c
> > new file mode 100644
> > index 00000000000..aefa1f0f147
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr103721-2.c
> > @@ -0,0 +1,28 @@
> > +// { dg-do run }
> > +// { dg-options "-O2" }
> > +
> > +extern void abort ();
> > +struct S { int x; } a[10];
> > +struct S *b;
> > +
> > +int
> > +main ()
> > +{
> > + int i, j = 0;
> > + struct S *q = a;
> > +
> > + for (i = 100; --i > 0; )
> > + {
> > + struct S *p;
> > + j++;
> > + if (j >= 10)
> > + j = 0;
> > + p = &a[j];
> > +
> > + if (p == q)
> > + abort ();
> > + __atomic_thread_fence (__ATOMIC_SEQ_CST);
> > + q = p;
> > + }
> > + return 0;
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/pr103721.c b/gcc/testsuite/gcc.dg/pr103721.c
> > new file mode 100644
> > index 00000000000..6ec2e44b30f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr103721.c
> > @@ -0,0 +1,25 @@
> > +// { dg-do run }
> > +// { dg-options "-O2" }
> > +
> > +int ipos = 0;
> > +int f (int world)
> > +{
> > + int searchVolume = world;
> > + int currentVolume = 0;
> > + while (currentVolume != searchVolume && searchVolume) {
> > + currentVolume = searchVolume;
> > + if (ipos != 0)
> > + searchVolume = 0;
> > + else
> > + searchVolume = 1;
> > + }
> > + return (currentVolume);
> > +}
> > +int main()
> > +{
> > + const int i = f (1111);
> > + __builtin_printf ("%d\n", (int)(i));
> > + if (i != 1)
> > + __builtin_abort ();
> > + return 0;
> > +}
> > diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
> > index d685b659df0..3ca65b32216 100644
> > --- a/gcc/tree-ssa-threadbackward.cc
> > +++ b/gcc/tree-ssa-threadbackward.cc
> > @@ -144,6 +144,10 @@ back_threader::back_threader (function *fun, unsigned flags, bool first)
> > m_flags = flags;
> > m_solver = new path_range_query (flags & BT_RESOLVE);
> > m_last_stmt = NULL;
> > +
> > + // The path solver needs EDGE_DFS_BACK in resolving mode.
> > + if (flags & BT_RESOLVE)
> > + mark_dfs_back_edges ();
> > }
> >
> > back_threader::~back_threader ()
> > diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
> > index 32ca693c464..fcb574553df 100644
> > --- a/gcc/value-relation.cc
> > +++ b/gcc/value-relation.cc
> > @@ -1234,7 +1234,7 @@ relation_oracle::debug () const
> >
> > path_oracle::path_oracle (relation_oracle *oracle)
> > {
> > - m_root = oracle;
> > + set_root_oracle (oracle);
> > bitmap_obstack_initialize (&m_bitmaps);
> > obstack_init (&m_chain_obstack);
> >
> > @@ -1368,7 +1368,7 @@ path_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1,
> > value_relation vr (k, ssa1, ssa2);
> > fprintf (dump_file, " Registering value_relation (path_oracle) ");
> > vr.dump (dump_file);
> > - fprintf (dump_file, " (bb%d)\n", bb->index);
> > + fprintf (dump_file, " (root: bb%d)\n", bb->index);
> > }
> >
> > if (k == EQ_EXPR)
> > diff --git a/gcc/value-relation.h b/gcc/value-relation.h
> > index 44d0796d939..848ffd3dab0 100644
> > --- a/gcc/value-relation.h
> > +++ b/gcc/value-relation.h
> > @@ -227,6 +227,7 @@ public:
> > relation_kind query_relation (basic_block, tree, tree);
> > relation_kind query_relation (basic_block, const_bitmap, const_bitmap);
> > void reset_path ();
> > + void set_root_oracle (relation_oracle *oracle) { m_root = oracle; }
> > void dump (FILE *, basic_block) const;
> > void dump (FILE *) const;
> > private:
> > --
> > 2.34.1
> >
>
next prev parent reply other threads:[~2022-01-21 10:30 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-21 8:29 Aldy Hernandez
2022-01-21 9:43 ` Richard Biener
2022-01-21 10:29 ` Aldy Hernandez [this message]
2022-01-21 10:56 ` Richard Biener
2022-01-21 12:11 ` Aldy Hernandez
2022-01-24 8:50 ` Richard Biener
2022-01-24 19:20 ` Aldy Hernandez
2022-02-01 18:41 ` Aldy Hernandez
2022-02-02 9:27 ` Richard Biener
2022-03-19 19:27 ` Jeff Law
2022-03-21 7:49 ` Richard Biener
2022-01-24 22:58 ` Jeff Law
2022-02-09 17:43 ` Martin Jambor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAGm3qMUUif_YBA8NCwJr0TVk8H616Wo8A-nNv3BY+JFEYtpnNg@mail.gmail.com \
--to=aldyh@redhat.com \
--cc=amacleod@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jeffreyalaw@gmail.com \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).