public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/riscv/heads/gcc-13-with-riscv-opts)] mode-switching: Fix the mode passed to the emit hook
@ 2023-11-21  4:11 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2023-11-21  4:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3f19003bd4661ffd5f0ee8168cef4bc6db0eddb5

commit 3f19003bd4661ffd5f0ee8168cef4bc6db0eddb5
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Sat Nov 11 17:28:56 2023 +0000

    mode-switching: Fix the mode passed to the emit hook
    
    optimize_mode_switching passes an entity's current mode (if known)
    to the emit hook.  However, the mode that it passed ignored the
    effect of the after hook.  Instead, the mode for the first emit
    call in a block was taken from the incoming mode, whereas the
    mode for each subsequent emit call was taken from the result
    of the previous call.
    
    The previous pass through the insns already calculated the
    correct mode, so this patch records it in the seginfo structure.
    (There was a 32-bit hole on 64-bit hosts, so this doesn't increase
    the size of the structure for them.)
    
    gcc/
            * mode-switching.cc (seginfo): Add a prev_mode field.
            (new_seginfo): Take and initialize the prev_mode.
            (optimize_mode_switching): Update calls accordingly.
            Use the recorded modes during the emit phase, rather than
            computing one on the fly.
    
    (cherry picked from commit 5afd208beaef50bcc43b556d4c41d41656b06436)

Diff:
---
 gcc/mode-switching.cc | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index bebe89d5fd2..12ddbd6adfa 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3.  If not see
    NEXT is the next insn in the same basic block.  */
 struct seginfo
 {
+  int prev_mode;
   int mode;
   rtx_insn *insn_ptr;
   struct seginfo *next;
@@ -140,20 +141,22 @@ commit_mode_sets (struct edge_list *edge_list, int e, struct bb_info *info)
   return need_commit;
 }
 
-/* Allocate a new BBINFO structure, initialized with the MODE, INSN,
-   and REGS_LIVE parameters.
+/* Allocate a new BBINFO structure, initialized with the PREV_MODE, MODE,
+   INSN, and REGS_LIVE parameters.
    INSN may not be a NOTE_INSN_BASIC_BLOCK, unless it is an empty
    basic block; that allows us later to insert instructions in a FIFO-like
    manner.  */
 
 static struct seginfo *
-new_seginfo (int mode, rtx_insn *insn, const HARD_REG_SET &regs_live)
+new_seginfo (int prev_mode, int mode, rtx_insn *insn,
+	     const HARD_REG_SET &regs_live)
 {
   struct seginfo *ptr;
 
   gcc_assert (!NOTE_INSN_BASIC_BLOCK_P (insn)
 	      || insn == BB_END (NOTE_BASIC_BLOCK (insn)));
   ptr = XNEW (struct seginfo);
+  ptr->prev_mode = prev_mode;
   ptr->mode = mode;
   ptr->insn_ptr = insn;
   ptr->next = NULL;
@@ -590,7 +593,7 @@ 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, ins_pos, live_now);
+		ptr = new_seginfo (no_mode, no_mode, ins_pos, live_now);
 		add_seginfo (&tail_ptr, ptr);
 		for (i = 0; i < no_mode; i++)
 		  clear_mode_bit (transp[bb->index], j, i);
@@ -606,12 +609,12 @@ optimize_mode_switching (void)
 
 		  if (mode != no_mode && mode != last_mode)
 		    {
-		      any_set_required = true;
-		      last_mode = mode;
-		      ptr = new_seginfo (mode, insn, live_now);
+		      ptr = new_seginfo (last_mode, mode, insn, live_now);
 		      add_seginfo (&tail_ptr, ptr);
 		      for (i = 0; i < no_mode; i++)
 			clear_mode_bit (transp[bb->index], j, i);
+		      any_set_required = true;
+		      last_mode = mode;
 		    }
 
 		  if (targetm.mode_switching.after)
@@ -637,7 +640,7 @@ optimize_mode_switching (void)
 	     mark the block as nontransparent.  */
 	  if (!any_set_required)
 	    {
-	      ptr = new_seginfo (no_mode, BB_END (bb), live_now);
+	      ptr = new_seginfo (last_mode, no_mode, BB_END (bb), live_now);
 	      add_seginfo (&tail_ptr, ptr);
 	      if (last_mode != no_mode)
 		for (i = 0; i < no_mode; i++)
@@ -778,9 +781,9 @@ optimize_mode_switching (void)
       FOR_EACH_BB_FN (bb, cfun)
 	{
 	  struct seginfo *ptr, *next;
-	  int cur_mode = bb_info[j][bb->index].mode_in;
+	  struct seginfo *first = bb_info[j][bb->index].seginfo;
 
-	  for (ptr = bb_info[j][bb->index].seginfo; ptr; ptr = next)
+	  for (ptr = first; ptr; ptr = next)
 	    {
 	      next = ptr->next;
 	      if (ptr->mode != no_mode)
@@ -790,14 +793,15 @@ optimize_mode_switching (void)
 		  rtl_profile_for_bb (bb);
 		  start_sequence ();
 
+		  int cur_mode = (ptr == first && ptr->prev_mode == no_mode
+				  ? bb_info[j][bb->index].mode_in
+				  : ptr->prev_mode);
+
 		  targetm.mode_switching.emit (entity_map[j], ptr->mode,
 					       cur_mode, ptr->regs_live);
 		  mode_set = get_insns ();
 		  end_sequence ();
 
-		  /* modes kill each other inside a basic block.  */
-		  cur_mode = ptr->mode;
-
 		  /* Insert MODE_SET only if it is nonempty.  */
 		  if (mode_set != NULL_RTX)
 		    {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-21  4:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-21  4:11 [gcc(refs/vendors/riscv/heads/gcc-13-with-riscv-opts)] mode-switching: Fix the mode passed to the emit hook Jeff Law

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