From: Richard Biener <richard.guenther@gmail.com>
To: Aldy Hernandez <aldyh@redhat.com>
Cc: GCC patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] Reset relations when crossing backedges.
Date: Fri, 21 Jan 2022 10:43:02 +0100 [thread overview]
Message-ID: <CAFiYyc28uQq78y7YoOs5Wvk_yMkxzY5CbHMaV2VKEnXW7vWDPg@mail.gmail.com> (raw)
In-Reply-To: <20220121082901.223286-1-aldyh@redhat.com>
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.
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
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.
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 9:43 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 [this message]
2022-01-21 10:29 ` Aldy Hernandez
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=CAFiYyc28uQq78y7YoOs5Wvk_yMkxzY5CbHMaV2VKEnXW7vWDPg@mail.gmail.com \
--to=richard.guenther@gmail.com \
--cc=aldyh@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/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).