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:
parent
b111589b09
commit
d16790f212
5 changed files with 143 additions and 28 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
12
gcc/tm.texi
12
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
|
||||
|
|
Loading…
Add table
Reference in a new issue