Re: [PATCH 12/12] mode-switching: Add a backprop hook

2023-11-09 Thread Jeff Law




On 11/5/23 11:50, Richard Sandiford wrote:

This patch adds a way for targets to ask that selected mode changes
be brought forward, through a combination of:

(1) requiring a mode in blocks where the entity was previously
 transparent

(2) pushing the transition at the head of a block onto incomging edges

SME has two uses for this:

- A "one-shot" entity that, for any given path of execution,
   either stays off or makes exactly one transition from off to on.
   This relies only on (1) above; see the hook description for more info.

   The main purpose of using mode-switching for this entity is to
   shrink-wrap the code that requires it.

- A second entity for which all transitions must be from known
   modes, which is enforced using a combination of (1) and (2).
   More specifically, (1) looks for edges B1->B2 for which:

   - B2 requires a specific mode and
   - B1 does not guarantee a specific starting mode

   In this system, such an edge is only possible if the entity is
   transparent in B1.  (1) then forces B1 to require some safe common
   mode.  Applying this inductively means that all incoming edges are
   from known modes.  If different edges give different starting modes,
   (2) pushes the transitions onto the edges themselves; this only
   happens if the entity is not transparent in some predecessor block.

The patch also uses the back-propagation as an excuse to do a simple
on-the-fly optimisation.

Hopefully the comments in the patch explain things a bit better.

gcc/
* target.def (mode_switching.backprop): New hook.
* doc/tm.texi.in (TARGET_MODE_BACKPROP): New @hook.
* doc/tm.texi: Regenerate.
* mode-switching.cc (struct bb_info): Add single_succ.
(confluence_info): Add transp field.
(single_succ_confluence_n, single_succ_transfer): New functions.
(backprop_confluence_n, backprop_transfer): Likewise.
(optimize_mode_switching): Use them.  Push mode transitions onto
a block's incoming edges, if the backprop hook requires it.
OK.  Really curious if we might be able to use this to improve the 
vsetvl bits in the RISC-V backend.


Jeff



[PATCH 12/12] mode-switching: Add a backprop hook

2023-11-05 Thread Richard Sandiford
This patch adds a way for targets to ask that selected mode changes
be brought forward, through a combination of:

(1) requiring a mode in blocks where the entity was previously
transparent

(2) pushing the transition at the head of a block onto incomging edges

SME has two uses for this:

- A "one-shot" entity that, for any given path of execution,
  either stays off or makes exactly one transition from off to on.
  This relies only on (1) above; see the hook description for more info.

  The main purpose of using mode-switching for this entity is to
  shrink-wrap the code that requires it.

- A second entity for which all transitions must be from known
  modes, which is enforced using a combination of (1) and (2).
  More specifically, (1) looks for edges B1->B2 for which:

  - B2 requires a specific mode and
  - B1 does not guarantee a specific starting mode

  In this system, such an edge is only possible if the entity is
  transparent in B1.  (1) then forces B1 to require some safe common
  mode.  Applying this inductively means that all incoming edges are
  from known modes.  If different edges give different starting modes,
  (2) pushes the transitions onto the edges themselves; this only
  happens if the entity is not transparent in some predecessor block.

The patch also uses the back-propagation as an excuse to do a simple
on-the-fly optimisation.

Hopefully the comments in the patch explain things a bit better.

gcc/
* target.def (mode_switching.backprop): New hook.
* doc/tm.texi.in (TARGET_MODE_BACKPROP): New @hook.
* doc/tm.texi: Regenerate.
* mode-switching.cc (struct bb_info): Add single_succ.
(confluence_info): Add transp field.
(single_succ_confluence_n, single_succ_transfer): New functions.
(backprop_confluence_n, backprop_transfer): Likewise.
(optimize_mode_switching): Use them.  Push mode transitions onto
a block's incoming edges, if the backprop hook requires it.
---
 gcc/doc/tm.texi   |  28 +
 gcc/doc/tm.texi.in|   2 +
 gcc/mode-switching.cc | 272 ++
 gcc/target.def|  29 +
 4 files changed, 331 insertions(+)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cd346538fe2..d83ca73b1af 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10456,6 +10456,34 @@ The hook should return the number of modes if no 
suitable mode exists
 for the given arguments.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_MODE_BACKPROP (int @var{entity}, int 
@var{mode1}, int @var{mode2})
+If defined, the mode-switching pass uses this hook to back-propagate mode
+requirements through blocks that have no mode requirements of their own.
+Specifically, @var{mode1} is the mode that @var{entity} has on exit
+from a block B1 (say) and @var{mode2} is the mode that the next block
+requires @var{entity} to have.  B1 does not have any mode requirements
+of its own.
+
+The hook should return the mode that it prefers or requires @var{entity}
+to have in B1, or the number of modes if there is no such requirement.
+If the hook returns a required mode for more than one of B1's outgoing
+edges, those modes are combined as for @code{TARGET_MODE_CONFLUENCE}.
+
+For example, suppose there is a ``one-shot'' entity that,
+for a given execution of a function, either stays off or makes exactly
+one transition from off to on.  It is safe to make the transition at any
+time, but it is better not to do so unnecessarily.  This hook allows the
+function to manage such an entity without having to track its state at
+runtime.  Specifically. the entity would have two modes, 0 for off and
+1 for on, with 2 representing ``don't know''.  The system is forbidden from
+transitioning from 2 to 1, since 2 represents the possibility that the
+entity is already on (and the aim is to avoid having to emit code to
+check for that case).  This hook would therefore return 1 when @var{mode1}
+is 2 and @var{mode2} is 1, which would force the entity to be on in the
+source block.  Applying this inductively would remove all transitions
+in which the previous state is unknown.
+@end deftypefn
+
 @deftypefn {Target Hook} int TARGET_MODE_ENTRY (int @var{entity})
 If this hook is defined, it is evaluated for every @var{entity} that
 needs mode switching.  It should return the mode that @var{entity} is
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ae23241ea1c..3d3ae12cc2f 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -6977,6 +6977,8 @@ mode or ``no mode'', depending on context.
 
 @hook TARGET_MODE_CONFLUENCE
 
+@hook TARGET_MODE_BACKPROP
+
 @hook TARGET_MODE_ENTRY
 
 @hook TARGET_MODE_EXIT
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index 87b23d2c050..720c30df72d 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -81,6 +81,7 @@ struct bb_info
   int computing;
   int mode_out;
   int mode_in;
+  int single_succ;
 };
 
 /* Clear ode I from entity J in bitmap