Makefile.in (print-rtl.o): Depend on TREE_H.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Wed, 17 Oct 2001 09:31:36 +0000 (09:31 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 17 Oct 2001 09:31:36 +0000 (05:31 -0400)
* Makefile.in (print-rtl.o): Depend on TREE_H.
* alias.c (get_alias_set): Make two passes over objects to first
see if inner object is access via restricted pointer.
Defer allocating alias set for restricted pointer until here.
Call find_placeholder with second arg nonzero.
Minor cleanups.
* emit-rtl.c (set_mem_attributes): Set more attributes.
(set_mem_align, change_address, adjust_address_1): New functions.
(change_address_1): Now static.
(adjust_address, adjust_address_nv): Deleted.
(replace_equiv_address): Call change_address_1.
* expr.c (get_inner_reference): Handle PLACEHOLDER_EXPR.
(find_placeholder): Get starting point from PLIST arg.
(expand_expr, case PLACEHOLDER_EXPR): Initialize find_placeholder arg.
* expr.h (set_mem_align, change_address, adjust_address_1): New decls.
(adjust_address, adjust_address_nv): New macros.
* print-rtl.c (tree.h): New include.
(print_rtx, case MEM): Print all memory attributes.

From-SVN: r46313

gcc/ChangeLog
gcc/Makefile.in
gcc/alias.c
gcc/emit-rtl.c
gcc/expr.c
gcc/expr.h
gcc/print-rtl.c

index 33bf8b2..751e583 100644 (file)
@@ -1,3 +1,24 @@
+Wed Oct 17 05:26:39 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * Makefile.in (print-rtl.o): Depend on TREE_H.
+       * alias.c (get_alias_set): Make two passes over objects to first
+       see if inner object is access via restricted pointer.
+       Defer allocating alias set for restricted pointer until here.
+       Call find_placeholder with second arg nonzero.
+       Minor cleanups.
+       * emit-rtl.c (set_mem_attributes): Set more attributes.
+       (set_mem_align, change_address, adjust_address_1): New functions.
+       (change_address_1): Now static.
+       (adjust_address, adjust_address_nv): Deleted.
+       (replace_equiv_address): Call change_address_1.
+       * expr.c (get_inner_reference): Handle PLACEHOLDER_EXPR.
+       (find_placeholder): Get starting point from PLIST arg.
+       (expand_expr, case PLACEHOLDER_EXPR): Initialize find_placeholder arg.
+       * expr.h (set_mem_align, change_address, adjust_address_1): New decls.
+       (adjust_address, adjust_address_nv): New macros.
+       * print-rtl.c (tree.h): New include.
+       (print_rtx, case MEM): Print all memory attributes.
+
 2001-10-17  Richard Henderson  <rth@redhat.com>
 
        * config/alpha/alpha.c (direct_call_operand): Don't fall off end.
index 0184816..27a3111 100644 (file)
@@ -1381,8 +1381,8 @@ rtl-error.o: rtl-error.c system.h $(RTL_H) $(INSN_ATTR_H) insn-config.h \
 rtl.o : rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) real.h $(GGC_H) errors.h
        $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
 
-print-rtl.o : print-rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
-    $(BASIC_BLOCK_H)
+print-rtl.o : print-rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
+    hard-reg-set.h $(BASIC_BLOCK_H)
        $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
 
 rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) hard-reg-set.h
index 53de65f..af0141f 100644 (file)
@@ -99,7 +99,7 @@ static int can_address_p              PARAMS ((tree));
 static rtx find_base_value             PARAMS ((rtx));
 static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx));
 static int insert_subset_children       PARAMS ((splay_tree_node, void*));
-static tree find_base_decl            PARAMS ((tree));
+static tree find_base_decl             PARAMS ((tree));
 static alias_set_entry get_alias_set_entry PARAMS ((HOST_WIDE_INT));
 static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
                                                      int (*) (rtx, int)));
@@ -458,7 +458,6 @@ HOST_WIDE_INT
 get_alias_set (t)
      tree t;
 {
-  tree orig_t;
   HOST_WIDE_INT set;
 
   /* If we're not doing any alias analysis, just assume everything
@@ -473,14 +472,76 @@ get_alias_set (t)
      language-specific routine may make mutually-recursive calls to each other
      to figure out what to do.  At each juncture, we see if this is a tree
      that the language may need to handle specially.  First handle things that
-     aren't types and start by removing nops since we care only about the
-     actual object.  Also replace PLACEHOLDER_EXPRs and pick up the outermost
-     object that we could have a pointer to.  */
+     aren't types.  */
   if (! TYPE_P (t))
     {
-      /* Remove any NOPs and see what any PLACEHOLD_EXPRs will expand to.  */
+      tree inner = t;
+      tree placeholder_ptr = 0;
+
+      /* First see if the actual object referenced is an INDIRECT_REF from a
+        restrict-qualified pointer or a "void *".  Start by removing nops
+        since we care only about the actual object.  Also replace
+        PLACEHOLDER_EXPRs.  */
+      while (((TREE_CODE (inner) == NOP_EXPR
+              || TREE_CODE (inner) == CONVERT_EXPR)
+             && (TYPE_MODE (TREE_TYPE (inner))
+                 == TYPE_MODE (TREE_TYPE (TREE_OPERAND (inner, 0)))))
+            || TREE_CODE (inner) == NON_LVALUE_EXPR
+            || TREE_CODE (inner) == PLACEHOLDER_EXPR
+            || handled_component_p (inner))
+       {
+         if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
+           inner = find_placeholder (inner, &placeholder_ptr);
+         else
+           inner = TREE_OPERAND (inner, 0);
+       }
+
+      /* Check for accesses through restrict-qualified pointers.  */
+      if (TREE_CODE (inner) == INDIRECT_REF)
+       {
+         tree decl = find_base_decl (TREE_OPERAND (inner, 0));
+
+         if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
+           {
+             /* If we haven't computed the actual alias set, do it now. */
+             if (DECL_POINTER_ALIAS_SET (decl) == -2)
+               {
+                 /* No two restricted pointers can point at the same thing.
+                    However, a restricted pointer can point at the same thing
+                    as an unrestricted pointer, if that unrestricted pointer
+                    is based on the restricted pointer.  So, we make the
+                    alias set for the restricted pointer a subset of the
+                    alias set for the type pointed to by the type of the
+                    decl.  */
+                 HOST_WIDE_INT pointed_to_alias_set
+                   = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
+
+                 if (pointed_to_alias_set == 0)
+                   /* It's not legal to make a subset of alias set zero.  */
+                   ;
+                 else
+                   {
+                     DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
+                     record_alias_subset  (pointed_to_alias_set,
+                                           DECL_POINTER_ALIAS_SET (decl));
+                   }
+               }
+
+             /* We use the alias set indicated in the declaration.  */
+             return DECL_POINTER_ALIAS_SET (decl);
+           }
+
+         /* If we have an INDIRECT_REF via a void pointer, we don't
+            know anything about what that might alias.  */
+         else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE)
+           return 0;
+       }
+
+      /* Otherwise, pick up the outermost object that we could have a pointer
+        to, processing conversion and PLACEHOLDER_EXPR as above.  */
+      placeholder_ptr = 0;
       while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR)
-             && (TYPE_MODE (TREE_TYPE (t))
+             && (TYPE_MODE (TREE_TYPE (t))
                  == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))))
             || TREE_CODE (t) == NON_LVALUE_EXPR
             || TREE_CODE (t) == PLACEHOLDER_EXPR
@@ -492,44 +553,22 @@ get_alias_set (t)
            return set;
 
          if (TREE_CODE (t) == PLACEHOLDER_EXPR)
-           t = find_placeholder (t, 0);
+           t = find_placeholder (t, &placeholder_ptr);
          else
            t = TREE_OPERAND (t, 0);
        }
 
-      /* Now give the language a chance to do something but record what we
-        gave it this time.  */
-      orig_t = t;
+      /* Give the language another chance to do something.  */
       if ((set = lang_get_alias_set (t)) != -1)
        return set;
 
-      /* Check for accesses through restrict-qualified pointers.  */
-      if (TREE_CODE (t) == INDIRECT_REF)
-       {
-         tree decl = find_base_decl (TREE_OPERAND (t, 0));
-
-         if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
-           /* We use the alias set indicated in the declaration.  */
-           return DECL_POINTER_ALIAS_SET (decl);
-
-         /* If we have an INDIRECT_REF via a void pointer, we don't
-            know anything about what that might alias.  */
-         if (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE)
-           return 0;
-       }
-
-      /* If we've already determined the alias set for this decl, just
-        return it.  This is necessary for C++ anonymous unions, whose
-        component variables don't look like union members (boo!).  */
+      /* If we've already determined the alias set for a decl, just return
+        it.  This is necessary for C++ anonymous unions, whose component
+        variables don't look like union members (boo!).  */
       if (TREE_CODE (t) == VAR_DECL
          && DECL_RTL_SET_P (t) && GET_CODE (DECL_RTL (t)) == MEM)
        return MEM_ALIAS_SET (DECL_RTL (t));
 
-      /* Give the language another chance to do something special.  */
-      if (orig_t != t
-         && (set = lang_get_alias_set (t)) != -1)
-       return set;
-
       /* Now all we care about is the type.  */
       t = TREE_TYPE (t);
     }
@@ -537,16 +576,12 @@ get_alias_set (t)
   /* Variant qualifiers don't affect the alias set, so get the main
      variant. If this is a type with a known alias set, return it.  */
   t = TYPE_MAIN_VARIANT (t);
-  if (TYPE_P (t) && TYPE_ALIAS_SET_KNOWN_P (t))
+  if (TYPE_ALIAS_SET_KNOWN_P (t))
     return TYPE_ALIAS_SET (t);
 
   /* See if the language has special handling for this type.  */
   if ((set = lang_get_alias_set (t)) != -1)
-    {
-      /* If the alias set is now known, we are done.  */
-      if (TYPE_ALIAS_SET_KNOWN_P (t))
-       return TYPE_ALIAS_SET (t);
-    }
+    return set;
 
   /* There are no objects of FUNCTION_TYPE, so there's no point in
      using up an alias set for them.  (There are, of course, pointers
index eaaf20c..50819c6 100644 (file)
@@ -178,6 +178,8 @@ static rtx make_jump_insn_raw               PARAMS ((rtx));
 static rtx make_call_insn_raw          PARAMS ((rtx));
 static rtx find_line_note              PARAMS ((rtx));
 static void mark_sequence_stack         PARAMS ((struct sequence_stack *));
+static rtx change_address_1            PARAMS ((rtx, enum machine_mode, rtx,
+                                                int));
 static void unshare_all_rtl_1          PARAMS ((rtx));
 static void unshare_all_decls          PARAMS ((tree));
 static void reset_used_decls           PARAMS ((tree));
@@ -1652,14 +1654,6 @@ set_mem_attributes (ref, t, objectp)
 
   type = TYPE_P (t) ? t : TREE_TYPE (t);
 
-  /* Get the alias set from the expression or type (perhaps using a
-     front-end routine) and then copy bits from the type.  */
-
-  /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY (type)
-     here, because, in C and C++, the fact that a location is accessed
-     through a const expression does not mean that the value there can
-     never change.  */
-
   /* If we have already set DECL_RTL = ref, get_alias_set will get the
      wrong answer, as it assumes that DECL_RTL already has the right alias
      info.  Callers should not set DECL_RTL until after the call to
@@ -1667,8 +1661,15 @@ set_mem_attributes (ref, t, objectp)
   if (DECL_P (t) && ref == DECL_RTL_IF_SET (t))
     abort ();
 
+  /* Get the alias set from the expression or type (perhaps using a
+     front-end routine).  */
   set_mem_alias_set (ref, get_alias_set (t));
 
+  /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY (type)
+     here, because, in C and C++, the fact that a location is accessed
+     through a const expression does not mean that the value there can
+     never change.  */
+
   MEM_VOLATILE_P (ref) = TYPE_VOLATILE (type);
   MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
 
@@ -1677,7 +1678,14 @@ set_mem_attributes (ref, t, objectp)
   if (objectp && ! AGGREGATE_TYPE_P (type))
     MEM_SCALAR_P (ref) = 1;
 
-  /* If T is a type, this is all we can do.  Otherwise, we may be able
+  /* If the size is known, we can set that.  */
+  if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
+    MEM_ATTRS (ref)
+      = get_mem_attrs (MEM_ALIAS_SET (ref), MEM_DECL (ref), MEM_OFFSET (ref),
+                      GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1)),
+                      MEM_ALIGN (ref));
+
+  /* If T is a type, there's nothing more we can do.  Otherwise, we may be able
      to deduce some more information about the expression.  */
   if (TYPE_P (t))
     return;
@@ -1686,17 +1694,27 @@ set_mem_attributes (ref, t, objectp)
   if (TREE_THIS_VOLATILE (t))
     MEM_VOLATILE_P (ref) = 1;
 
-  /* Now see if we can say more about whether it's an aggregate or
-     scalar.  If we already know it's an aggregate, don't bother.  */
-  if (MEM_IN_STRUCT_P (ref))
-    return;
-
   /* Now remove any NOPs: they don't change what the underlying object is.
      Likewise for SAVE_EXPR.  */
   while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
         || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == SAVE_EXPR)
     t = TREE_OPERAND (t, 0);
 
+  /* If this is a decl, set the attributes of the MEM from it.  */
+  if (DECL_P (t))
+    MEM_ATTRS (ref)
+      = get_mem_attrs
+       (MEM_ALIAS_SET (ref), t, GEN_INT (0),
+        (TYPE_SIZE_UNIT (TREE_TYPE (t))
+         && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1))
+        ? GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1))
+        : 0, DECL_ALIGN (t) / BITS_PER_UNIT);
+
+  /* Now see if we can say more about whether it's an aggregate or
+     scalar.  If we already know it's an aggregate, don't bother.  */
+  if (MEM_IN_STRUCT_P (ref))
+    return;
+
   /* Since we already know the type isn't an aggregate, if this is a decl,
      it must be a scalar.  Or if it is a reference into an aggregate,
      this is part of an aggregate.   Otherwise we don't know.  */
@@ -1715,7 +1733,6 @@ set_mem_alias_set (mem, set)
      rtx mem;
      HOST_WIDE_INT set;
 {
-  /* It would be nice to enable this check, but we can't quite yet.  */
 #ifdef ENABLE_CHECKING 
   /* If the new and old alias sets don't conflict, something is wrong.  */
   if (!alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)))
@@ -1725,15 +1742,25 @@ set_mem_alias_set (mem, set)
   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem),
                                   MEM_SIZE (mem), MEM_ALIGN (mem));
 }
+
+/* Set the alignment of MEM to ALIGN.  */
+
+void
+set_mem_align (mem, align)
+     rtx mem;
+     unsigned int align;
+{
+  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_DECL (mem),
+                                  MEM_OFFSET (mem), MEM_SIZE (mem), align);
+}
 \f
-/* Return a memory reference like MEMREF, but with its mode changed
-   to MODE and its address changed to ADDR.
-   (VOIDmode means don't change the mode.
-   NULL for ADDR means don't change the address.)
-   VALIDATE is nonzero if the returned memory location is required to be
-   valid.  */
+/* Return a memory reference like MEMREF, but with its mode changed to MODE
+   and its address changed to ADDR.  (VOIDmode means don't change the mode.
+   NULL for ADDR means don't change the address.)  VALIDATE is nonzero if the
+   returned memory location is required to be valid.  The memory
+   attributes are not changed.  */
 
-rtx
+static rtx
 change_address_1 (memref, mode, addr, validate)
      rtx memref;
      enum machine_mode mode;
@@ -1768,60 +1795,81 @@ change_address_1 (memref, mode, addr, validate)
   return new;
 }
 
-/* Return a memory reference like MEMREF, but with its mode changed
-   to MODE and its address offset by OFFSET bytes.  */
+/* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
+   way we are changing MEMREF, so we only preserve the alias set.  */
 
 rtx
-adjust_address (memref, mode, offset)
+change_address (memref, mode, addr)
      rtx memref;
      enum machine_mode mode;
-     HOST_WIDE_INT offset;
+     rtx addr;
 {
-  /* For now, this is just a wrapper for change_address, but eventually
-     will do memref tracking.  */
-  rtx addr = XEXP (memref, 0);
-
-  /* ??? Prefer to create garbage instead of creating shared rtl.  */
-  addr = copy_rtx (addr);
+  rtx new = change_address_1 (memref, mode, addr, 1);
+  enum machine_mode mmode = GET_MODE (new);
 
-  /* If MEMREF is a LO_SUM and the offset is within the alignment of the
-     object, we can merge it into the LO_SUM.  */
-  if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
-      && offset >= 0
-      && (unsigned HOST_WIDE_INT) offset
-         < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
-    addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
-                          plus_constant (XEXP (addr, 1), offset));
-  else
-    addr = plus_constant (addr, offset);
+  MEM_ATTRS (new)
+    = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0,
+                    mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode)),
+                    (mmode == BLKmode ? 1
+                     : GET_MODE_ALIGNMENT (mmode) / BITS_PER_UNIT));
 
-  return change_address (memref, mode, addr);
+  return new;
 }
 
-/* Likewise, but the reference is not required to be valid.  */
+/* Return a memory reference like MEMREF, but with its mode changed
+   to MODE and its address offset by OFFSET bytes.  If VALIDATE is
+   nonzero, the memory address is forced to be valid.  */
 
 rtx
-adjust_address_nv (memref, mode, offset)
+adjust_address_1 (memref, mode, offset, validate)
      rtx memref;
      enum machine_mode mode;
      HOST_WIDE_INT offset;
+     int validate;
 {
-  /* For now, this is just a wrapper for change_address, but eventually
-     will do memref tracking.  */
   rtx addr = XEXP (memref, 0);
+  rtx new;
+  rtx memoffset = MEM_OFFSET (memref);
+  unsigned int memalign = MEM_ALIGN (memref);
 
-  /* If MEMREF is a LO_SUM and the offset is within the size of the
+  /* If MEMREF is a LO_SUM and the offset is within the alignment of the
      object, we can merge it into the LO_SUM.  */
   if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
       && offset >= 0
       && (unsigned HOST_WIDE_INT) offset
          < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
-    addr = gen_rtx_LO_SUM (mode, XEXP (addr, 0),
+    addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
                           plus_constant (XEXP (addr, 1), offset));
+  else if (offset == 0)
+    /* ??? Prefer to create garbage instead of creating shared rtl.  */
+    addr = copy_rtx (addr);
   else
     addr = plus_constant (addr, offset);
 
-  return change_address_1 (memref, mode, addr, 0);
+  new = change_address_1 (memref, mode, addr, validate);
+
+  /* Compute the new values of the memory attributes due to this adjustment.
+     We add the offsets and update the alignment.  */
+  if (memoffset)
+    memoffset = GEN_INT (offset + INTVAL (memoffset));
+
+  /* If the offset is negative, don't try to update the alignment.  If it's
+     zero, the alignment hasn't changed.  Otherwise, the known alignment may
+     be less strict.  */
+  if (offset < 0)
+    memalign = 1;
+
+  while (offset > 0 && (offset % memalign) != 0)
+    memalign >>= 1;
+
+  MEM_ATTRS (new)
+    = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), memoffset,
+                    mode == BLKmode
+                    ? 0 : GEN_INT (GET_MODE_SIZE (mode)), memalign);
+
+  /* At some point, we should validate that this offset is within the object,
+     if all the appropriate values are known.  */
+  return new;
 }
 
 /* Return a memory reference like MEMREF, but with its address changed to
@@ -1834,10 +1882,11 @@ replace_equiv_address (memref, addr)
      rtx memref;
      rtx addr;
 {
-  /* For now, this is just a wrapper for change_address, but eventually
-     will do memref tracking.  */
-  return change_address (memref, VOIDmode, addr);
+  /* change_address_1 copies the memory attribute structure without change
+     and that's exactly what we want here.  */
+  return change_address_1 (memref, VOIDmode, addr, 1);
 }
+
 /* Likewise, but the reference is not required to be valid.  */
 
 rtx
@@ -1845,8 +1894,6 @@ replace_equiv_address_nv (memref, addr)
      rtx memref;
      rtx addr;
 {
-  /* For now, this is just a wrapper for change_address, but eventually
-     will do memref tracking.  */
   return change_address_1 (memref, VOIDmode, addr, 0);
 }
 \f
index 1c81f73..e06d4b1 100644 (file)
@@ -5403,6 +5403,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
   tree offset = size_zero_node;
   tree bit_offset = bitsize_zero_node;
   unsigned int alignment = BIGGEST_ALIGNMENT;
+  tree placeholder_ptr = 0;
   tree tem;
 
   /* First get the mode, signedness, and size.  We do this from just the
@@ -5500,6 +5501,11 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
                                           unit_size));
        }
 
+      else if (TREE_CODE (exp) == PLACEHOLDER_EXPR)
+       {
+         exp = find_placeholder (exp, &placeholder_ptr);
+         continue;
+       }
       else if (TREE_CODE (exp) != NON_LVALUE_EXPR
               && ! ((TREE_CODE (exp) == NOP_EXPR
                      || TREE_CODE (exp) == CONVERT_EXPR)
@@ -5961,10 +5967,11 @@ check_max_integer_computation_mode (exp)
 \f
 /* Return an object on the placeholder list that matches EXP, a
    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
-   PLACEHOLDER_EXPR or a pointer type to it.  For further information,
-   see tree.def.  If no such object is found, abort.  If PLIST is nonzero,
-   it is a location into which a pointer into the placeholder list at
-   which the object is found is placed.  */
+   PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
+   tree.def.  If no such object is found, abort.  If PLIST is nonzero, it is
+   a location which initially points to a starting location in the
+   placeholder list (zero means start of the list) and where a pointer into
+   the placeholder list at which the object is found is placed.  */
 
 tree
 find_placeholder (exp, plist)
@@ -5974,7 +5981,9 @@ find_placeholder (exp, plist)
   tree type = TREE_TYPE (exp);
   tree placeholder_expr;
 
-  for (placeholder_expr = placeholder_list; placeholder_expr != 0;
+  for (placeholder_expr
+       = plist && *plist ? TREE_CHAIN (*plist) : placeholder_list;
+       placeholder_expr != 0;
        placeholder_expr = TREE_CHAIN (placeholder_expr))
     {
       tree need_type = TYPE_MAIN_VARIANT (type);
@@ -6550,7 +6559,7 @@ expand_expr (exp, target, tmode, modifier)
     case PLACEHOLDER_EXPR:
       {
        tree old_list = placeholder_list;
-       tree placeholder_expr;
+       tree placeholder_expr = 0;
 
        exp = find_placeholder (exp, &placeholder_expr);
        placeholder_list = TREE_CHAIN (placeholder_expr);
index a518cf0..af79fd5 100644 (file)
@@ -500,10 +500,11 @@ extern rtx force_operand PARAMS ((rtx, rtx));
 
 /* Return an object on the placeholder list that matches EXP, a
    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
-   PLACEHOLDER_EXPR or a pointer type to it.  For further information,
-   see tree.def.  If no such object is found, abort.  If PLIST is nonzero,
-   it is a location into which a pointer into the placeholder list at
-   which the object is found is placed.  */
+   PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
+   tree.def.  If no such object is found, abort.  If PLIST is nonzero, it is
+   a location which initially points to a starting location in the
+   placeholder list (zero means start of the list) and where a pointer into
+   the placeholder list at which the object is found is placed.  */
 extern tree find_placeholder PARAMS ((tree, tree *));
 
 /* Generate code for computing expression EXP.
@@ -611,23 +612,26 @@ extern rtx memory_address_noforce PARAMS ((enum machine_mode, rtx));
 /* Set the alias set of MEM to SET.  */
 extern void set_mem_alias_set PARAMS ((rtx, HOST_WIDE_INT));
 
+/* Set the alignment of MEM to ALIGN.  */
+extern void set_mem_align PARAMS ((rtx, unsigned int));
+
 /* Return a memory reference like MEMREF, but with its mode changed
    to MODE and its address changed to ADDR.
    (VOIDmode means don't change the mode.
-   NULL for ADDR means don't change the address.)
-   VALIDATE is nonzero if the returned memory location is required to be
-   valid.  */
-extern rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx, int));
-
-#define change_address(MEMREF, MODE, ADDR) \
-  change_address_1 (MEMREF, MODE, ADDR, 1)
+   NULL for ADDR means don't change the address.)  */
+extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
 
 /* Return a memory reference like MEMREF, but with its mode changed
    to MODE and its address offset by OFFSET bytes.  */
-extern rtx adjust_address PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
+#define adjust_address(MEMREF, MODE, OFFSET) \
+  adjust_address_1 (MEMREF, MODE, OFFSET, 1)
 
 /* Likewise, but the reference is not required to be valid.  */
-extern rtx adjust_address_nv PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
+#define adjust_address_nv(MEMREF, MODE, OFFSET) \
+  adjust_address_1 (MEMREF, MODE, OFFSET, 0)
+
+extern rtx adjust_address_1 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT,
+                                    int));
 
 /* Return a memory reference like MEMREF, but with its address changed to
    ADDR.  The caller is asserting that the actual piece of memory pointed
index f2025b5..3d78dd3 100644 (file)
@@ -23,6 +23,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "config.h"
 #include "system.h"
 #include "rtl.h"
+
+/* We don't want the tree code checking code for the access to the
+   DECL_NAME to be included in the gen* programs.  */
+#undef ENABLE_TREE_CHECKING
+#include "tree.h"
 #include "real.h"
 #include "flags.h"
 #include "hard-reg-set.h"
@@ -446,8 +451,30 @@ print_rtx (in_rtx)
   switch (GET_CODE (in_rtx))
     {
     case MEM:
-      fputc (' ', outfile);
+      fputs (" [", outfile);
       fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
+      if (MEM_DECL (in_rtx) && DECL_NAME (MEM_DECL (in_rtx)))
+       fprintf (outfile, " %s",
+                IDENTIFIER_POINTER (DECL_NAME (MEM_DECL (in_rtx))));
+
+      if (MEM_OFFSET (in_rtx))
+       {
+         fputc ('+', outfile);
+         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
+                  INTVAL (MEM_OFFSET (in_rtx)));
+       }
+
+      if (MEM_SIZE (in_rtx))
+       {
+         fputs (" S", outfile);
+         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
+                  INTVAL (MEM_SIZE (in_rtx)));
+       }
+
+      if (MEM_ALIGN (in_rtx) != 1)
+       fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
+
+      fputc (']', outfile);
       break;
 
 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64