function.c (assign_stack_temp_for_type): Clear best_p when an exact match is found.
authorJohn Wehle <john@feith.com>
Wed, 10 Feb 1999 23:10:43 +0000 (23:10 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 10 Feb 1999 23:10:43 +0000 (16:10 -0700)
        * 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
gcc/config/i386/i386.h
gcc/function.c
gcc/stmt.c
gcc/tm.texi

index 65d743af9d3084451243fbcdca83e430ce854d0c..92da3b23e7c1652688b21eb477eb62c8bb97beca 100644 (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.
index 9e1150b0be380f17d0f9c84e7ec2633d20abda50..718c719181752e16e3b69d0f1844b100a21ae0f7 100644 (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
index c9ec569c57063c47a1b277017d6fe0a042bdafb2..a14a886d4e8414db679559c360b07786bb8ed052 100644 (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);
+}
 \f
 /* 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;
     }
index 62f880dd4d24456aee7fa364edbf5d2ff12ed6f2..a565adf640209bc718080cf54c24412ddb285eb3 100644 (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)));
 
index 2e2f688f7937b86ba33b160d4cd64b19321e5b5f..d3dac9fd938b5cdbded822175d41a41bbe720d47 100644 (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