This is the mail archive of the egcs@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.
On Feb 16, 1999, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote:
> I am getting bootstrap failures on sparc's for egcs-2.93.08
> 19990215. I initially reported an identical problem on SunOS4 with
> --enable-c-cpplib, however it occurs even with no special options. I.e.
> its not specific to cpplib. Both solaris and SunOS4 have this error.
Yep, any target with strict alignment requirements should be
presenting this kind of error for code such as
#include <stdlib.h>
main() {
char c[5];
memset(c, 0, sizeof(c));
}
The problem is a side-effect of:
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.
It causes the array c to be unaligned. This wouldn't be a problem if
the inlined version of memset() didn't assume that its argument is
properly aligned in this case. This patch is probably also causing
slow-downs on other targets that do not reject unaligned data, just
run slower.
Reverting the patch is an obvious temporary fix, since it causes
assign_stack_temp[_for_type] to call assign_stack_local with
align==-1, so that size is rounded up and becomes properly aligned for
sparc, but it would defeat the purpose of the patch. So we should
probably fix the code that inlines memset() et al. so as to properly
handle such misalignments.
For your convenience, here's the relevant part of John Wehle's patch,
that should be reverted in order to bootstrap on sparc targets.
--
Alexandre Oliva http://www.dcc.unicamp.br/~oliva aoliva@{acm.org}
oliva@{dcc.unicamp.br,gnu.org,egcs.cygnus.com,samba.org}
Universidade Estadual de Campinas, SP, Brasil
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -c -r1.72 -r1.73
diff: conflicting specifications of output style
*** function.c 1999/02/08 21:39:24 1.72
--- function.c 1999/02/10 23:10:39 1.73
***************
*** 65,70 ****
--- 65,74 ----
#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,391 ****
--- 390,397 ----
/* 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,445 ****
--- 446,453 ----
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,724 ****
if (align == 0)
{
! alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
if (mode == BLKmode)
! alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
}
else if (align == -1)
{
--- 724,742 ----
if (align == 0)
{
! tree type;
!
! alignment = GET_MODE_ALIGNMENT (mode);
if (mode == BLKmode)
! 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,799 ****
if (align == 0)
{
! alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
if (mode == BLKmode)
! alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
}
else if (align == -1)
{
--- 809,827 ----
if (align == 0)
{
! tree type;
!
! alignment = GET_MODE_ALIGNMENT (mode);
if (mode == BLKmode)
! 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,860 ****
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)
enum machine_mode mode;
HOST_WIDE_INT size;
int keep;
{
struct temp_slot *p, *best_p = 0;
/* If SIZE is -1 it means that somebody tried to allocate a temporary
--- 877,890 ----
if we are to allocate something at an inner level to be treated as
a variable in the block (e.g., a SAVE_EXPR). */
! 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,880 ****
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;
!
! /* 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))
best_p = p;
/* Make our best, if any, the one to use. */
if (best_p)
--- 892,922 ----
if (size == -1)
abort ();
! align = GET_MODE_ALIGNMENT (mode);
! if (mode == BLKmode)
! align = BIGGEST_ALIGNMENT;
!
! 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,890 ****
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;
HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
if (best_p->size - rounded_size >= alignment)
--- 926,932 ----
for BLKmode slots, so that we can be sure of the alignment. */
if (GET_MODE (best_p->slot) == BLKmode)
{
! 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,902 ****
--- 939,945 ----
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;
***************
*** 919,928 ****
HOST_WIDE_INT frame_offset_old = frame_offset;
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);
/* The following slot size computation is necessary because we don't
know the actual size of the temporary slot until assign_stack_local
--- 962,971 ----
HOST_WIDE_INT frame_offset_old = frame_offset;
p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
+
+ 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,983 ****
--- 1021,1038 ----
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,1016 ****
&& 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);
MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
return tmp;
}
--- 1065,1071 ----
&& TREE_CODE (TYPE_ARRAY_MAX_SIZE (type)) == INTEGER_CST)
size = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type));
! tmp = assign_stack_temp_for_type (mode, size, keep, type);
MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
return tmp;
}