public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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
> >
>


  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).