Improve prepare_shrink_wrap to sink more instructions
authorJiong Wang <jiong.wang@arm.com>
Wed, 24 Sep 2014 18:30:34 +0000 (18:30 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Wed, 24 Sep 2014 18:30:34 +0000 (18:30 +0000)
  gcc/
    * shrink-wrap.c (move_insn_for_shrink_wrap): Add further check when
    !REG_P (src) to release more instruction sink opportunities.

  gcc/testsuite/
    * gcc.target/aarch64/shrink_wrap_symbol_ref_1.c: New testcase.

From-SVN: r215563

gcc/ChangeLog
gcc/shrink-wrap.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/shrink_wrap_symbol_ref_1.c [new file with mode: 0644]

index ce6738c852dd55a9cd2fd44e010e876393dd39a3..fd6a7d32cb638731c21a0b02d9804b7208ffc9f0 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-24  Jiong Wang  <jiong.wang@arm.com>
+
+       * shrink-wrap.c (move_insn_for_shrink_wrap): Add further check when
+       !REG_P (src) to release more instruction sink opportunities.
+
 2014-09-24  Wilco Dijkstra  <wilco.dijkstra@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_register_move_cost): Add register
index 9ae8a08ec1053b4687d0e6f76d0874f8b3006a6b..af23f0288d74730e11351915df91bd61f88fbaff 100644 (file)
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bb-reorder.h"
 #include "shrink-wrap.h"
 #include "regcprop.h"
+#include "rtl-iter.h"
 
 #ifdef HAVE_simple_return
 
@@ -169,7 +170,9 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
 {
   rtx set, src, dest;
   bitmap live_out, live_in, bb_uses, bb_defs;
-  unsigned int i, dregno, end_dregno, sregno, end_sregno;
+  unsigned int i, dregno, end_dregno;
+  unsigned int sregno = FIRST_PSEUDO_REGISTER;
+  unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
   basic_block next_block;
   edge live_edge;
 
@@ -179,7 +182,34 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
     return false;
   src = SET_SRC (set);
   dest = SET_DEST (set);
-  if (!REG_P (dest) || !REG_P (src)
+
+  if (!REG_P (src))
+    {
+      unsigned int reg_num = 0;
+      unsigned int nonconstobj_num = 0;
+      rtx src_inner = NULL_RTX;
+
+      subrtx_var_iterator::array_type array;
+      FOR_EACH_SUBRTX_VAR (iter, array, src, ALL)
+       {
+         rtx x = *iter;
+         if (REG_P (x))
+           {
+             reg_num++;
+             src_inner = x;
+           }
+         else if (!CONSTANT_P (x) && OBJECT_P (x))
+           nonconstobj_num++;
+       }
+
+      if (nonconstobj_num > 0
+         || reg_num > 1)
+       src = NULL_RTX;
+      else if (reg_num == 1)
+       src = src_inner;
+    }
+
+  if (!REG_P (dest) || src == NULL_RTX
       /* STACK or FRAME related adjustment might be part of prologue.
         So keep them in the entry block.  */
       || dest == stack_pointer_rtx
@@ -188,10 +218,13 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
     return false;
 
   /* Make sure that the source register isn't defined later in BB.  */
-  sregno = REGNO (src);
-  end_sregno = END_REGNO (src);
-  if (overlaps_hard_reg_set_p (defs, GET_MODE (src), sregno))
-    return false;
+  if (REG_P (src))
+    {
+      sregno = REGNO (src);
+      end_sregno = END_REGNO (src);
+      if (overlaps_hard_reg_set_p (defs, GET_MODE (src), sregno))
+       return false;
+    }
 
   /* Make sure that the destination register isn't referenced later in BB.  */
   dregno = REGNO (dest);
index 2b4f867fe5db954cd2b69630ed222c1c28886187..ddf0c323a041ecafc48b1b5c7bba722f38fe1135 100644 (file)
@@ -1,3 +1,7 @@
+2014-09-24  Jiong Wang  <jiong.wang@arm.com>
+
+       * gcc.target/aarch64/shrink_wrap_symbol_ref_1.c: New testcase.
+
 2014-09-24  Marek Polacek  <polacek@redhat.com>
 
        PR c/61405
diff --git a/gcc/testsuite/gcc.target/aarch64/shrink_wrap_symbol_ref_1.c b/gcc/testsuite/gcc.target/aarch64/shrink_wrap_symbol_ref_1.c
new file mode 100644 (file)
index 0000000..dd3056d
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */
+
+extern char *asm_out_file;
+extern void default_elf_asm_output_ascii (char *, const char *, int);
+
+void
+assemble_string (const char *p, int size)
+{
+  int pos = 0;
+  int maximum = 2000;
+
+  while (pos < size)
+    {
+      int thissize = size - pos;
+
+      if (thissize > maximum)
+       thissize = maximum;
+
+      default_elf_asm_output_ascii (asm_out_file, p, thissize);;
+
+      pos += thissize;
+      p += thissize;
+    }
+}
+
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue"  } } */
+/* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */