re PR target/13585 (Incorrect optimisation of call to sfunc)

PR target/13585
	* sh-protos.h (check_use_sfunc_addr): Declare.
	* sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions.
	* sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate.

From-SVN: r75717
This commit is contained in:
J"orn Rennecke 2004-01-12 12:59:38 +00:00 committed by Joern Rennecke
parent f6ea0188bf
commit 07d7d2f4d1
4 changed files with 56 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2004-01-09 J"orn Rennecke <joern.rennecke@superh.com>
PR target/13585
* sh-protos.h (check_use_sfunc_addr): Declare.
* sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions.
* sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate.
2004-01-12 Jan Hubicka <jh@suse.cz>
* alias.c: Invlude varray.h

View File

@ -125,6 +125,7 @@ extern bool sh_cannot_change_mode_class
extern void sh_mark_label (rtx, int);
extern int sh_register_move_cost
(enum machine_mode mode, enum reg_class, enum reg_class);
extern int check_use_sfunc_addr (rtx, rtx);
#ifdef HARD_CONST
extern void fpscr_set_from_mem (int, HARD_REG_SET);

View File

@ -9167,4 +9167,51 @@ sh_expand_t_scc (enum rtx_code code, rtx target)
return 1;
}
/* INSN is an sfunc; return the rtx that describes the address used. */
static rtx
extract_sfunc_addr (rtx insn)
{
rtx pattern, part = NULL_RTX;
int len, i;
pattern = PATTERN (insn);
len = XVECLEN (pattern, 0);
for (i = 0; i < len; i++)
{
part = XVECEXP (pattern, 0, i);
if (GET_CODE (part) == USE && GET_MODE (XEXP (part, 0)) == Pmode
&& GENERAL_REGISTER_P (true_regnum (XEXP (part, 0))))
return XEXP (part, 0);
}
if (GET_CODE (XVECEXP (pattern, 0, 0)) == UNSPEC_VOLATILE)
return XVECEXP (XVECEXP (pattern, 0, 0), 0, 1);
abort ();
}
/* Verify that the register in use_sfunc_addr still agrees with the address
used in the sfunc. This prevents fill_slots_from_thread from changing
use_sfunc_addr.
INSN is the use_sfunc_addr instruction, and REG is the register it
guards. */
int
check_use_sfunc_addr (rtx insn, rtx reg)
{
/* Search for the sfunc. It should really come right after INSN. */
while ((insn = NEXT_INSN (insn)))
{
if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN)
break;
if (! INSN_P (insn))
continue;
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
insn = XVECEXP (PATTERN (insn), 0, 0);
if (GET_CODE (PATTERN (insn)) != PARALLEL
|| get_attr_type (insn) != TYPE_SFUNC)
continue;
return rtx_equal_p (extract_sfunc_addr (insn), reg);
}
abort ();
}
#include "gt-sh.h"

View File

@ -1245,7 +1245,7 @@
(define_insn "use_sfunc_addr"
[(set (reg:SI PR_REG)
(unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
"TARGET_SH1"
"TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
""
[(set_attr "length" "0")])