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
This commit is contained in:
John Wehle 1999-02-10 23:10:43 +00:00 committed by Jeff Law
parent b111589b09
commit d16790f212
5 changed files with 143 additions and 28 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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)));

View File

@ -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