aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/calls.c50
-rw-r--r--gcc/config/i386/i386.c2
-rw-r--r--gcc/explow.c7
-rw-r--r--gcc/function.c3
-rw-r--r--gcc/function.h2
-rw-r--r--gcc/integrate.c12
7 files changed, 85 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6977d80..fbfe968 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+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,
diff --git a/gcc/calls.c b/gcc/calls.c
index 84fdd60..03261c0 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 de8517a..1e5e44e 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 1f76dcf..5883ada 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 9b2182e..6945b6b 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 1a94f94..5783c22 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 0cbff9d..865b4bb 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);