[taken from gcc-2.95.3-latest-cvs]

2000-10-17  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
	* function.c (locate_and_pad_parm): Don't align stack unconditionally.
	Fri Nov  5 10:07:25 1999  Nick Clifton  <nickc@cygnus.com>
	* function.c (is_addressof): New function.  Returns true if


git-svn-id: file:///srv/svn/repos/haiku/trunk/buildtools@9592 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2004-10-28 18:22:34 +00:00
parent 4837867f67
commit d9bb2c14a8

View File

@ -513,8 +513,9 @@ static int *record_insns PROTO((rtx));
static int contains PROTO((rtx, int *));
#endif /* HAVE_prologue || HAVE_epilogue */
static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
static void purge_addressof_1 PROTO((rtx *, rtx, int, int,
static boolean purge_addressof_1 PROTO((rtx *, rtx, int, int,
struct hash_table *));
static int is_addressof PROTO ((rtx *, void *));
static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
struct hash_table *,
hash_table_key));
@ -3055,9 +3056,10 @@ static rtx purge_addressof_replacements;
/* Helper function for purge_addressof. See if the rtx expression at *LOC
in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into
the stack. */
the stack. If the function returns FALSE then the replacement could not
be made. */
static void
static boolean
purge_addressof_1 (loc, insn, force, store, ht)
rtx *loc;
rtx insn;
@ -3068,13 +3070,14 @@ purge_addressof_1 (loc, insn, force, store, ht)
RTX_CODE code;
int i, j;
char *fmt;
boolean result = true;
/* Re-start here to avoid recursion in common cases. */
restart:
x = *loc;
if (x == 0)
return;
return true;
code = GET_CODE (x);
@ -3087,7 +3090,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (validate_change (insn, loc, sub, 0)
|| validate_replace_rtx (x, sub, insn))
return;
return true;
start_sequence ();
sub = force_operand (sub, NULL_RTX);
@ -3098,7 +3101,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
insns = gen_sequence ();
end_sequence ();
emit_insn_before (insns, insn);
return;
return true;
}
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
{
@ -3117,7 +3120,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
&& (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
{
put_addressof_into_stack (XEXP (x, 0), ht);
return;
return true;
}
else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
{
@ -3136,7 +3139,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (x, XEXP (tem, 0)))
{
*loc = XEXP (XEXP (tem, 1), 0);
return;
return true;
}
/* See comment for purge_addressof_replacements. */
@ -3176,11 +3179,17 @@ purge_addressof_1 (loc, insn, force, store, ht)
z = gen_lowpart (GET_MODE (x), z);
*loc = z;
return;
return true;
}
/* There should always be such a replacement. */
abort ();
/* Sometimes we may not be able to find the replacement. For
example when the original insn was a MEM in a wider mode,
and the note is part of a sign extension of a narrowed
version of that MEM. Gcc testcase compile/990829-1.c can
generate an example of this siutation. Rather than complain
we return false, which will prompt our caller to remove the
offending note. */
return false;
}
size_x = GET_MODE_BITSIZE (GET_MODE (x));
@ -3266,7 +3275,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
purge_bitfield_addressof_replacements));
/* We replaced with a reg -- all done. */
return;
return true;
}
}
else if (validate_change (insn, loc, sub, 0))
@ -3283,13 +3292,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
{
XEXP (XEXP (tem, 1), 0) = sub;
return;
return true;
}
purge_addressof_replacements
= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
gen_rtx_EXPR_LIST (VOIDmode, sub,
purge_addressof_replacements));
return;
return true;
}
goto restart;
}
@ -3299,13 +3308,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
else if (code == ADDRESSOF)
{
put_addressof_into_stack (x, ht);
return;
return true;
}
else if (code == SET)
{
purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return;
result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return result;
}
/* Scan all subexpressions. */
@ -3313,11 +3322,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
}
return result;
}
/* Return a new hash table entry in HT. */
@ -3437,6 +3448,16 @@ compute_insns_for_mem (insns, last_insn, ht)
}
}
/* Helper function for purge_addressof called through for_each_rtx.
Returns true iff the rtl is an ADDRESSOF. */
static int
is_addressof (rtl, data)
rtx * rtl;
void * data ATTRIBUTE_UNUSED;
{
return GET_CODE (* rtl) == ADDRESSOF;
}
/* Eliminate all occurrences of ADDRESSOF from INSNS. Elide any remaining
(MEM (ADDRESSOF)) patterns, and force any needed registers into the
stack. */
@ -3465,9 +3486,30 @@ purge_addressof (insns)
if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
|| GET_CODE (insn) == CALL_INSN)
{
purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0, &ht);
purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
if (! purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0, &ht))
/* If we could not replace the ADDRESSOFs in the insn,
something is wrong. */
abort ();
if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht))
{
/* If we could not replace the ADDRESSOFs in the insn's notes,
we can just remove the offending notes instead. */
rtx note;
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
{
/* If we find a REG_RETVAL note then the insn is a libcall.
Such insns must have REG_EQUAL notes as well, in order
for later passes of the compiler to work. So it is not
safe to delete the notes here, and instead we abort. */
if (REG_NOTE_KIND (note) == REG_RETVAL)
abort ();
if (for_each_rtx (& note, is_addressof, NULL))
remove_note (insn, note);
}
}
}
/* Clean up. */
@ -5292,7 +5334,18 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
- offset_ptr->constant);
}
#else /* !ARGS_GROW_DOWNWARD */
if (!in_regs
#ifdef REG_PARM_STACK_SPACE
|| REG_PARM_STACK_SPACE (fndecl) > 0
#else
/* For the gcc-2_95-branch we want to make sure not to break something
on platforms which pass argument in registers but don't define
REG_PARM_STACK_SPACE. So we force the original behaviour here. */
|| 1
#endif
)
pad_to_arg_alignment (initial_offset_ptr, boundary);
*offset_ptr = *initial_offset_ptr;
#ifdef PUSH_ROUNDING