Commit 745f2a84 by Richard Henderson Committed by Richard Henderson

re PR target/21518 (unable to find a register with -fPIC and -O2 and non inlining static function)

        PR 21518
        * loop.c (scan_loop): Do not propagate computations to a hard
        register destination with SMALL_REGISTER_CLASSES.

From-SVN: r106373
parent 12674da3
2005-11-01 Richard Henderson <rth@redhat.com>
PR 21518
* loop.c (scan_loop): Do not propagate computations to a hard
register destination with SMALL_REGISTER_CLASSES.
2005-11-01 Joseph S. Myers <joseph@codesourcery.com> 2005-11-01 Joseph S. Myers <joseph@codesourcery.com>
* config/rs6000/rs6000.c (rs6000_rtx_costs): Do not add extra * config/rs6000/rs6000.c (rs6000_rtx_costs): Do not add extra
......
...@@ -1266,12 +1266,13 @@ scan_loop (struct loop *loop, int flags) ...@@ -1266,12 +1266,13 @@ scan_loop (struct loop *loop, int flags)
{ {
struct movable *m; struct movable *m;
int regno = REGNO (SET_DEST (set)); int regno = REGNO (SET_DEST (set));
rtx user, user_set;
/* A potential lossage is where we have a case where two insns /* A potential lossage is where we have a case where two
can be combined as long as they are both in the loop, but insns can be combined as long as they are both in the
we move one of them outside the loop. For large loops, loop, but we move one of them outside the loop. For
this can lose. The most common case of this is the address large loops, this can lose. The most common case of
of a function being called. this is the address of a function being called.
Therefore, if this register is marked as being used Therefore, if this register is marked as being used
exactly once if we are in a loop with calls exactly once if we are in a loop with calls
...@@ -1279,41 +1280,44 @@ scan_loop (struct loop *loop, int flags) ...@@ -1279,41 +1280,44 @@ scan_loop (struct loop *loop, int flags)
this register with the source of this SET. If we can, this register with the source of this SET. If we can,
delete this insn. delete this insn.
Don't do this if P has a REG_RETVAL note or if we have Don't do this if:
SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */ (1) P has a REG_RETVAL note or
(2) if we have SMALL_REGISTER_CLASSES and
(a) SET_SRC is a hard register or
(b) the destination of the user is a hard register. */
if (loop_info->has_call if (loop_info->has_call
&& regs->array[regno].single_usage != 0 && regno >= FIRST_PSEUDO_REGISTER
&& regs->array[regno].single_usage != const0_rtx && (user = regs->array[regno].single_usage) != NULL
&& user != const0_rtx
&& REGNO_FIRST_UID (regno) == INSN_UID (p) && REGNO_FIRST_UID (regno) == INSN_UID (p)
&& (REGNO_LAST_UID (regno) && REGNO_LAST_UID (regno) == INSN_UID (user)
== INSN_UID (regs->array[regno].single_usage))
&& regs->array[regno].set_in_loop == 1 && regs->array[regno].set_in_loop == 1
&& GET_CODE (SET_SRC (set)) != ASM_OPERANDS && GET_CODE (SET_SRC (set)) != ASM_OPERANDS
&& ! side_effects_p (SET_SRC (set)) && ! side_effects_p (SET_SRC (set))
&& ! find_reg_note (p, REG_RETVAL, NULL_RTX) && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
&& (! SMALL_REGISTER_CLASSES && (!SMALL_REGISTER_CLASSES
|| (! (REG_P (SET_SRC (set)) || !REG_P (SET_SRC (set))
&& (REGNO (SET_SRC (set)) || !HARD_REGISTER_P (SET_SRC (set)))
< FIRST_PSEUDO_REGISTER)))) && (!SMALL_REGISTER_CLASSES
&& regno >= FIRST_PSEUDO_REGISTER || !NONJUMP_INSN_P (user)
|| !(user_set = single_set (user))
|| !REG_P (SET_DEST (user_set))
|| !HARD_REGISTER_P (SET_DEST (user_set)))
/* This test is not redundant; SET_SRC (set) might be /* This test is not redundant; SET_SRC (set) might be
a call-clobbered register and the life of REGNO a call-clobbered register and the life of REGNO
might span a call. */ might span a call. */
&& ! modified_between_p (SET_SRC (set), p, && ! modified_between_p (SET_SRC (set), p, user)
regs->array[regno].single_usage) && no_labels_between_p (p, user)
&& no_labels_between_p (p, && validate_replace_rtx (SET_DEST (set),
regs->array[regno].single_usage) SET_SRC (set), user))
&& validate_replace_rtx (SET_DEST (set), SET_SRC (set),
regs->array[regno].single_usage))
{ {
/* Replace any usage in a REG_EQUAL note. Must copy /* Replace any usage in a REG_EQUAL note. Must copy
the new source, so that we don't get rtx sharing the new source, so that we don't get rtx sharing
between the SET_SOURCE and REG_NOTES of insn p. */ between the SET_SOURCE and REG_NOTES of insn p. */
REG_NOTES (regs->array[regno].single_usage) REG_NOTES (user)
= (replace_rtx = replace_rtx (REG_NOTES (user), SET_DEST (set),
(REG_NOTES (regs->array[regno].single_usage), copy_rtx (SET_SRC (set)));
SET_DEST (set), copy_rtx (SET_SRC (set))));
delete_insn (p); delete_insn (p);
for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set)); for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
......
/* { dg-do compile } */
/* { dg-options "-O2 -fPIC -fno-tree-pre" } */
/* { dg-require-effective-target ilp32 } */
extern void __attribute__ ((regparm (3)))
drawPointsLines (char type, int first, int *dd);
int
do_locator (int *call)
{
char prephitmp5;
int type;
int i;
if (call == 0)
prephitmp5 = 1;
else
{
type = *call;
i = 0;
do
{
if (i != type)
drawPointsLines ((int) (char) type, 0, call);
i = i + 1;
}
while (i != 2);
prephitmp5 = (char) type;
}
drawPointsLines ((int) prephitmp5, 0, call);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment