mirror of
https://review.haiku-os.org/buildtools
synced 2024-11-23 07:18:49 +01:00
[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:
parent
4837867f67
commit
d9bb2c14a8
@ -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 (®_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 (®_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
|
||||
|
Loading…
Reference in New Issue
Block a user