Commit 03390cda by Chung-Ju Wu Committed by Chung-Ju Wu

[NDS32] Have shirnk-wrapping optimization to be performed on nds32 target.

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
parent aa2642ef
2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com> 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. * config/nds32/constants.md (UNSPEC_VOLATILE_POP25_RETURN): New.
* config/nds32/nds32.md (pop25return): New. * config/nds32/nds32.md (pop25return): New.
* config/nds32/nds32.c (nds32_expand_epilogue_v3pop): Emit * config/nds32/nds32.c (nds32_expand_epilogue_v3pop): Emit
......
...@@ -120,6 +120,10 @@ extern const char *nds32_output_32bit_load_s (rtx *, int); ...@@ -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_push (rtx);
extern const char *nds32_output_stack_pop (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. */ /* Auxiliary functions to decide output alignment or not. */
extern int nds32_target_alignment (rtx); extern int nds32_target_alignment (rtx);
......
...@@ -3087,12 +3087,9 @@ nds32_expand_epilogue (void) ...@@ -3087,12 +3087,9 @@ nds32_expand_epilogue (void)
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
} }
/* Generate return instruction by using /* Generate return instruction by using 'return_internal' pattern.
unspec_volatile_func_return pattern. Make sure this instruction is after gen_blockage(). */
Make sure this instruction is after gen_blockage(). emit_jump_insn (gen_return_internal ());
NOTE that $lp will become 'live'
after this instruction has been emitted. */
emit_insn (gen_unspec_volatile_func_return ());
return; return;
} }
...@@ -3196,9 +3193,8 @@ nds32_expand_epilogue (void) ...@@ -3196,9 +3193,8 @@ nds32_expand_epilogue (void)
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
} }
/* Generate return instruction by using /* Generate return instruction. */
unspec_volatile_func_return pattern. */ emit_jump_insn (gen_return_internal ());
emit_insn (gen_unspec_volatile_func_return ());
} }
/* Function for v3push prologue. */ /* Function for v3push prologue. */
...@@ -3350,12 +3346,9 @@ nds32_expand_epilogue_v3pop (void) ...@@ -3350,12 +3346,9 @@ nds32_expand_epilogue_v3pop (void)
epilogue code fragment BUT 'ret' instruction. */ epilogue code fragment BUT 'ret' instruction. */
if (cfun->machine->naked_p) if (cfun->machine->naked_p)
{ {
/* Generate return instruction by using /* Generate return instruction by using 'return_internal' pattern.
unspec_volatile_func_return pattern. Make sure this instruction is after gen_blockage(). */
Make sure this instruction is after gen_blockage(). emit_jump_insn (gen_return_internal ());
NOTE that $lp will become 'live'
after this instruction has been emitted. */
emit_insn (gen_unspec_volatile_func_return ());
return; return;
} }
...@@ -3454,6 +3447,25 @@ nds32_expand_epilogue_v3pop (void) ...@@ -3454,6 +3447,25 @@ nds32_expand_epilogue_v3pop (void)
emit_jump_insn (gen_pop25return ()); 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. /* Function to test 333-form for load/store instructions.
......
...@@ -2090,17 +2090,27 @@ create_template: ...@@ -2090,17 +2090,27 @@ create_template:
;; ---------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------
;; unspec operation patterns ;; Return operation patterns
;; ---------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------
;; In nds32 target, the 'ret5' instuction is actually 'jr5 $lp'. ;; Use this pattern to expand a return instruction
;; This pattern is designed to distinguish function return ;; with simple_return rtx if no epilogue is required.
;; from general indirect_jump pattern so that we can directly (define_expand "return"
;; generate 'ret5' for readability. [(simple_return)]
"nds32_can_use_return_insn ()"
""
)
(define_insn "unspec_volatile_func_return" ;; This pattern is expanded only by the shrink-wrapping optimization
[(set (pc) ;; on paths where the function prologue has not been executed.
(unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_FUNC_RETURN))] (define_expand "simple_return"
[(simple_return)]
""
""
)
(define_insn "return_internal"
[(simple_return)]
"" ""
{ {
if (TARGET_16_BIT) if (TARGET_16_BIT)
...@@ -2108,7 +2118,7 @@ create_template: ...@@ -2108,7 +2118,7 @@ create_template:
else else
return "ret"; return "ret";
} }
[(set_attr "type" "misc") [(set_attr "type" "branch")
(set_attr "enabled" "1") (set_attr "enabled" "1")
(set (attr "length") (set (attr "length")
(if_then_else (match_test "TARGET_16_BIT") (if_then_else (match_test "TARGET_16_BIT")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment