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>
* 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/nds32.md (pop25return): New.
* config/nds32/nds32.c (nds32_expand_epilogue_v3pop): Emit
......
......@@ -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);
......
......@@ -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.
......
......@@ -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")
......
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