From c2f8b491493226d196fc80a9f0d4856612c52992 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 7 Feb 2000 18:39:40 +0100 Subject: [PATCH] calls.c (compute_argument_block_size): New argument preferred_stack_boundary. * 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. From-SVN: r31831 --- gcc/ChangeLog | 18 +++++++++++++++ gcc/calls.c | 50 ++++++++++++++++++++++++++++++++++++------ gcc/config/i386/i386.c | 2 +- gcc/explow.c | 7 ++++++ gcc/function.c | 3 +++ gcc/function.h | 2 ++ gcc/integrate.c | 12 +++++++++- 7 files changed, 85 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6977d80f777..fbfe968d702 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +Mon Feb 7 18:36:41 MET 2000 Jan Hubicka + + * 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 * cpplib.c (my_strerror, cpp_error, cpp_error_with_line, diff --git a/gcc/calls.c b/gcc/calls.c index 84fdd606604..03261c08046 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -148,7 +148,8 @@ static void precompute_arguments PARAMS ((int, int, int, 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 *, @@ -1176,9 +1177,11 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, 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; @@ -1192,8 +1195,9 @@ compute_argument_block_size (reg_parm_stack_space, args_size) 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) @@ -1214,10 +1218,12 @@ compute_argument_block_size (reg_parm_stack_space, args_size) 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 @@ -1692,6 +1698,14 @@ expand_call (exp, target, ignore) 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 @@ -1921,6 +1935,13 @@ expand_call (exp, target, ignore) 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, @@ -2062,7 +2083,8 @@ expand_call (exp, target, ignore) 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, @@ -2703,6 +2725,13 @@ emit_library_call VPARAMS((rtx orgfun, int no_queue, enum machine_mode outmode, 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); @@ -3192,6 +3221,13 @@ emit_library_call_value VPARAMS((rtx orgfun, rtx value, int no_queue, 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))) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index de8517a0e79..1e5e44ed73e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1776,7 +1776,7 @@ ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2) #ifdef PREFERRED_STACK_BOUNDARY { int offset; - int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT; offset = frame_pointer_needed ? 8 : 4; diff --git a/gcc/explow.c b/gcc/explow.c index 1f76dcf081d..5883adaee81 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -1178,6 +1178,13 @@ allocate_dynamic_stack_space (size, target, known_align) if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) size = convert_to_mode (Pmode, size, 1); + /* We can't attempt to minimize alignment necessary, because we don't + know the final value of preferred_stack_boundary yet while executing + this code. */ +#ifdef PREFERRED_STACK_BOUNDARY + cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; +#endif + /* We will need to ensure that the address we return is aligned to BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't always know its final value at this point in the compilation (it diff --git a/gcc/function.c b/gcc/function.c index 9b2182eb16a..6945b6b53e0 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -5686,6 +5686,9 @@ prepare_function_start () cfun->original_arg_vector = 0; cfun->stack_alignment_needed = 0; +#ifdef STACK_BOUNDARY + cfun->preferred_stack_boundary = STACK_BOUNDARY; +#endif /* Set if a call to setjmp is seen. */ current_function_calls_setjmp = 0; diff --git a/gcc/function.h b/gcc/function.h index 1a94f948c69..5783c22b6ff 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -456,6 +456,8 @@ struct function struct machine_function *machine; /* The largest alignment of slot allocated on the stack. */ int stack_alignment_needed; + /* Preferred alignment of the end of stack frame. */ + int preferred_stack_boundary; /* Language-specific code can use this to store whatever it likes. */ struct language_function *language; diff --git a/gcc/integrate.c b/gcc/integrate.c index 0cbff9d05f3..865b4bb6faa 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -602,6 +602,12 @@ expand_inline_function (fndecl, parms, target, ignore, type, 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. */ @@ -1619,13 +1625,17 @@ copy_rtx_and_substitute (orig, map, for_lhs) { 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); -- 2.30.2