public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2871] [RFA] Minor improvement to coremark, avoid unconditional jump to return
@ 2022-09-26 13:41 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2022-09-26 13:41 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1b74b5cb4e9d7191f298245063a8f9c3a1bbeff4

commit r13-2871-g1b74b5cb4e9d7191f298245063a8f9c3a1bbeff4
Author: Jeff Law <jeffreyalaw@gmail.com>
Date:   Sun Sep 25 12:23:59 2022 -0400

    [RFA] Minor improvement to coremark, avoid unconditional jump to return
    
    gcc/
            * cfgcleanup.cc (bb_is_just_return): No longer static.
            * cfgcleanup.h (bb_is_just_return): Add prototype.
            * cfgrtl.cc (fixup_reorder_chain): Do not create an
            unconditional jump to a return block.  Conditionally
            remove unreachable blocks.
    
    gcc/testsuite/
    
            * gcc.target/riscv/ret-1.c: New test.

Diff:
---
 gcc/cfgcleanup.cc                      |  2 +-
 gcc/cfgcleanup.h                       |  1 +
 gcc/cfgrtl.cc                          | 29 +++++++++++++++++++++++-
 gcc/testsuite/gcc.target/riscv/ret-1.c | 41 ++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc
index a8b0139bb4d..a363e0b4da3 100644
--- a/gcc/cfgcleanup.cc
+++ b/gcc/cfgcleanup.cc
@@ -2599,7 +2599,7 @@ trivially_empty_bb_p (basic_block bb)
    return value.  Fill in *RET and *USE with the return and use insns
    if any found, otherwise NULL.  All CLOBBERs are ignored.  */
 
-static bool
+bool
 bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
 {
   *ret = *use = NULL;
diff --git a/gcc/cfgcleanup.h b/gcc/cfgcleanup.h
index a6d882f98a4..f1021ca835f 100644
--- a/gcc/cfgcleanup.h
+++ b/gcc/cfgcleanup.h
@@ -30,5 +30,6 @@ extern int flow_find_head_matching_sequence (basic_block, basic_block,
 extern bool delete_unreachable_blocks (void);
 extern void delete_dead_jumptables (void);
 extern bool cleanup_cfg (int);
+extern bool bb_is_just_return (basic_block, rtx_insn **, rtx_insn **);
 
 #endif /* GCC_CFGCLEANUP_H */
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index a05c338a4c8..90cd6ee56a7 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -3901,6 +3901,7 @@ fixup_reorder_chain (void)
   /* Now add jumps and labels as needed to match the blocks new
      outgoing edges.  */
 
+  bool remove_unreachable_blocks = false;
   for (bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; bb ; bb = (basic_block)
        bb->aux)
     {
@@ -4043,10 +4044,30 @@ fixup_reorder_chain (void)
 	    continue;
 	}
 
+      /* If E_FALL->dest is just a return block, then we can emit a
+	 return rather than a jump to the return block.  */
+      rtx_insn *ret, *use;
+      basic_block dest;
+      if (bb_is_just_return (e_fall->dest, &ret, &use)
+	  && (PATTERN (ret) == simple_return_rtx || PATTERN (ret) == ret_rtx))
+	{
+	  ret_label = PATTERN (ret);
+	  dest = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
+	  /* E_FALL->dest might become unreachable as a result of
+	     replacing the jump with a return.  So arrange to remove
+	     unreachable blocks.  */
+	  remove_unreachable_blocks = true;
+	}
+      else
+	{
+	  dest = e_fall->dest;
+	}
+
       /* We got here if we need to add a new jump insn. 
 	 Note force_nonfallthru can delete E_FALL and thus we have to
 	 save E_FALL->src prior to the call to force_nonfallthru.  */
-      nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
+      nb = force_nonfallthru_and_redirect (e_fall, dest, ret_label);
       if (nb)
 	{
 	  nb->aux = bb->aux;
@@ -4134,6 +4155,12 @@ fixup_reorder_chain (void)
 		  ei_next (&ei2);
 	    }
       }
+
+  /* Replacing a jump with a return may have exposed an unreachable
+     block.  Conditionally remove them if such transformations were
+     made.  */
+  if (remove_unreachable_blocks)
+    delete_unreachable_blocks ();
 }
 \f
 /* Perform sanity checks on the insn chain.
diff --git a/gcc/testsuite/gcc.target/riscv/ret-1.c b/gcc/testsuite/gcc.target/riscv/ret-1.c
new file mode 100644
index 00000000000..28133aa4226
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ret-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* This was extracted from coremark.  */
+
+
+typedef signed short ee_s16;
+typedef struct list_data_s
+{
+    ee_s16 data16;
+    ee_s16 idx;
+} list_data;
+
+typedef struct list_head_s
+{
+    struct list_head_s *next;
+    struct list_data_s *info;
+} list_head;
+
+
+list_head *
+core_list_find(list_head *list, list_data *info)
+{
+    if (info->idx >= 0)
+    {
+        while (list && (list->info->idx != info->idx))
+            list = list->next;
+        return list;
+    }
+    else
+    {
+        while (list && ((list->info->data16 & 0xff) != info->data16))
+            list = list->next;
+        return list;
+    }
+}
+
+/* There is only one legitimate unconditional jump, so test for that,
+   which will catch the case where bb-reorder leaves a jump to a ret
+   in the IL.  */
+/* { dg-final { scan-assembler-times "jump" 1 } } */
+

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

only message in thread, other threads:[~2022-09-26 13:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-26 13:41 [gcc r13-2871] [RFA] Minor improvement to coremark, avoid unconditional jump to return 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).