+Mon Feb 7 18:36:41 MET 2000 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (compute_argument_block_size): New argument
+ preferred_stack_boundary.
+ (expand_call): update cfun->preferred_stack_boundary, update call of
+ compute_argument_block_size
+ (emit_library_call): Increate cfun->preferred_stack_boundary
+ to PREFERRED_STACK_BOUNDARY
+ (emit_library_call_value): Likewise.
+ * explow.c (allocate_dynamic_stack_spave): Likewise.
+ * function.c (prepare_function_start): Set
+ cfun->preferred_stack_boundary
+ * function.h (struct function): Add preferred_stack_boundary field.
+ * integrate.c (expand_inline_function): Update
+ cfun->preferred_stack_boundary and cfun->stack_alignment_needed.
+ (copy_rtx_and_substitute): Align frame to stack_alignment_needed only.
+ * i386.c (compute_frame_size): Use cfun->preferred_stack_boundary.
+
2000-02-06 Zack Weinberg <zack@wolery.cumb.org>
* cpplib.c (my_strerror, cpp_error, cpp_error_with_line,
struct arg_data *,
struct args_size *));
static int compute_argument_block_size PARAMS ((int,
- struct args_size *));
+ struct args_size *,
+ int));
static void initialize_argument_information PARAMS ((int,
struct arg_data *,
struct args_size *,
for arguments passed in registers. */
static int
-compute_argument_block_size (reg_parm_stack_space, args_size)
+compute_argument_block_size (reg_parm_stack_space, args_size,
+ preferred_stack_boundary)
int reg_parm_stack_space;
struct args_size *args_size;
+ int preferred_stack_boundary ATTRIBUTE_UNUSED;
{
int unadjusted_args_size = args_size->constant;
args_size->constant = 0;
#ifdef PREFERRED_STACK_BOUNDARY
- if (PREFERRED_STACK_BOUNDARY != BITS_PER_UNIT)
- args_size->var = round_up (args_size->var, STACK_BYTES);
+ preferred_stack_boundary /= BITS_PER_UNIT;
+ if (preferred_stack_boundary > 1)
+ args_size->var = round_up (args_size->var, preferred_stack_boundary);
#endif
if (reg_parm_stack_space > 0)
else
{
#ifdef PREFERRED_STACK_BOUNDARY
+ preferred_stack_boundary /= BITS_PER_UNIT;
args_size->constant = (((args_size->constant
+ pending_stack_adjust
- + STACK_BYTES - 1)
- / STACK_BYTES * STACK_BYTES)
+ + preferred_stack_boundary - 1)
+ / preferred_stack_boundary
+ * preferred_stack_boundary)
- pending_stack_adjust);
#endif
rtx call_fusage = 0;
register tree p;
register int i;
+#ifdef PREFERRED_STACK_BOUNDARY
+ int preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+#else
+ /* In this case preferred_stack_boundary variable is meaningless.
+ It is used only in order to keep ifdef noise down when calling
+ compute_argument_block_size. */
+ int preferred_stack_boundary = 0;
+#endif
/* The value of the function call can be put in a hard register. But
if -fcheck-memory-usage, code which invokes functions (and thus
if (fndecl && DECL_NAME (fndecl))
name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
+ /* Ensure current function's preferred stack boundary is at least
+ what we need. We don't have to increase alignment for recursive
+ functions. */
+ if (cfun->preferred_stack_boundary < preferred_stack_boundary
+ && fndecl != current_function_decl)
+ cfun->preferred_stack_boundary = preferred_stack_boundary;
+
/* See if this is a call to a function that can return more than once
or a call to longjmp or malloc. */
special_function_p (fndecl, &returns_twice, &is_longjmp, &fork_or_exec,
and constant sizes must be combined, the size may have to be rounded,
and there may be a minimum required size. */
unadjusted_args_size
- = compute_argument_block_size (reg_parm_stack_space, &args_size);
+ = compute_argument_block_size (reg_parm_stack_space, &args_size,
+ preferred_stack_boundary);
/* Now make final decision about preallocating stack space. */
must_preallocate = finalize_must_preallocate (must_preallocate,
push_temp_slots ();
+#ifdef PREFERRED_STACK_BOUNDARY
+ /* Ensure current function's preferred stack boundary is at least
+ what we need. */
+ if (cfun->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
+ cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+#endif
+
for (count = 0; count < nargs; count++)
{
rtx val = va_arg (p, rtx);
is_const = no_queue;
fun = orgfun;
+#ifdef PREFERRED_STACK_BOUNDARY
+ /* Ensure current function's preferred stack boundary is at least
+ what we need. */
+ if (cfun->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
+ cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+#endif
+
/* If this kind of value comes back in memory,
decide where in memory it should come back. */
if (aggregate_value_p (type_for_mode (outmode, 0)))
nargs = list_length (DECL_ARGUMENTS (fndecl));
+ if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
+ cfun->preferred_stack_boundary = inl_f->preferred_stack_boundary;
+
+ if (cfun->stack_alignment_needed < inl_f->stack_alignment_needed)
+ cfun->stack_alignment_needed = inl_f->stack_alignment_needed;
+
/* Check that the parms type match and that sufficient arguments were
passed. Since the appropriate conversions or default promotions have
already been applied, the machine modes should match exactly. */
{
rtx loc, seq;
int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
+ int alignment
+ = (DECL_SAVED_INSNS (map->fndecl)->stack_alignment_needed
+ / BITS_PER_UNIT);
#ifdef FRAME_GROWS_DOWNWARD
/* In this case, virtual_stack_vars_rtx points to one byte
higher than the top of the frame area. So make sure we
allocate a big enough chunk to keep the frame pointer
aligned like a real one. */
- size = CEIL_ROUND (size, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ if (alignment)
+ size = CEIL_ROUND (size, alignment);
#endif
start_sequence ();
loc = assign_stack_temp (BLKmode, size, 1);