From: Alex Coplan <alex.coplan@arm.com>
To: gcc-patches@gcc.gnu.org, Kyrylo Tkachov <kyrylo.tkachov@arm.com>,
richard.sandiford@arm.com
Subject: Re: [PATCH 01/11] rtl-ssa: Support for inserting new insns
Date: Wed, 22 Nov 2023 14:44:06 +0000 [thread overview]
Message-ID: <ZV4TtntBhrZl9ipD@arm.com> (raw)
In-Reply-To: <mptsf4zjpdu.fsf@arm.com>
On 21/11/2023 11:51, Richard Sandiford wrote:
> Alex Coplan <alex.coplan@arm.com> writes:
> > N.B. this is just a rebased (but otherwise unchanged) version of the
> > same patch already posted here:
> >
> > https://gcc.gnu.org/pipermail/gcc-patches/2023-October/633348.html
> >
> > this is the only unreviewed dependency from the previous series, so it
> > seemed easier just to re-post it (not least to appease the pre-commit
> > CI).
> >
> > -- >8 --
> >
> > The upcoming aarch64 load pair pass needs to form store pairs, and can
> > re-order stores over loads when alias analysis determines this is safe.
> > In the case that both mem defs have uses in the RTL-SSA IR, and both
> > stores require re-ordering over their uses, we represent that as
> > (tentative) deletion of the original store insns and creation of a new
> > insn, to prevent requiring repeated re-parenting of uses during the
> > pass. We then update all mem uses that require re-parenting in one go
> > at the end of the pass.
> >
> > To support this, RTL-SSA needs to handle inserting new insns (rather
> > than just changing existing ones), so this patch adds support for that.
> >
> > New insns (and new accesses) are temporaries, allocated above a temporary
> > obstack_watermark, such that the user can easily back out of a change without
> > awkward bookkeeping.
> >
> > Bootstrapped/regtested as a series on aarch64-linux-gnu, OK for trunk?
> >
> > gcc/ChangeLog:
> >
> > * rtl-ssa/accesses.cc (function_info::create_set): New.
> > * rtl-ssa/accesses.h (access_info::is_temporary): New.
> > * rtl-ssa/changes.cc (move_insn): Handle new (temporary) insns.
> > (function_info::finalize_new_accesses): Handle new/temporary
> > user-created accesses.
> > (function_info::apply_changes_to_insn): Ensure m_is_temp flag
> > on new insns gets cleared.
> > (function_info::change_insns): Handle new/temporary insns.
> > (function_info::create_insn): New.
> > * rtl-ssa/changes.h (class insn_change): Make function_info a
> > friend class.
> > * rtl-ssa/functions.h (function_info): Declare new entry points:
> > create_set, create_insn. Declare new change_alloc helper.
> > * rtl-ssa/insns.cc (insn_info::print_full): Identify temporary insns in
> > dump.
> > * rtl-ssa/insns.h (insn_info): Add new m_is_temp flag and accompanying
> > is_temporary accessor.
> > * rtl-ssa/internals.inl (insn_info::insn_info): Initialize m_is_temp to
> > false.
> > * rtl-ssa/member-fns.inl (function_info::change_alloc): New.
> > * rtl-ssa/movement.h (restrict_movement_for_defs_ignoring): Add
> > handling for temporary defs.
>
> Looks good, but there were a couple of things I didn't understand:
Thanks for the review.
>
> > ---
> > gcc/rtl-ssa/accesses.cc | 10 ++++++
> > gcc/rtl-ssa/accesses.h | 4 +++
> > gcc/rtl-ssa/changes.cc | 74 +++++++++++++++++++++++++++++++-------
> > gcc/rtl-ssa/changes.h | 2 ++
> > gcc/rtl-ssa/functions.h | 14 ++++++++
> > gcc/rtl-ssa/insns.cc | 5 +++
> > gcc/rtl-ssa/insns.h | 7 +++-
> > gcc/rtl-ssa/internals.inl | 1 +
> > gcc/rtl-ssa/member-fns.inl | 12 +++++++
> > gcc/rtl-ssa/movement.h | 8 ++++-
> > 10 files changed, 123 insertions(+), 14 deletions(-)
> >
> > diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
> > index 510545a8bad..76d70fd8bd3 100644
> > --- a/gcc/rtl-ssa/accesses.cc
> > +++ b/gcc/rtl-ssa/accesses.cc
> > @@ -1456,6 +1456,16 @@ function_info::make_uses_available (obstack_watermark &watermark,
> > return use_array (new_uses, num_uses);
> > }
> >
> > +set_info *
> > +function_info::create_set (obstack_watermark &watermark,
> > + insn_info *insn,
> > + resource_info resource)
> > +{
> > + auto set = change_alloc<set_info> (watermark, insn, resource);
> > + set->m_is_temp = true;
> > + return set;
> > +}
> > +
> > // Return true if ACCESS1 can represent ACCESS2 and if ACCESS2 can
> > // represent ACCESS1.
> > static bool
> > diff --git a/gcc/rtl-ssa/accesses.h b/gcc/rtl-ssa/accesses.h
> > index fce31d46717..7e7a90ece97 100644
> > --- a/gcc/rtl-ssa/accesses.h
> > +++ b/gcc/rtl-ssa/accesses.h
> > @@ -204,6 +204,10 @@ public:
> > // in the main instruction pattern.
> > bool only_occurs_in_notes () const { return m_only_occurs_in_notes; }
> >
> > + // Return true if this is a temporary access, e.g. one created for
> > + // an insn that is about to be inserted.
> > + bool is_temporary () const { return m_is_temp; }
> > +
> > protected:
> > access_info (resource_info, access_kind);
> >
> > diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
> > index aab532b9f26..da2a61d701a 100644
> > --- a/gcc/rtl-ssa/changes.cc
> > +++ b/gcc/rtl-ssa/changes.cc
> > @@ -394,14 +394,20 @@ move_insn (insn_change &change, insn_info *after)
> > // At the moment we don't support moving instructions between EBBs,
> > // but this would be worth adding if it's useful.
> > insn_info *insn = change.insn ();
> > - gcc_assert (after->ebb () == insn->ebb ());
> > +
> > bb_info *bb = after->bb ();
> > basic_block cfg_bb = bb->cfg_bb ();
> >
> > - if (insn->bb () != bb)
> > - // Force DF to mark the old block as dirty.
> > - df_insn_delete (rtl);
> > - ::remove_insn (rtl);
> > + if (!insn->is_temporary ())
> > + {
> > + gcc_assert (after->ebb () == insn->ebb ());
> > +
> > + if (insn->bb () != bb)
> > + // Force DF to mark the old block as dirty.
> > + df_insn_delete (rtl);
> > + ::remove_insn (rtl);
> > + }
> > +
> > ::add_insn_after (rtl, after_rtl, cfg_bb);
> > }
> >
> > @@ -439,10 +445,15 @@ function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
> > gcc_assert (def);
> > if (def->m_is_temp)
> > {
> > - // At present, the only temporary instruction definitions we
> > - // create are clobbers, such as those added during recog.
> > - gcc_assert (is_a<clobber_info *> (def));
> > - def = allocate<clobber_info> (change.insn (), ref.regno);
> > + if (is_a<clobber_info *> (def))
> > + def = allocate<clobber_info> (change.insn (), ref.regno);
> > + else if (is_a<set_info *> (def))
> > + {
> > + def->m_is_temp = false;
> > + def = allocate<set_info> (change.insn (), def->resource ());
>
> Why is it necessary to clear is_temp on the old temporary set,
> when it wasn't for the temporary clobber?
In the case of a store pair insn (in the parallel form), I think we will
see two writes of memory in properties.refs (). If we're inserting a
new stp insn with a newly-created set of memory, then we must ensure
that we only try to add one def of memory to m_temp_defs, or we will get
an invalid access array.
If we don't clear m_is_temp on the old def, then we will allocate and push two
defs of memory in this case, which is clearly wrong. I don't think the same
situation can happen with clobbers. AIUI, non-memory resources can only have at
most one write in properties.refs ().
Having said that, and having looked again at the code more closely, I
don't think clearing the flag alone is the right solution, as the second
time we process a memory write in this case, we will call
record_reference against the old (temporary) def, and thus any changes
made by record_reference will be lost.
I think instead we should replace the temporary def with the
newly-allocated (permanent) def in change.new_defs, and then push a
pointer to this new def to m_temp_defs.
So perhaps we could use find_access_index instead of find_access, and
in the case that we find a temporary def, do something like:
def = allocate<set_info> (change.insn (), def->resource ());
change.new_defs[def_index] = def;
WDYT?
>
> > + }
> > + else
> > + gcc_unreachable ();
> > }
> > else if (!def->m_has_been_superceded)
> > {
> > @@ -511,7 +522,9 @@ function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
> > unsigned int i = 0;
> > for (use_info *use : change.new_uses)
> > {
> > - if (!use->m_has_been_superceded)
> > + if (use->m_is_temp)
> > + use->m_has_been_superceded = true;
> > + else if (!use->m_has_been_superceded)
>
> Where do the temporary uses come from? It doesn't look like this patch
> itself provided a new means of creating them.
Ah, sorry, I think this is a hold-over from a previous iteration of the
patch where we did provide an entry point for creating new uses. I
dropped it in favour of teaching RTL-SSA to infer uses of mem
(g:505f1202e3a1a1aecd0df10d0f1620df6fea4ab5).
I'll drop this in the next iteration of the patch.
Thanks,
Alex
>
> Thanks,
> Richard
>
> > {
> > use = allocate_temp<use_info> (insn, use->resource (), use->def ());
> > use->m_has_been_superceded = true;
> > @@ -645,6 +658,8 @@ function_info::apply_changes_to_insn (insn_change &change)
> >
> > insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
> > }
> > +
> > + insn->m_is_temp = false;
> > }
> >
prev parent reply other threads:[~2023-11-22 14:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-16 18:06 Alex Coplan
2023-11-21 11:51 ` Richard Sandiford
2023-11-22 14:44 ` Alex Coplan [this message]
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=ZV4TtntBhrZl9ipD@arm.com \
--to=alex.coplan@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=kyrylo.tkachov@arm.com \
--cc=richard.sandiford@arm.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).