re PR rtl-optimization/12345 (internal compiler error: verify_flow_info failed)

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.

From-SVN: r71935
This commit is contained in:
Richard Sandiford 2003-09-30 07:14:39 +00:00 committed by Richard Sandiford
parent 3c44a3c4b7
commit 573850d4cb
4 changed files with 85 additions and 27 deletions

View File

@ -1,3 +1,18 @@
2003-09-30 Richard Sandiford <rsandifo@redhat.com>
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 <carlo@alinoe.com>
PR debug/12319

View File

@ -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);

View File

@ -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

View File

@ -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")])