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:
parent
f6ea0188bf
commit
07d7d2f4d1
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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")])
|
||||
|
||||
|
|
Loading…
Reference in New Issue