public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-modules] Allow try_split to split RTX_FRAME_RELATED_P insns
@ 2020-08-28 15:59 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-08-28 15:59 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e7d55c6b81733335d81e35f7c0116bbdffccb682

commit e7d55c6b81733335d81e35f7c0116bbdffccb682
Author: Senthil Kumar Selvaraj <saaadhu@gcc.gnu.org>
Date:   Thu Aug 13 13:19:26 2020 +0530

    Allow try_split to split RTX_FRAME_RELATED_P insns
    
    Instead of rejecting RTX_FRAME_RELATED_P insns, allow try_split to split
    such insns, provided the split is after reload, and the result of the split
    is a single insn.
    
    recog.c:peep2_attempt already splits an RTX_FRAME_RELATED_P insn splitting
    to a single insn. This patch refactors existing code copying frame related
    info to a separate function (copy_frame_info_to_split_insn) and calls it
    from both peep2_attempt and try_split.
    
    2020-08-21  Senthil Kumar Selvaraj  <saaadhu@gcc.gnu.org>
    
    gcc/ChangeLog:
    
            * emit-rtl.c (try_split): Call copy_frame_info_to_split_insn
            to split certain RTX_FRAME_RELATED_P insns.
            * recog.c (copy_frame_info_to_split_insn): New function.
            (peep2_attempt): Split copying of frame related info of
            RTX_FRAME_RELATED_P insns into above function and call it.
            * recog.h (copy_frame_info_to_split_insn): Declare it.

Diff:
---
 gcc/emit-rtl.c |  19 ++++++--
 gcc/recog.c    | 134 +++++++++++++++++++++++++++++++--------------------------
 gcc/recog.h    |   2 +
 3 files changed, 90 insertions(+), 65 deletions(-)

diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index f9b0e9714d9..3706f0a03fd 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3822,10 +3822,6 @@ try_split (rtx pat, rtx_insn *trial, int last)
   int njumps = 0;
   rtx_insn *call_insn = NULL;
 
-  /* We're not good at redistributing frame information.  */
-  if (RTX_FRAME_RELATED_P (trial))
-    return trial;
-
   if (any_condjump_p (trial)
       && (note = find_reg_note (trial, REG_BR_PROB, 0)))
     split_branch_probability
@@ -3842,6 +3838,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
   if (!seq)
     return trial;
 
+  int split_insn_count = 0;
   /* Avoid infinite loop if any insn of the result matches
      the original pattern.  */
   insn_last = seq;
@@ -3850,11 +3847,25 @@ try_split (rtx pat, rtx_insn *trial, int last)
       if (INSN_P (insn_last)
 	  && rtx_equal_p (PATTERN (insn_last), pat))
 	return trial;
+      split_insn_count++;
       if (!NEXT_INSN (insn_last))
 	break;
       insn_last = NEXT_INSN (insn_last);
     }
 
+  /* We're not good at redistributing frame information if
+     the split occurs before reload or if it results in more
+     than one insn.  */
+  if (RTX_FRAME_RELATED_P (trial))
+    {
+      if (!reload_completed || split_insn_count != 1)
+        return trial;
+
+      rtx_insn *new_insn = seq;
+      rtx_insn *old_insn = trial;
+      copy_frame_info_to_split_insn (old_insn, new_insn);
+    }
+
   /* We will be adding the new sequence to the function.  The splitters
      may have introduced invalid RTL sharing, so unshare the sequence now.  */
   unshare_all_rtl_in_chain (seq);
diff --git a/gcc/recog.c b/gcc/recog.c
index 25f19b1b1cf..ce83b7f5218 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3277,6 +3277,78 @@ peep2_reinit_state (regset live)
   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
 }
 
+/* Copies frame related info of an insn (OLD_INSN) to the single
+   insn (NEW_INSN) that was obtained by splitting OLD_INSN.  */
+
+void
+copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
+{
+  bool any_note = false;
+  rtx note;
+
+  if (!RTX_FRAME_RELATED_P (old_insn))
+    return;
+
+  RTX_FRAME_RELATED_P (new_insn) = 1;
+
+  /* Allow the backend to fill in a note during the split.  */
+  for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
+    switch (REG_NOTE_KIND (note))
+      {
+      case REG_FRAME_RELATED_EXPR:
+      case REG_CFA_DEF_CFA:
+      case REG_CFA_ADJUST_CFA:
+      case REG_CFA_OFFSET:
+      case REG_CFA_REGISTER:
+      case REG_CFA_EXPRESSION:
+      case REG_CFA_RESTORE:
+      case REG_CFA_SET_VDRAP:
+        any_note = true;
+        break;
+      default:
+        break;
+      }
+
+  /* If the backend didn't supply a note, copy one over.  */
+  if (!any_note)
+    for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
+      switch (REG_NOTE_KIND (note))
+        {
+        case REG_FRAME_RELATED_EXPR:
+        case REG_CFA_DEF_CFA:
+        case REG_CFA_ADJUST_CFA:
+        case REG_CFA_OFFSET:
+        case REG_CFA_REGISTER:
+        case REG_CFA_EXPRESSION:
+        case REG_CFA_RESTORE:
+        case REG_CFA_SET_VDRAP:
+          add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
+          any_note = true;
+          break;
+        default:
+          break;
+        }
+
+  /* If there still isn't a note, make sure the unwind info sees the
+     same expression as before the split.  */
+  if (!any_note)
+    {
+      rtx old_set, new_set;
+
+      /* The old insn had better have been simple, or annotated.  */
+      old_set = single_set (old_insn);
+      gcc_assert (old_set != NULL);
+
+      new_set = single_set (new_insn);
+      if (!new_set || !rtx_equal_p (new_set, old_set))
+        add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
+    }
+
+  /* Copy prologue/epilogue status.  This is required in order to keep
+     proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
+  maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
+}
+
 /* While scanning basic block BB, we found a match of length MATCH_LEN,
    starting at INSN.  Perform the replacement, removing the old insns and
    replacing them with ATTEMPT.  Returns the last insn emitted, or NULL
@@ -3297,9 +3369,6 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
   old_insn = peep2_insn_data[peep2_current].insn;
   if (RTX_FRAME_RELATED_P (old_insn))
     {
-      bool any_note = false;
-      rtx note;
-
       if (match_len != 0)
 	return NULL;
 
@@ -3313,64 +3382,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
 	return NULL;
 
       /* We have a 1-1 replacement.  Copy over any frame-related info.  */
-      RTX_FRAME_RELATED_P (new_insn) = 1;
-
-      /* Allow the backend to fill in a note during the split.  */
-      for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
-	switch (REG_NOTE_KIND (note))
-	  {
-	  case REG_FRAME_RELATED_EXPR:
-	  case REG_CFA_DEF_CFA:
-	  case REG_CFA_ADJUST_CFA:
-	  case REG_CFA_OFFSET:
-	  case REG_CFA_REGISTER:
-	  case REG_CFA_EXPRESSION:
-	  case REG_CFA_RESTORE:
-	  case REG_CFA_SET_VDRAP:
-	    any_note = true;
-	    break;
-	  default:
-	    break;
-	  }
-
-      /* If the backend didn't supply a note, copy one over.  */
-      if (!any_note)
-        for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
-	  switch (REG_NOTE_KIND (note))
-	    {
-	    case REG_FRAME_RELATED_EXPR:
-	    case REG_CFA_DEF_CFA:
-	    case REG_CFA_ADJUST_CFA:
-	    case REG_CFA_OFFSET:
-	    case REG_CFA_REGISTER:
-	    case REG_CFA_EXPRESSION:
-	    case REG_CFA_RESTORE:
-	    case REG_CFA_SET_VDRAP:
-	      add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
-	      any_note = true;
-	      break;
-	    default:
-	      break;
-	    }
-
-      /* If there still isn't a note, make sure the unwind info sees the
-	 same expression as before the split.  */
-      if (!any_note)
-	{
-	  rtx old_set, new_set;
-
-	  /* The old insn had better have been simple, or annotated.  */
-	  old_set = single_set (old_insn);
-	  gcc_assert (old_set != NULL);
-
-	  new_set = single_set (new_insn);
-	  if (!new_set || !rtx_equal_p (new_set, old_set))
-	    add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
-	}
-
-      /* Copy prologue/epilogue status.  This is required in order to keep
-	 proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
-      maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
+      copy_frame_info_to_split_insn (old_insn, new_insn);
     }
 
   /* If we are splitting a CALL_INSN, look for the CALL_INSN
diff --git a/gcc/recog.h b/gcc/recog.h
index 3e4b55bdf3f..ae3675f5c82 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -150,6 +150,8 @@ extern rtx_insn *peephole2_insns (rtx, rtx_insn *, int *);
 extern int store_data_bypass_p (rtx_insn *, rtx_insn *);
 extern int if_test_bypass_p (rtx_insn *, rtx_insn *);
 
+extern void copy_frame_info_to_split_insn (rtx_insn *, rtx_insn *);
+
 #ifndef GENERATOR_FILE
 /* Try recognizing the instruction INSN,
    and return the code number that results.


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

only message in thread, other threads:[~2020-08-28 15:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-28 15:59 [gcc/devel/c++-modules] Allow try_split to split RTX_FRAME_RELATED_P insns Nathan Sidwell

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