From d16790f212312ea395cb1d2a4f9641dea9892c64 Mon Sep 17 00:00:00 2001 From: John Wehle Date: Wed, 10 Feb 1999 23:10:43 +0000 Subject: [PATCH] function.c (assign_stack_temp_for_type): Clear best_p when an exact match is found. * function.c (assign_stack_temp_for_type): Clear best_p when an exact match is found. * i386.h (LOCAL_ALIGNMENT): Define. * function.c (assign_stack_local, assign_outer_stack_local): Use it. (assign_stack_temp_for_type): New function based on assign_stack_temp. (assign_stack_temp): Call it. (assign_temp): Use assign_stack_temp_for_type, not assign_stack_temp. * stmt.c: Use assign_temp, not assign_stack_temp. * tm.texi: Document LOCAL_ALIGNMENT. From-SVN: r25143 --- gcc/ChangeLog | 13 ++++++ gcc/config/i386/i386.h | 40 +++++++++++++++++ gcc/function.c | 99 ++++++++++++++++++++++++++++++++---------- gcc/stmt.c | 7 +-- gcc/tm.texi | 12 +++++ 5 files changed, 143 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65d743af9d3..92da3b23e7c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +Thu Feb 11 00:08:17 1999 John Wehle (john@feith.com) + + * function.c (assign_stack_temp_for_type): Clear best_p + when an exact match is found. + + * i386.h (LOCAL_ALIGNMENT): Define. + * function.c (assign_stack_local, assign_outer_stack_local): Use it. + (assign_stack_temp_for_type): New function based on assign_stack_temp. + (assign_stack_temp): Call it. + (assign_temp): Use assign_stack_temp_for_type, not assign_stack_temp. + * stmt.c: Use assign_temp, not assign_stack_temp. + * tm.texi: Document LOCAL_ALIGNMENT. + Wed Feb 10 23:28:28 1999 Jeffrey A Law (law@cygnus.com) * reorg.c: Finish deleting half-deleted comment. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 9e1150b0be3..718c7191817 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -502,6 +502,46 @@ extern int ix86_arch; : (ALIGN)) \ : (ALIGN)) +/* If defined, a C expression to compute the alignment for a local + variable. TYPE is the data type, and ALIGN is the alignment that + the object would ordinarily have. The value of this macro is used + instead of that alignment to align the object. + + If this macro is not defined, then ALIGN is used. + + One use of this macro is to increase alignment of medium-size + data to make it all fit in fewer cache lines. */ + +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == ARRAY_TYPE \ + ? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : TREE_CODE (TYPE) == COMPLEX_TYPE \ + ? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : ((TREE_CODE (TYPE) == RECORD_TYPE \ + || TREE_CODE (TYPE) == UNION_TYPE \ + || TREE_CODE (TYPE) == QUAL_UNION_TYPE) \ + && TYPE_FIELDS (TYPE)) \ + ? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : TREE_CODE (TYPE) == REAL_TYPE \ + ? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : (ALIGN)) + /* Set this non-zero if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT 0 diff --git a/gcc/function.c b/gcc/function.c index c9ec569c570..a14a886d4e8 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -65,6 +65,10 @@ Boston, MA 02111-1307, USA. */ #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY #endif +#ifndef LOCAL_ALIGNMENT +#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT +#endif + /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to give the same symbol without quotes for an alternative entry point. You @@ -386,6 +390,8 @@ struct temp_slot /* The rtx used to represent the address if not the address of the slot above. May be an EXPR_LIST if multiple addresses exist. */ rtx address; + /* The alignment (in bits) of the slot. */ + int align; /* The size, in units, of the slot. */ HOST_WIDE_INT size; /* The value of `sequence_rtl_expr' when this temporary is allocated. */ @@ -440,6 +446,8 @@ struct fixup_replacement static rtx assign_outer_stack_local PROTO ((enum machine_mode, HOST_WIDE_INT, int, struct function *)); +static rtx assign_stack_temp_for_type PROTO ((enum machine_mode, HOST_WIDE_INT, + int, tree)); static struct temp_slot *find_temp_slot_from_address PROTO((rtx)); static void put_reg_into_stack PROTO((struct function *, rtx, tree, enum machine_mode, enum machine_mode, @@ -716,9 +724,19 @@ assign_stack_local (mode, size, align) if (align == 0) { - alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; + tree type; + + alignment = GET_MODE_ALIGNMENT (mode); if (mode == BLKmode) - alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT; + alignment = BIGGEST_ALIGNMENT; + + /* Allow the target to (possibly) increase the alignment of this + stack slot. */ + type = type_for_mode (mode, 0); + if (type) + alignment = LOCAL_ALIGNMENT (type, alignment); + + alignment /= BITS_PER_UNIT; } else if (align == -1) { @@ -791,9 +809,19 @@ assign_outer_stack_local (mode, size, align, function) if (align == 0) { - alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; + tree type; + + alignment = GET_MODE_ALIGNMENT (mode); if (mode == BLKmode) - alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT; + alignment = BIGGEST_ALIGNMENT; + + /* Allow the target to (possibly) increase the alignment of this + stack slot. */ + type = type_for_mode (mode, 0); + if (type) + alignment = LOCAL_ALIGNMENT (type, alignment); + + alignment /= BITS_PER_UNIT; } else if (align == -1) { @@ -849,12 +877,14 @@ assign_outer_stack_local (mode, size, align, function) if we are to allocate something at an inner level to be treated as a variable in the block (e.g., a SAVE_EXPR). */ -rtx -assign_stack_temp (mode, size, keep) +static rtx +assign_stack_temp_for_type (mode, size, keep, type) enum machine_mode mode; HOST_WIDE_INT size; int keep; + tree type; { + int align; struct temp_slot *p, *best_p = 0; /* If SIZE is -1 it means that somebody tried to allocate a temporary @@ -862,19 +892,31 @@ assign_stack_temp (mode, size, keep) if (size == -1) abort (); - /* First try to find an available, already-allocated temporary that is the - exact size we require. */ - for (p = temp_slots; p; p = p->next) - if (p->size == size && GET_MODE (p->slot) == mode && ! p->in_use) - break; + align = GET_MODE_ALIGNMENT (mode); + if (mode == BLKmode) + align = BIGGEST_ALIGNMENT; - /* If we didn't find, one, try one that is larger than what we want. We - find the smallest such. */ - if (p == 0) - for (p = temp_slots; p; p = p->next) - if (p->size > size && GET_MODE (p->slot) == mode && ! p->in_use - && (best_p == 0 || best_p->size > p->size)) + if (! type) + type = type_for_mode (mode, 0); + if (type) + align = LOCAL_ALIGNMENT (type, align); + + /* Try to find an available, already-allocated temporary of the proper + mode which meets the size and alignment requirements. Choose the + smallest one with the closest alignment. */ + for (p = temp_slots; p; p = p->next) + if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode + && ! p->in_use + && (best_p == 0 || best_p->size > p->size + || (best_p->size == p->size && best_p->align > p->align))) + { + if (p->align == align && p->size == size) + { + best_p = 0; + break; + } best_p = p; + } /* Make our best, if any, the one to use. */ if (best_p) @@ -884,7 +926,7 @@ assign_stack_temp (mode, size, keep) for BLKmode slots, so that we can be sure of the alignment. */ if (GET_MODE (best_p->slot) == BLKmode) { - int alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT; + int alignment = best_p->align / BITS_PER_UNIT; HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment); if (best_p->size - rounded_size >= alignment) @@ -897,6 +939,7 @@ assign_stack_temp (mode, size, keep) p->slot = gen_rtx_MEM (BLKmode, plus_constant (XEXP (best_p->slot, 0), rounded_size)); + p->align = best_p->align; p->address = 0; p->rtl_expr = 0; p->next = temp_slots; @@ -920,9 +963,9 @@ assign_stack_temp (mode, size, keep) p = (struct temp_slot *) oballoc (sizeof (struct temp_slot)); - /* If the temp slot mode doesn't indicate the alignment, - use the largest possible, so no one will be disappointed. */ - p->slot = assign_stack_local (mode, size, mode == BLKmode ? -1 : 0); + p->slot = assign_stack_local (mode, size, align); + + p->align = align; /* The following slot size computation is necessary because we don't know the actual size of the temporary slot until assign_stack_local @@ -978,6 +1021,18 @@ assign_stack_temp (mode, size, keep) MEM_ALIAS_SET (p->slot) = 0; return p->slot; } + +/* Allocate a temporary stack slot and record it for possible later + reuse. First three arguments are same as in preceding function. */ + +rtx +assign_stack_temp (mode, size, keep) + enum machine_mode mode; + HOST_WIDE_INT size; + int keep; +{ + return assign_stack_temp_for_type (mode, size, keep, NULL_TREE); +} /* Assign a temporary of given TYPE. KEEP is as for assign_stack_temp. @@ -1010,7 +1065,7 @@ assign_temp (type, keep, memory_required, dont_promote) && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type)) == INTEGER_CST) size = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type)); - tmp = assign_stack_temp (mode, size, keep); + tmp = assign_stack_temp_for_type (mode, size, keep, type); MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type)); return tmp; } diff --git a/gcc/stmt.c b/gcc/stmt.c index 62f880dd4d2..a565adf6402 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -3495,12 +3495,7 @@ expand_decl (decl) oldaddr = XEXP (DECL_RTL (decl), 0); } - DECL_RTL (decl) - = assign_stack_temp (DECL_MODE (decl), - ((TREE_INT_CST_LOW (DECL_SIZE (decl)) - + BITS_PER_UNIT - 1) - / BITS_PER_UNIT), - 1); + DECL_RTL (decl) = assign_temp (TREE_TYPE (decl), 1, 1, 1); MEM_SET_IN_STRUCT_P (DECL_RTL (decl), AGGREGATE_TYPE_P (TREE_TYPE (decl))); diff --git a/gcc/tm.texi b/gcc/tm.texi index 2e2f688f793..d3dac9fd938 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -873,6 +873,18 @@ The typical use of this macro is to increase alignment for string constants to be word aligned so that @code{strcpy} calls that copy constants can be done inline. +@findex LOCAL_ALIGNMENT +@item LOCAL_ALIGNMENT (@var{type}, @var{basic-align}) +If defined, a C expression to compute the alignment for a variables in +the local store. @var{type} is the data type, and @var{basic-align} is +the alignment that the object would ordinarily have. The value of this +macro is used instead of that alignment to align the object. + +If this macro is not defined, then @var{basic-align} is used. + +One use of this macro is to increase alignment of medium-size data to +make it all fit in fewer cache lines. + @findex EMPTY_FIELD_BOUNDARY @item EMPTY_FIELD_BOUNDARY Alignment in bits to be given to a structure bit field that follows an -- 2.30.2