[07/12] mode-switching: Allow targets to set the mode for EH handlers

Message ID mpty1fc6npe.fsf@arm.com
State Unresolved
Headers
Series Tweaks and extensions to the mode-switching pass |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Richard Sandiford Nov. 5, 2023, 6:48 p.m. UTC
  The mode-switching pass already had hooks to say what mode
an entity is in on entry to a function and what mode it must
be in on return.  For SME, we also want to say what mode an
entity is guaranteed to be in on entry to an exception handler.

gcc/
	* target.def (mode_switching.eh_handler): New hook.
	* doc/tm.texi.in (TARGET_MODE_EH_HANDLER): New @hook.
	* doc/tm.texi: Regenerate.
	* mode-switching.cc (optimize_mode_switching): Use eh_handler
	to get the mode on entry to an exception handler.
---
 gcc/doc/tm.texi       | 6 ++++++
 gcc/doc/tm.texi.in    | 2 ++
 gcc/mode-switching.cc | 5 ++++-
 gcc/target.def        | 7 +++++++
 4 files changed, 19 insertions(+), 1 deletion(-)
  

Comments

Jeff Law Nov. 7, 2023, 1:07 a.m. UTC | #1
On 11/5/23 11:48, Richard Sandiford wrote:
> The mode-switching pass already had hooks to say what mode
> an entity is in on entry to a function and what mode it must
> be in on return.  For SME, we also want to say what mode an
> entity is guaranteed to be in on entry to an exception handler.
> 
> gcc/
> 	* target.def (mode_switching.eh_handler): New hook.
> 	* doc/tm.texi.in (TARGET_MODE_EH_HANDLER): New @hook.
> 	* doc/tm.texi: Regenerate.
> 	* mode-switching.cc (optimize_mode_switching): Use eh_handler
> 	to get the mode on entry to an exception handler.
Can we ever have a path to the exception handler triggered by a normal 
control flow and if so, presumably we want this to apply in that case too?

It looks like that's the semantics of the implementation by way to using 
bb_has_eh_pred.  Just want to make sure that's the semantics you want in 
that oddball case.

Assuming it is the semantics you want, it's OK for the trunk, though you 
might want to twiddle the docs slightly to mention that case.

jeff
  
Richard Sandiford Nov. 8, 2023, 12:15 a.m. UTC | #2
Thanks for the reviews.

Jeff Law <jeffreyalaw@gmail.com> writes:
> On 11/5/23 11:48, Richard Sandiford wrote:
>> The mode-switching pass already had hooks to say what mode
>> an entity is in on entry to a function and what mode it must
>> be in on return.  For SME, we also want to say what mode an
>> entity is guaranteed to be in on entry to an exception handler.
>> 
>> gcc/
>> 	* target.def (mode_switching.eh_handler): New hook.
>> 	* doc/tm.texi.in (TARGET_MODE_EH_HANDLER): New @hook.
>> 	* doc/tm.texi: Regenerate.
>> 	* mode-switching.cc (optimize_mode_switching): Use eh_handler
>> 	to get the mode on entry to an exception handler.
> Can we ever have a path to the exception handler triggered by a normal 
> control flow and if so, presumably we want this to apply in that case too?

Not directly AFAIK.  The handler has to handle the EH_DATA_REGNOs,
call __cxa_begin_catch, etc.  So even if there is fall-through at
the source level, I think there'd always be a block that is only
reached through abnormal control flow.  So...

> It looks like that's the semantics of the implementation by way to using 
> bb_has_eh_pred.  Just want to make sure that's the semantics you want in 
> that oddball case.
>
> Assuming it is the semantics you want, it's OK for the trunk, though you 
> might want to twiddle the docs slightly to mention that case.

...I think these EH blocks are pure re-entry points.  I suppose some
targets might have entities whose state is call-preserved, so that it's
not changed by EH edges.  But that might also apply to other abnormal
control flow too, so it's probably a separate issue/feature.

Thanks,
Richard
  
Jeff Law Nov. 8, 2023, 2:24 a.m. UTC | #3
On 11/7/23 17:15, Richard Sandiford wrote:
> Thanks for the reviews.
> 
> Jeff Law <jeffreyalaw@gmail.com> writes:
>> On 11/5/23 11:48, Richard Sandiford wrote:
>>> The mode-switching pass already had hooks to say what mode
>>> an entity is in on entry to a function and what mode it must
>>> be in on return.  For SME, we also want to say what mode an
>>> entity is guaranteed to be in on entry to an exception handler.
>>>
>>> gcc/
>>> 	* target.def (mode_switching.eh_handler): New hook.
>>> 	* doc/tm.texi.in (TARGET_MODE_EH_HANDLER): New @hook.
>>> 	* doc/tm.texi: Regenerate.
>>> 	* mode-switching.cc (optimize_mode_switching): Use eh_handler
>>> 	to get the mode on entry to an exception handler.
>> Can we ever have a path to the exception handler triggered by a normal
>> control flow and if so, presumably we want this to apply in that case too?
> 
> Not directly AFAIK.  The handler has to handle the EH_DATA_REGNOs,
> call __cxa_begin_catch, etc.  So even if there is fall-through at
> the source level, I think there'd always be a block that is only
> reached through abnormal control flow.  So...
> 
>> It looks like that's the semantics of the implementation by way to using
>> bb_has_eh_pred.  Just want to make sure that's the semantics you want in
>> that oddball case.
>>
>> Assuming it is the semantics you want, it's OK for the trunk, though you
>> might want to twiddle the docs slightly to mention that case.
> 
> ...I think these EH blocks are pure re-entry points.  I suppose some
> targets might have entities whose state is call-preserved, so that it's
> not changed by EH edges.  But that might also apply to other abnormal
> control flow too, so it's probably a separate issue/feature.
OK.  I wouldn't be surprised if there's state that wouldn't be correct 
if we had code which jumped directly into the EH handler path.  Makes me 
wonder if the C++ language might actually prohibit such shenanigans.

Jeff
  

Patch

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 759331a2c96..1a825c5004e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10455,6 +10455,12 @@  If @code{TARGET_MODE_EXIT} is defined then @code{TARGET_MODE_ENTRY}
 must be defined.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_MODE_EH_HANDLER (int @var{entity})
+If this hook is defined, it should return the mode that @var{entity} is
+guaranteed to be in on entry to an exception handler, or the number of modes
+if there is no such guarantee.
+@end deftypefn
+
 @deftypefn {Target Hook} int TARGET_MODE_PRIORITY (int @var{entity}, int @var{n})
 This hook specifies the order in which modes for @var{entity}
 are processed. 0 is the highest priority,
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index a7b7aa289d8..5360c1bb2d8 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -6979,6 +6979,8 @@  mode or ``no mode'', depending on context.
 
 @hook TARGET_MODE_EXIT
 
+@hook TARGET_MODE_EH_HANDLER
+
 @hook TARGET_MODE_PRIORITY
 
 @node Target Attributes
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index 1145350ca26..b8a887d81f7 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -597,7 +597,10 @@  optimize_mode_switching (void)
 		gcc_assert (NOTE_INSN_BASIC_BLOCK_P (ins_pos));
 		if (ins_pos != BB_END (bb))
 		  ins_pos = NEXT_INSN (ins_pos);
-		ptr = new_seginfo (no_mode, no_mode, ins_pos, live_now);
+		if (bb_has_eh_pred (bb)
+		    && targetm.mode_switching.eh_handler)
+		  last_mode = targetm.mode_switching.eh_handler (e);
+		ptr = new_seginfo (no_mode, last_mode, ins_pos, live_now);
 		add_seginfo (&tail_ptr, ptr);
 		bitmap_clear_bit (transp_all, bb->index);
 	      }
diff --git a/gcc/target.def b/gcc/target.def
index 3dae33522f1..a70275b8abd 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7070,6 +7070,13 @@  If @code{TARGET_MODE_EXIT} is defined then @code{TARGET_MODE_ENTRY}\n\
 must be defined.",
  int, (int entity), NULL)
 
+DEFHOOK
+(eh_handler,
+ "If this hook is defined, it should return the mode that @var{entity} is\n\
+guaranteed to be in on entry to an exception handler, or the number of modes\n\
+if there is no such guarantee.",
+ int, (int entity), NULL)
+
 DEFHOOK
 (priority,
  "This hook specifies the order in which modes for @var{entity}\n\