From: Richard Sandiford <richard.sandiford@arm.com>
To: jlaw@ventanamicro.com, gcc-patches@gcc.gnu.org
Cc: Richard Sandiford <richard.sandiford@arm.com>
Subject: [PATCH 6/6] rtl-ssa: Handle call clobbers in more places
Date: Tue, 24 Oct 2023 11:50:06 +0100 [thread overview]
Message-ID: <20231024105006.3337671-7-richard.sandiford@arm.com> (raw)
In-Reply-To: <20231024105006.3337671-1-richard.sandiford@arm.com>
In order to save (a lot of) memory, RTL-SSA avoids creating
individual clobber records for every call-clobbered register.
It instead maintains a list & splay tree of calls in an EBB,
grouped by ABI.
This patch takes these call clobbers into account in a couple
more routines. I don't think this will have any effect on
existing users, since it's only necessary for hard registers.
gcc/
* rtl-ssa/access-utils.h (next_call_clobbers): New function.
(is_single_dominating_def, remains_available_on_exit): Replace with...
* rtl-ssa/functions.h (function_info::is_single_dominating_def)
(function_info::remains_available_on_exit): ...these new member
functions.
(function_info::m_clobbered_by_calls): New member variable.
* rtl-ssa/functions.cc (function_info::function_info): Explicitly
initialize m_clobbered_by_calls.
* rtl-ssa/insns.cc (function_info::record_call_clobbers): Update
m_clobbered_by_calls for each call-clobber note.
* rtl-ssa/member-fns.inl (function_info::is_single_dominating_def):
New function. Check for call clobbers.
* rtl-ssa/accesses.cc (function_info::remains_available_on_exit):
Likewise.
---
gcc/rtl-ssa/access-utils.h | 27 +++++++++------------------
gcc/rtl-ssa/accesses.cc | 25 +++++++++++++++++++++++++
gcc/rtl-ssa/functions.cc | 2 +-
gcc/rtl-ssa/functions.h | 14 ++++++++++++++
gcc/rtl-ssa/insns.cc | 2 ++
gcc/rtl-ssa/member-fns.inl | 9 +++++++++
6 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/gcc/rtl-ssa/access-utils.h b/gcc/rtl-ssa/access-utils.h
index 84d386b7d8b..0d7a57f843c 100644
--- a/gcc/rtl-ssa/access-utils.h
+++ b/gcc/rtl-ssa/access-utils.h
@@ -127,24 +127,6 @@ set_with_nondebug_insn_uses (access_info *access)
return nullptr;
}
-// Return true if SET is the only set of SET->resource () and if it
-// dominates all uses (excluding uses of SET->resource () at points
-// where SET->resource () is always undefined).
-inline bool
-is_single_dominating_def (const set_info *set)
-{
- return set->is_first_def () && set->is_last_def ();
-}
-
-// SET is known to be available on entry to BB. Return true if it is
-// also available on exit from BB. (The value might or might not be live.)
-inline bool
-remains_available_on_exit (const set_info *set, bb_info *bb)
-{
- return (set->is_last_def ()
- || *set->next_def ()->insn () > *bb->end_insn ());
-}
-
// ACCESS is known to be associated with an instruction rather than
// a phi node. Return which instruction that is.
inline insn_info *
@@ -313,6 +295,15 @@ next_call_clobbers_ignoring (insn_call_clobbers_tree &tree, insn_info *insn,
return tree->insn ();
}
+// Search forwards from immediately after INSN for the first instruction
+// recorded in TREE. Return null if no such instruction exists.
+inline insn_info *
+next_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn)
+{
+ auto ignore = [](const insn_info *) { return false; };
+ return next_call_clobbers_ignoring (tree, insn, ignore);
+}
+
// If ACCESS is a set, return the first use of ACCESS by a nondebug insn I
// for which IGNORE (I) is false. Return null if ACCESS is not a set or if
// no such use exists.
diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
index 774ab9d99ee..c35c7efb73d 100644
--- a/gcc/rtl-ssa/accesses.cc
+++ b/gcc/rtl-ssa/accesses.cc
@@ -1303,6 +1303,31 @@ function_info::insert_temp_clobber (obstack_watermark &watermark,
return insert_access (watermark, clobber, old_defs);
}
+// See the comment above the declaration.
+bool
+function_info::remains_available_on_exit (const set_info *set, bb_info *bb)
+{
+ if (HARD_REGISTER_NUM_P (set->regno ())
+ && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
+ {
+ insn_info *search_insn = (set->bb () == bb
+ ? set->insn ()
+ : bb->head_insn ());
+ for (ebb_call_clobbers_info *call_group : bb->ebb ()->call_clobbers ())
+ {
+ if (!call_group->clobbers (set->resource ()))
+ continue;
+
+ insn_info *insn = next_call_clobbers (*call_group, search_insn);
+ if (insn && insn->bb () == bb)
+ return false;
+ }
+ }
+
+ return (set->is_last_def ()
+ || *set->next_def ()->insn () > *bb->end_insn ());
+}
+
// A subroutine of make_uses_available. Try to make USE's definition
// available at the head of BB. WILL_BE_DEBUG_USE is true if the
// definition will be used only in debug instructions.
diff --git a/gcc/rtl-ssa/functions.cc b/gcc/rtl-ssa/functions.cc
index c35d25dbf8f..8a8108baae8 100644
--- a/gcc/rtl-ssa/functions.cc
+++ b/gcc/rtl-ssa/functions.cc
@@ -32,7 +32,7 @@
using namespace rtl_ssa;
function_info::function_info (function *fn)
- : m_fn (fn)
+ : m_fn (fn), m_clobbered_by_calls ()
{
// Force the alignment to be obstack_alignment. Everything else is normal.
obstack_specify_allocation (&m_obstack, OBSTACK_CHUNK_SIZE,
diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h
index cd90b6aa9df..ab253e750cb 100644
--- a/gcc/rtl-ssa/functions.h
+++ b/gcc/rtl-ssa/functions.h
@@ -102,6 +102,11 @@ public:
// definitions by things like phi nodes.
iterator_range<def_iterator> reg_defs (unsigned int regno) const;
+ // Return true if SET is the only set of SET->resource () and if it
+ // dominates all uses (excluding uses of SET->resource () at points
+ // where SET->resource () is always undefined).
+ bool is_single_dominating_def (const set_info *set) const;
+
// Check if all uses of register REGNO are either unconditionally undefined
// or use the same single dominating definition. Return the definition
// if so, otherwise return null.
@@ -116,6 +121,11 @@ public:
// scope until the change has been aborted or successfully completed.
obstack_watermark new_change_attempt () { return &m_temp_obstack; }
+ // SET either occurs in BB or is known to be available on entry to BB.
+ // Return true if it is also available on exit from BB. (The value
+ // might or might not be live.)
+ bool remains_available_on_exit (const set_info *set, bb_info *bb);
+
// Make a best attempt to check whether the values used by USES are
// available on entry to BB, without solving a full dataflow problem.
// If all the values are already live on entry to BB or can be made
@@ -357,6 +367,10 @@ private:
// on it. As with M_QUEUED_INSN_UPDATES, these updates are queued until
// a convenient point.
auto_bitmap m_need_to_purge_dead_edges;
+
+ // The set of hard registers that are fully or partially clobbered
+ // by at least one insn_call_clobbers_note.
+ HARD_REG_SET m_clobbered_by_calls;
};
void pp_function (pretty_printer *, const function_info *);
diff --git a/gcc/rtl-ssa/insns.cc b/gcc/rtl-ssa/insns.cc
index f970375d906..5fde3f2bb4b 100644
--- a/gcc/rtl-ssa/insns.cc
+++ b/gcc/rtl-ssa/insns.cc
@@ -568,6 +568,8 @@ function_info::record_call_clobbers (build_info &bi, insn_info *insn,
insn->add_note (insn_clobbers);
ecc->insert_max_node (insn_clobbers);
+
+ m_clobbered_by_calls |= abi.full_and_partial_reg_clobbers ();
}
else
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
diff --git a/gcc/rtl-ssa/member-fns.inl b/gcc/rtl-ssa/member-fns.inl
index 3fdca14e0ef..ce2db045b78 100644
--- a/gcc/rtl-ssa/member-fns.inl
+++ b/gcc/rtl-ssa/member-fns.inl
@@ -916,6 +916,15 @@ function_info::reg_defs (unsigned int regno) const
return { m_defs[regno + 1], nullptr };
}
+inline bool
+function_info::is_single_dominating_def (const set_info *set) const
+{
+ return (set->is_first_def ()
+ && set->is_last_def ()
+ && (!HARD_REGISTER_NUM_P (set->regno ())
+ || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
+}
+
inline set_info *
function_info::single_dominating_def (unsigned int regno) const
{
--
2.25.1
next prev parent reply other threads:[~2023-10-24 10:50 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-24 10:50 [PATCH 0/6] rtl-ssa: Various fixes needed for the late-combine pass Richard Sandiford
2023-10-24 10:50 ` [PATCH 1/6] rtl-ssa: Ensure global registers are live on exit Richard Sandiford
2023-10-24 17:21 ` Jeff Law
2023-10-24 10:50 ` [PATCH 2/6] rtl-ssa: Create REG_UNUSED notes after all pending changes Richard Sandiford
2023-10-24 17:22 ` Jeff Law
2023-10-24 10:50 ` [PATCH 3/6] rtl-ssa: Fix ICE when deleting memory clobbers Richard Sandiford
2023-10-24 17:24 ` Jeff Law
2023-10-24 10:50 ` [PATCH 4/6] rtl-ssa: Handle artifical uses of deleted defs Richard Sandiford
2023-10-24 17:26 ` Jeff Law
2023-10-24 10:50 ` [PATCH 5/6] rtl-ssa: Calculate dominance frontiers for the exit block Richard Sandiford
2023-10-24 17:28 ` Jeff Law
2023-10-24 10:50 ` Richard Sandiford [this message]
2023-10-24 17:37 ` [PATCH 6/6] rtl-ssa: Handle call clobbers in more places Jeff Law
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=20231024105006.3337671-7-richard.sandiford@arm.com \
--to=richard.sandiford@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jlaw@ventanamicro.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).