[NDS32] Have shirnk-wrapping optimization to be performed on nds32 target.
authorChung-Ju Wu <jasonwucj@gmail.com>
Fri, 16 Jan 2015 06:20:22 +0000 (06:20 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Fri, 16 Jan 2015 06:20:22 +0000 (06:20 +0000)
gcc/
* config/nds32/nds32-protos.h (nds32_can_use_return_insn): New.
* config/nds32/nds32.md (unspec_volatile_func_return): Remove.
(return_internal): New.
(return): Define this named pattern.
(simple_return): Define this named pattern.
* config/nds32/nds32.c (nds32_expand_epilogue): Emit return_internal
pattern instead of unspec_volatile_func_return.
(nds32_expand_epilogue_v3pop): Likewise.
(nds32_can_use_return_insn): New function.

From-SVN: r219711

gcc/ChangeLog
gcc/config/nds32/nds32-protos.h
gcc/config/nds32/nds32.c
gcc/config/nds32/nds32.md

index 1d998d02fb7328a8a2623c228fd9bd3d20f07733..5d0313dffdfd2bfc700445fbf00e618b328f718e 100644 (file)
@@ -1,3 +1,15 @@
+2015-01-16  Chung-Ju Wu  <jasonwucj@gmail.com>
+
+       * config/nds32/nds32-protos.h (nds32_can_use_return_insn): New.
+       * config/nds32/nds32.md (unspec_volatile_func_return): Remove.
+       (return_internal): New.
+       (return): Define this named pattern.
+       (simple_return): Define this named pattern.
+       * config/nds32/nds32.c (nds32_expand_epilogue): Emit return_internal
+       pattern instead of unspec_volatile_func_return.
+       (nds32_expand_epilogue_v3pop): Likewise.
+       (nds32_can_use_return_insn): New function.
+
 2015-01-16  Chung-Ju Wu  <jasonwucj@gmail.com>
 
        * config/nds32/constants.md (UNSPEC_VOLATILE_POP25_RETURN): New.
index 328e0619ead9a5518a494f3e2091c57a2920e22d..91f8d9ab0b26341e360b01e2149b474a15a0b0e0 100644 (file)
@@ -120,6 +120,10 @@ extern const char *nds32_output_32bit_load_s (rtx *, int);
 extern const char *nds32_output_stack_push (rtx);
 extern const char *nds32_output_stack_pop (rtx);
 
+/* Auxiliary functions to check using return with null epilogue.  */
+
+extern int nds32_can_use_return_insn (void);
+
 /* Auxiliary functions to decide output alignment or not.  */
 
 extern int nds32_target_alignment (rtx);
index d38ea896d79cf062694e404ff67aacece8b4b14b..538495fb298b5f362df0008773e331deadc06d1e 100644 (file)
@@ -3087,12 +3087,9 @@ nds32_expand_epilogue (void)
          RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
        }
 
-      /* Generate return instruction by using
-         unspec_volatile_func_return pattern.
-         Make sure this instruction is after gen_blockage().
-         NOTE that $lp will become 'live'
-         after this instruction has been emitted.  */
-      emit_insn (gen_unspec_volatile_func_return ());
+      /* Generate return instruction by using 'return_internal' pattern.
+         Make sure this instruction is after gen_blockage().  */
+      emit_jump_insn (gen_return_internal ());
       return;
     }
 
@@ -3196,9 +3193,8 @@ nds32_expand_epilogue (void)
       RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
     }
 
-  /* Generate return instruction by using
-     unspec_volatile_func_return pattern.  */
-  emit_insn (gen_unspec_volatile_func_return ());
+  /* Generate return instruction.  */
+  emit_jump_insn (gen_return_internal ());
 }
 
 /* Function for v3push prologue.  */
@@ -3350,12 +3346,9 @@ nds32_expand_epilogue_v3pop (void)
      epilogue code fragment BUT 'ret' instruction.  */
   if (cfun->machine->naked_p)
     {
-      /* Generate return instruction by using
-         unspec_volatile_func_return pattern.
-         Make sure this instruction is after gen_blockage().
-         NOTE that $lp will become 'live'
-         after this instruction has been emitted.  */
-      emit_insn (gen_unspec_volatile_func_return ());
+      /* Generate return instruction by using 'return_internal' pattern.
+         Make sure this instruction is after gen_blockage().  */
+      emit_jump_insn (gen_return_internal ());
       return;
     }
 
@@ -3454,6 +3447,25 @@ nds32_expand_epilogue_v3pop (void)
   emit_jump_insn (gen_pop25return ());
 }
 
+/* Return nonzero if this function is known to have a null epilogue.
+   This allows the optimizer to omit jumps to jumps if no stack
+   was created.  */
+int
+nds32_can_use_return_insn (void)
+{
+  /* Prior to reloading, we can't tell how many registers must be saved.
+     Thus we can not determine whether this function has null epilogue.  */
+  if (!reload_completed)
+    return 0;
+
+  /* If no stack was created, two conditions must be satisfied:
+     1. This is a naked function.
+        So there is no callee-saved, local size, or outgoing size.
+     2. This is NOT a variadic function.
+        So there is no pushing arguement registers into the stack.  */
+  return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0));
+}
+
 /* ------------------------------------------------------------------------ */
 
 /* Function to test 333-form for load/store instructions.
index 01faa681cad5f03a18400480ec400db1b0b479d5..1cf620288c780af10123642976223688ebbd4176 100644 (file)
@@ -2090,17 +2090,27 @@ create_template:
 
 
 ;; ----------------------------------------------------------------------------
-;; unspec operation patterns
+;; Return operation patterns
 ;; ----------------------------------------------------------------------------
 
-;; In nds32 target, the 'ret5' instuction is actually 'jr5 $lp'.
-;; This pattern is designed to distinguish function return
-;; from general indirect_jump pattern so that we can directly
-;; generate 'ret5' for readability.
+;; Use this pattern to expand a return instruction
+;; with simple_return rtx if no epilogue is required.
+(define_expand "return"
+  [(simple_return)]
+  "nds32_can_use_return_insn ()"
+  ""
+)
 
-(define_insn "unspec_volatile_func_return"
-  [(set (pc)
-       (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_FUNC_RETURN))]
+;; This pattern is expanded only by the shrink-wrapping optimization
+;; on paths where the function prologue has not been executed.
+(define_expand "simple_return"
+  [(simple_return)]
+  ""
+  ""
+)
+
+(define_insn "return_internal"
+  [(simple_return)]
   ""
 {
   if (TARGET_16_BIT)
@@ -2108,7 +2118,7 @@ create_template:
   else
     return "ret";
 }
-  [(set_attr "type" "misc")
+  [(set_attr "type" "branch")
    (set_attr "enabled" "1")
    (set (attr "length")
        (if_then_else (match_test "TARGET_16_BIT")