From 614c1fd706c3b4b237759beb6983e24eb52f6a23 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Tue, 30 Sep 2003 07:14:39 +0000 Subject: [PATCH] PR optimization/12345 * config/mips/mips-protos.h (mips_restore_gp): Remove. (mips_gp_save_slot): Declare. * config/mips/mips.c (mips_restore_gp): Remove in favor of... (mips_gp_save_slot): ...this new function. * config/mips/mips.md (exception_receiver): Use mips_gp_save_slot and mips_output_move to generate the output template. (call_internal): Force splitting if TARGET_SPLIT_CALLS. Don't emit a gp load after a noreturn call. Load the gp using a move rather than an exception_receiver pattern. (call_value_internal, call_value_multiple_internal): Likewise. (call_split, call_value_split, call_value_multiple_split): Clobber $28. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71935 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 +++++++++ gcc/config/mips/mips-protos.h | 2 +- gcc/config/mips/mips.c | 23 ++++++-------- gcc/config/mips/mips.md | 72 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 85 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c2f6901..78531d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2003-09-30 Richard Sandiford + + PR optimization/12345 + * config/mips/mips-protos.h (mips_restore_gp): Remove. + (mips_gp_save_slot): Declare. + * config/mips/mips.c (mips_restore_gp): Remove in favor of... + (mips_gp_save_slot): ...this new function. + * config/mips/mips.md (exception_receiver): Use mips_gp_save_slot + and mips_output_move to generate the output template. + (call_internal): Force splitting if TARGET_SPLIT_CALLS. Don't emit + a gp load after a noreturn call. Load the gp using a move rather + than an exception_receiver pattern. + (call_value_internal, call_value_multiple_internal): Likewise. + (call_split, call_value_split, call_value_multiple_split): Clobber $28. + 2003-09-30 Carlo Wood PR debug/12319 diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index d057d17..3e3e414 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -61,7 +61,7 @@ extern rtx mips_subword (rtx, int); extern bool mips_split_64bit_move_p (rtx, rtx); extern void mips_split_64bit_move (rtx, rtx); extern const char *mips_output_move (rtx, rtx); -extern const char *mips_restore_gp (rtx *); +extern rtx mips_gp_save_slot (void); #ifdef RTX_CODE extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *); extern void gen_conditional_branch (rtx *, enum rtx_code); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7fcab39..a2232f0 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -2749,30 +2749,27 @@ mips_output_move (rtx dest, rtx src) abort (); } -/* Return instructions to restore the global pointer from the stack, - assuming TARGET_ABICALLS. Used by exception_receiver to set up - the GP for exception handlers. +/* Return an rtx for the gp save slot. Valid only when using o32 or + o64 abicalls. */ - OPERANDS is an array of operands whose contents are undefined - on entry. */ - -const char * -mips_restore_gp (rtx *operands) +rtx +mips_gp_save_slot (void) { rtx loc; - operands[0] = pic_offset_table_rtx; + if (!TARGET_ABICALLS || TARGET_NEWABI) + abort (); + if (frame_pointer_needed) loc = hard_frame_pointer_rtx; else loc = stack_pointer_rtx; loc = plus_constant (loc, current_function_outgoing_args_size); - operands[1] = gen_rtx_MEM (ptr_mode, loc); - - return mips_output_move (operands[0], operands[1]); + loc = gen_rtx_MEM (Pmode, loc); + RTX_UNCHANGING_P (loc) = 1; + return loc; } - /* Make normal rtx_code into something we can index from an array */ static enum internal_test diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 61aeead..1b184ac 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -8228,7 +8228,11 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" [(set (reg:SI 28) (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))] "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)" - { return mips_restore_gp (operands); } +{ + operands[0] = pic_offset_table_rtx; + operands[1] = mips_gp_save_slot (); + return mips_output_move (operands[0], operands[1]); +} [(set_attr "type" "load") (set_attr "length" "8")]) @@ -8317,17 +8321,55 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" DONE; }) +;; This instruction directly corresponds to an assembly-language "jal". +;; There are four cases: +;; +;; - -mno-abicalls: +;; Both symbolic and register destinations are OK. The pattern +;; always expands to a single mips instruction. +;; +;; - -mabicalls/-mno-explicit-relocs: +;; Again, both symbolic and register destinations are OK. +;; The call is treated as a multi-instruction black box. +;; +;; - -mabicalls/-mexplicit-relocs with n32 or n64: +;; Only "jal $25" is allowed. This expands to a single "jalr $25" +;; instruction. +;; +;; - -mabicalls/-mexplicit-relocs with o32 or o64: +;; Only "jal $25" is allowed. The call is actually two instructions: +;; "jalr $25" followed by an insn to reload $gp. +;; +;; In the last case, we can generate the individual instructions with +;; a define_split. There are several things to be wary of: +;; +;; - We can't expose the load of $gp before reload. If we did, +;; it might get removed as dead, but reload can introduce new +;; uses of $gp by rematerializing constants. +;; +;; - We shouldn't restore $gp after calls that never return. +;; It isn't valid to insert instructions between a noreturn +;; call and the following barrier. +;; +;; - The splitter deliberately changes the liveness of $gp. The unsplit +;; instruction preserves $gp and so have no effect on its liveness. +;; But once we generate the separate insns, it becomes obvious that +;; $gp is not live on entry to the call. +;; +;; ??? The operands[2] = insn check is a hack to make the original insn +;; available to the splitter. (define_insn_and_split "call_internal" [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S")) (match_operand 1 "" "")) (clobber (reg:SI 31))] "" - "%*jal\t%0%/" - "reload_completed && TARGET_SPLIT_CALLS" + { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; } + "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)" [(const_int 0)] { emit_call_insn (gen_call_split (operands[0], operands[1])); - emit_insn (gen_exception_receiver ()); + if (!find_reg_note (operands[2], REG_NORETURN, 0)) + emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); DONE; } [(set_attr "jal" "indirect,direct") @@ -8337,7 +8379,7 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" [(call (mem:SI (match_operand 0 "call_insn_operand" "c")) (match_operand 1 "" "")) (clobber (reg:SI 31)) - (const_int 1)] + (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" "%*jalr\t%0%/" [(set_attr "type" "call")]) @@ -8354,19 +8396,21 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" DONE; }) +;; See comment for call_internal. (define_insn_and_split "call_value_internal" [(set (match_operand 0 "register_operand" "=df,df") (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) (match_operand 2 "" ""))) (clobber (reg:SI 31))] "" - "%*jal\t%1%/" - "reload_completed && TARGET_SPLIT_CALLS" + { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; } + "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)" [(const_int 0)] { emit_call_insn (gen_call_value_split (operands[0], operands[1], operands[2])); - emit_insn (gen_exception_receiver ()); + if (!find_reg_note (operands[3], REG_NORETURN, 0)) + emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); DONE; } [(set_attr "jal" "indirect,direct") @@ -8377,11 +8421,12 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" (call (mem:SI (match_operand 1 "call_insn_operand" "c")) (match_operand 2 "" ""))) (clobber (reg:SI 31)) - (const_int 1)] + (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" "%*jalr\t%1%/" [(set_attr "type" "call")]) +;; See comment for call_internal. (define_insn_and_split "call_value_multiple_internal" [(set (match_operand 0 "register_operand" "=df,df") (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) @@ -8391,13 +8436,14 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" (match_dup 2))) (clobber (reg:SI 31))] "" - "%*jal\t%1%/" - "reload_completed && TARGET_SPLIT_CALLS" + { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; } + "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)" [(const_int 0)] { emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], operands[2], operands[3])); - emit_insn (gen_exception_receiver ()); + if (!find_reg_note (operands[4], REG_NORETURN, 0)) + emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); DONE; } [(set_attr "jal" "indirect,direct") @@ -8411,7 +8457,7 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/" (call (mem:SI (match_dup 1)) (match_dup 2))) (clobber (reg:SI 31)) - (const_int 1)] + (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" "%*jalr\t%1%/" [(set_attr "type" "call")]) -- 2.7.4