From 03390cda42267d8d04c7bde6c2a649cd255ae367 Mon Sep 17 00:00:00 2001 From: Chung-Ju Wu Date: Fri, 16 Jan 2015 06:20:22 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 12 ++++++++++ gcc/config/nds32/nds32-protos.h | 4 ++++ gcc/config/nds32/nds32.c | 42 +++++++++++++++++++++------------ gcc/config/nds32/nds32.md | 28 +++++++++++++++------- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d998d02fb7..5d0313dffdf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-01-16 Chung-Ju Wu + + * 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 * config/nds32/constants.md (UNSPEC_VOLATILE_POP25_RETURN): New. diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h index 328e0619ead..91f8d9ab0b2 100644 --- a/gcc/config/nds32/nds32-protos.h +++ b/gcc/config/nds32/nds32-protos.h @@ -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); diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c index d38ea896d79..538495fb298 100644 --- a/gcc/config/nds32/nds32.c +++ b/gcc/config/nds32/nds32.c @@ -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. diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md index 01faa681cad..1cf620288c7 100644 --- a/gcc/config/nds32/nds32.md +++ b/gcc/config/nds32/nds32.md @@ -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") -- 2.30.2