diff options
author | John David Anglin <dave.anglin@nrc-cnrc.gc.ca> | 2011-09-03 16:21:27 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2011-09-03 16:21:27 +0000 |
commit | 157685833c61872ba047a2df180340e9bda920ab (patch) | |
tree | 3a6e1bbeb1e00c61eb841f9ceab6123262fced82 | |
parent | 13868f4049616f5ac73bb89ce38474ada50ff28c (diff) | |
download | gcc-157685833c61872ba047a2df180340e9bda920ab.zip gcc-157685833c61872ba047a2df180340e9bda920ab.tar.gz gcc-157685833c61872ba047a2df180340e9bda920ab.tar.bz2 |
PR Bug middle-end/50232
PR Bug middle-end/50232
* config/pa/pa.md (return): Define "return" insn pattern.
(epilogue): Use it when no epilogue is needed.
* config/pa/pa.c (pa_can_use_return_insn): New function.
* config/pa/pa-protos.h (pa_can_use_return_insn): Declare.
From-SVN: r178500
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/pa/pa-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 18 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 21 |
4 files changed, 43 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8da81f7..a6d6f3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-09-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR Bug middle-end/50232 + * config/pa/pa.md (return): Define "return" insn pattern. + (epilogue): Use it when no epilogue is needed. + * config/pa/pa.c (pa_can_use_return_insn): New function. + * config/pa/pa-protos.h (pa_can_use_return_insn): Declare. + 2011-09-03 Eric Botcazou <ebotcazou@adacore.com> * cfgexpand.c (add_stack_var): Assert that the alignment is not zero. diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index d481c3d..8c733e4 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -93,6 +93,7 @@ extern int and_mask_p (unsigned HOST_WIDE_INT); extern int cint_ok_for_move (HOST_WIDE_INT); extern void hppa_expand_prologue (void); extern void hppa_expand_epilogue (void); +extern bool pa_can_use_return_insn (void); extern int ior_mask_p (unsigned HOST_WIDE_INT); extern void compute_zdepdi_operands (unsigned HOST_WIDE_INT, unsigned *); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index db404cd..e3ad4c8 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4329,6 +4329,24 @@ hppa_expand_epilogue (void) } } +bool +pa_can_use_return_insn (void) +{ + if (!reload_completed) + return false; + + if (frame_pointer_needed) + return false; + + if (df_regs_ever_live_p (2)) + return false; + + if (crtl->profile) + return false; + + return compute_frame_size (get_frame_size (), 0) == 0; +} + rtx hppa_pic_save_rtx (void) { diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index ee94b2e..62369a5 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -6671,6 +6671,20 @@ ;; Unconditional and other jump instructions. +;; Trivial return used when no epilogue is needed. +(define_insn "return" + [(return) + (use (reg:SI 2))] + "pa_can_use_return_insn ()" + "* +{ + if (TARGET_PA_20) + return \"bve%* (%%r2)\"; + return \"bv%* %%r0(%%r2)\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + ;; This is used for most returns. (define_insn "return_internal" [(return) @@ -6719,11 +6733,8 @@ rtx x; /* Try to use the trivial return first. Else use the full epilogue. */ - if (reload_completed - && !frame_pointer_needed - && !df_regs_ever_live_p (2) - && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)) - x = gen_return_internal (); + if (pa_can_use_return_insn ()) + x = gen_return (); else { hppa_expand_epilogue (); |