Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Wed, 31 May 2000 18:37:31 +0000 (18:37 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 31 May 2000 18:37:31 +0000 (14:37 -0400)
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.

From-SVN: r34305

28 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/alias.c
gcc/builtins.c
gcc/c-common.c
gcc/c-common.h
gcc/c-typeck.c
gcc/caller-save.c
gcc/calls.c
gcc/cp/ChangeLog
gcc/cp/Makefile.in
gcc/cp/decl.c
gcc/cp/tree.c
gcc/explow.c
gcc/expr.c
gcc/expr.h
gcc/function.c
gcc/recog.c
gcc/regmove.c
gcc/reload.c
gcc/reload1.c
gcc/rtl.def
gcc/rtl.h
gcc/stmt.c
gcc/stor-layout.c
gcc/toplev.c
gcc/tree.c
gcc/tree.h

index 9f9c79b..62555cb 100644 (file)
@@ -32,6 +32,87 @@ Wed May 31 13:17:20 2000  Philippe De Muyter  <phdm@macqel.be>
 
 Wed May 31 08:07:52 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
+       * alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
+       (REG_BASE_VALUE): Remove unneeded cast to unsigned.
+       (get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
+       (find_base_decl): New function, from c_find_base_decl in c-common.c.
+       (new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
+       (get_alias_set): Likewise.
+       Major rework to do more things and allow language-specific code
+       to just handle special-cases.
+       (record_alias_subset): Args are HOST_WIDE_INT.
+       (record_component_alias): Local vars are HOST_WIDE_INT.
+       Don't handle COMPLEX_EXPR.
+       (get_varargs_alias_set): Moved from builtins.c.
+       (get_frame_alias_set): New function.
+       * builtins.c (expand_builtin_return_address): Use frame alias set.
+       (expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
+       for setjmp buffer.
+       (get_memory_rtx): Rework to use set_mem_attributes.
+       (get_varargs_alias_set): Deleted from here.
+       * c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
+       (c_find_base_decl): Deleted from here.
+       (c_get_alias_set): Remove many cases and rework to just handle
+       C-specific cases.
+       * c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
+       * c-decl.c (rtl.h, expr.h): Now included.
+       (init_decl_processing): Call record_component_aliases on array types.
+       (grokdeclarator): Likewise.
+       Set TREE_ADDRESSABLE for all fields that are not bitfields.
+       * c-typeck.c (common_type): Call record_component_aliases for array.
+       * caller-save.c (setup_save_areas): Rework register loop for unsigned.
+       Set all save areas to the frame alias set.
+       * calls.c (initialie_argument_information): Call set_mem_attributes.
+       (compute_argument_addresses, expand_call): Likewise.
+       * explow.c (set_mem_attributes): New function.
+       (stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
+       * expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
+       LEN and OFFSET now HOST_WIDE_INT.
+       (clear_by_pieces): Similar changes.
+       (move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
+       (move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
+       (move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
+       (clear_by_pieces_1): Likewise.
+       (emit_push_insn): Call set_mem_attributes.
+       (expand_expr, case INDIRECT_REF): Likewise.
+       (expand_expr, case VAR_DECL): Call change_address.
+       * expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
+       tree_low_cst.
+       (get_varargs_alias_set, get_frame_alias_set): New decls.
+       (record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
+       (new_alias_set, set_mem_attributes): Likewse.
+       * function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
+       (assign_stack_temp_for_type): Likewise.
+       Can split slot even if alias set since can copy.
+       Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
+       (assign_temp): Use host_integerp and tree_low_cst.
+       (put_var_into_stack): Properly handle SAVE_EXPR.
+       (put_addressof_into_stack): Likewise.
+       (assign_parms): Call set_mem_attributes.
+       Delete #if 0 code.
+       (fix_lexical_address): Put reference to chain into frame alias set.
+       (expand_function_start): Call set_mem_attributes.
+       * integrate.c (expand_inline_function): Likewise.
+       * recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
+       * regmove.c (try_apply_stack_adjustment): Likewise.
+       * reload.c (push_reload, make_memloc): Likewise.
+       * reload1.c (alter_reg): Make alias sets for spilled pseudos.
+       * rtl.def (MEM): Update comment.
+       * rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
+       (move_by_pieces): Change length to HOST_WIDE_INT.
+       (record_base_value, record_alias_subset): Delete from here.
+       * stmt.c (expand_decl): Call set_mem_attributes.
+       * stor-layout.c (finish_record_layout): Call record_component_aliases.i
+       * toplev.c (compile_file): Call init_alias_once earlier.
+       * tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
+       from here: now in alias.c.
+       * tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
+       (struct tree_decl): Likewise.
+       (get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
+       * varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
+       (output_constant_def, force_const_mem): Likewise.
+       
        * flow.c (propagate_block): If block has no successors, stores to
        frame are dead if not used.
 
index 8640756..f131dab 100644 (file)
@@ -1092,12 +1092,13 @@ $(srcdir)/c-gperf.h: c-parse.gperf
        exit 1 )
         $(SHELL) $(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h
 
-c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h $(GGC_H) \
-    c-lex.h flags.h function.h output.h toplev.h defaults.h
+c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \
+    c-common.h $(GGC_H) c-lex.h flags.h function.h output.h expr.h toplev.h \
+    defaults.h
 c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
     flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h
-c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h $(GGC_H) \
-    c-lex.h toplev.h output.h function.h
+c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
+    $(GGC_H)  c-lex.h toplev.h output.h function.h
 c-lex.o : c-lex.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-lex.h c-tree.h \
     c-common.h $(srcdir)/c-parse.h $(srcdir)/c-gperf.h c-pragma.h input.h \
     intl.h flags.h toplev.h output.h mbchar.h $(GGC_H)
index 9d3ff8b..feed541 100644 (file)
@@ -57,10 +57,10 @@ Boston, MA 02111-1307, USA.  */
     In this situation we say the alias set for `struct S' is the
    `superset' and that those for `int' and `double' are `subsets'.
 
-   To see whether two alias sets can point to the same memory, we must go
-   down the list of decendents of each and see if there is some alias set
-   in common.  We need not trace past immediate decendents, however, since
-   we propagate all grandchildren up one level.
+   To see whether two alias sets can point to the same memory, we must
+   see if either alias set is a subset of the other. We need not trace
+   past immediate decendents, however, since we propagate all
+   grandchildren up one level.
 
    Alias set zero is implicitly a superset of all other alias sets.
    However, this is no actual entry for alias set zero.  It is an
@@ -69,7 +69,7 @@ Boston, MA 02111-1307, USA.  */
 typedef struct alias_set_entry
 {
   /* The alias set number, as stored in MEM_ALIAS_SET.  */
-  int alias_set;
+  HOST_WIDE_INT alias_set;
 
   /* The children of the alias set.  These are not just the immediate
      children, but, in fact, all decendents.  So, if we have:
@@ -81,6 +81,10 @@ typedef struct alias_set_entry
   splay_tree children;
 } *alias_set_entry;
 
+/* The language-specific function for alias analysis.  If NULL, the
+   language does not do any special alias analysis.  */
+HOST_WIDE_INT (*lang_get_alias_set) PARAMS ((tree));
+
 static int rtx_equal_for_memref_p      PARAMS ((rtx, rtx));
 static rtx find_symbolic_term          PARAMS ((rtx));
 static rtx get_addr                    PARAMS ((rtx));
@@ -93,9 +97,10 @@ static int base_alias_check          PARAMS ((rtx, rtx, enum machine_mode,
 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 alias_set_entry get_alias_set_entry PARAMS ((int));
+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 (*) (rtx)));
 static int aliases_everything_p         PARAMS ((rtx));
 static int write_dependence_p           PARAMS ((rtx, rtx, int));
 static int nonlocal_reference_p         PARAMS ((rtx));
@@ -140,7 +145,7 @@ static rtx *new_reg_base_value;
 static unsigned int reg_base_value_size; /* size of reg_base_value array */
 
 #define REG_BASE_VALUE(X) \
-  ((unsigned) REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
+  (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
 
 /* Vector of known invariant relationships between registers.  Set in
    loop unrolling.  Indexed by register number, if nonzero the value
@@ -187,7 +192,7 @@ static splay_tree alias_sets;
 
 static alias_set_entry
 get_alias_set_entry (alias_set)
-     int alias_set;
+     HOST_WIDE_INT alias_set;
 {
   splay_tree_node sn
     = splay_tree_lookup (alias_sets, (splay_tree_key) alias_set);
@@ -236,8 +241,7 @@ mems_in_disjoint_alias_sets_p (mem1, mem2)
   if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2))
     return 0;
 
-  /* Iterate through each of the children of the first alias set,
-     comparing it with the second alias set.  */
+  /* See if the first alias set is a subset of the second.  */
   ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
   if (ase != 0 && splay_tree_lookup (ase->children,
                                     (splay_tree_key) MEM_ALIAS_SET (mem2)))
@@ -266,6 +270,168 @@ insert_subset_children (node, data)
 
   return 0;
 }
+\f
+/* T is an expression with pointer type.  Find the DECL on which this
+   expression is based.  (For example, in `a[i]' this would be `a'.)
+   If there is no such DECL, or a unique decl cannot be determined,
+   NULL_TREE is retured.  */
+
+static tree
+find_base_decl (t)
+     tree t;
+{
+  tree d0, d1, d2;
+
+  if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t)))
+    return 0;
+
+  /* If this is a declaration, return it.  */
+  if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
+    return t;
+
+  /* Handle general expressions.  It would be nice to deal with
+     COMPONENT_REFs here.  If we could tell that `a' and `b' were the
+     same, then `a->f' and `b->f' are also the same.  */
+  switch (TREE_CODE_CLASS (TREE_CODE (t)))
+    {
+    case '1':
+      return find_base_decl (TREE_OPERAND (t, 0));
+
+    case '2':
+      /* Return 0 if found in neither or both are the same.  */
+      d0 = find_base_decl (TREE_OPERAND (t, 0));
+      d1 = find_base_decl (TREE_OPERAND (t, 1));
+      if (d0 == d1)
+       return d0;
+      else if (d0 == 0)
+       return d1;
+      else if (d1 == 0)
+       return d0;
+      else
+       return 0;
+
+    case '3':
+      d0 = find_base_decl (TREE_OPERAND (t, 0));
+      d1 = find_base_decl (TREE_OPERAND (t, 1));
+      d0 = find_base_decl (TREE_OPERAND (t, 0));
+      d2 = find_base_decl (TREE_OPERAND (t, 2));
+
+      /* Set any nonzero values from the last, then from the first.  */
+      if (d1 == 0) d1 = d2;
+      if (d0 == 0) d0 = d1;
+      if (d1 == 0) d1 = d0;
+      if (d2 == 0) d2 = d1;
+
+      /* At this point all are nonzero or all are zero.  If all three are the
+        same, return it.  Otherwise, return zero.  */
+      return (d0 == d1 && d1 == d2) ? d0 : 0;
+
+    default:
+      return 0;
+    }
+}
+
+/* Return the alias set for T, which may be either a type or an
+   expression.  Call language-specific routine for help, if needed.  */
+
+HOST_WIDE_INT
+get_alias_set (t)
+     tree t;
+{
+  HOST_WIDE_INT set;
+  HOST_WIDE_INT bitsize, bitpos;
+  tree offset;
+  enum machine_mode mode;
+  int volatilep, unsignedp;
+  unsigned int alignment;
+
+  /* If we're not doing any alias analysis, just assume everything
+     aliases everything else.  Also return 0 if this or its type is
+     an error.  */
+  if (! flag_strict_aliasing || t == error_mark_node
+      || (! TYPE_P (t)
+         && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
+    return 0;
+
+  /* We can be passed either an expression or a type.  This and the
+     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.
+     But first remove nops since we care only about the actual object.  */
+  while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
+        || TREE_CODE (t) == NON_LVALUE_EXPR)
+    t = TREE_OPERAND (t, 0);
+
+  /* Now give the language a chance to do something.  */
+  if (lang_get_alias_set != 0
+      && (set = (*lang_get_alias_set) (t)) != -1)
+    return set;
+
+  /* If this is a reference, go inside it and use the underlying object.  */
+  if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r')
+    t = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
+                            &unsignedp, &volatilep, &alignment);
+
+  if (TREE_CODE (t) == INDIRECT_REF)
+    {
+      /* Check for accesses through restrict-qualified pointers.  */
+      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;
+    }
+
+  /* Give the language another chance to do something special.  */
+  if (lang_get_alias_set != 0
+      && (set = (*lang_get_alias_set) (t)) != -1)
+    return set;
+
+  /* Now we are done with expressions, so get the type if this isn't
+     a type.  */
+  if (! TYPE_P (t))
+    t = TREE_TYPE (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))
+    return TYPE_ALIAS_SET (t);
+
+  /* See if the language has special handling for this type.  */
+  if (lang_get_alias_set != 0
+      && (set = (*lang_get_alias_set) (t)) != -1)
+    ;
+  /* 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
+     and references to functions, but that's different.)  */
+  else if (TREE_CODE (t) == FUNCTION_TYPE)
+    set = 0;
+  else
+    /* Otherwise make a new alias set for this type.  */
+    set = new_alias_set ();
+
+  TYPE_ALIAS_SET (t) = set;
+  return set;
+}
+
+/* Return a brand-new alias set.  */
+
+HOST_WIDE_INT
+new_alias_set ()
+{
+  static HOST_WIDE_INT last_alias_set;
+
+  if (flag_strict_aliasing)
+    return ++last_alias_set;
+  else
+    return 0;
+}
 
 /* Indicate that things in SUBSET can alias things in SUPERSET, but
    not vice versa.  For example, in C, a store to an `int' can alias a
@@ -278,8 +444,8 @@ insert_subset_children (node, data)
 
 void
 record_alias_subset (superset, subset)
-     int superset;
-     int subset;
+     HOST_WIDE_INT superset;
+     HOST_WIDE_INT subset;
 {
   alias_set_entry superset_entry;
   alias_set_entry subset_entry;
@@ -326,8 +492,8 @@ void
 record_component_aliases (type)
      tree type;
 {
-  int superset = get_alias_set (type);
-  int subset;
+  HOST_WIDE_INT superset = get_alias_set (type);
+  HOST_WIDE_INT subset;
   tree field;
 
   if (superset == 0)
@@ -336,7 +502,6 @@ record_component_aliases (type)
   switch (TREE_CODE (type))
     {
     case ARRAY_TYPE:
-    case COMPLEX_TYPE:
       subset = get_alias_set (TREE_TYPE (type));
       if (subset != 0)
        record_alias_subset (superset, subset);
@@ -358,6 +523,34 @@ record_component_aliases (type)
     }
 }
 
+/* Allocate an alias set for use in storing and reading from the varargs
+   spill area.  */
+
+HOST_WIDE_INT
+get_varargs_alias_set ()
+{
+  static HOST_WIDE_INT set = -1;
+
+  if (set == -1)
+    set = new_alias_set ();
+
+  return set;
+}
+
+/* Likewise, but used for the fixed portions of the frame, e.g., register
+   save areas.  */
+
+HOST_WIDE_INT
+get_frame_alias_set ()
+{
+  static HOST_WIDE_INT set = -1;
+
+  if (set == -1)
+    set = new_alias_set ();
+
+  return set;
+}
+
 /* Inside SRC, the source of a SET, find a base address.  */
 
 static rtx
@@ -975,6 +1168,7 @@ base_alias_check (x, y, x_mode, y_mode)
 /* Convert the address X into something we can use.  This is done by returning
    it unchanged unless it is a value; in the latter case we call cselib to get
    a more useful rtx.  */
+
 static rtx
 get_addr (x)
      rtx x;
index 1094e30..0e89481 100644 (file)
@@ -288,6 +288,7 @@ expand_builtin_return_addr (fndecl_code, count, tem)
 #endif
       tem = memory_address (Pmode, tem);
       tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
+      MEM_ALIAS_SET (tem) = get_frame_alias_set ();
     }
 
   /* For __builtin_frame_address, return what we've got.  */
@@ -302,10 +303,14 @@ expand_builtin_return_addr (fndecl_code, count, tem)
   tem = memory_address (Pmode,
                        plus_constant (tem, GET_MODE_SIZE (Pmode)));
   tem = gen_rtx_MEM (Pmode, tem);
+  MEM_ALIAS_SET (tem) = get_frame_alias_set ();
 #endif
   return tem;
 }
 
+/* Alias set used for setjmp buffer.  */
+static HOST_WIDE_INT setjmp_alias_set = -1;
+
 /* __builtin_setjmp is passed a pointer to an array of five words (not
    all will be used on all machines).  It operates similarly to the C
    library function of the same name, but is more efficient.  Much of
@@ -326,9 +331,13 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
   enum machine_mode value_mode;
   rtx stack_save;
+  rtx mem;
 
   value_mode = TYPE_MODE (integer_type_node);
 
+  if (setjmp_alias_set == -1)
+    setjmp_alias_set = new_alias_set ();
+
 #ifdef POINTERS_EXTEND_UNSIGNED
   buf_addr = convert_memory_address (Pmode, buf_addr);
 #endif
@@ -349,17 +358,20 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
 #endif
 
-  emit_move_insn (gen_rtx_MEM (Pmode, buf_addr),
-                 BUILTIN_SETJMP_FRAME_VALUE);
-  emit_move_insn (validize_mem
-                 (gen_rtx_MEM (Pmode,
-                               plus_constant (buf_addr,
-                                              GET_MODE_SIZE (Pmode)))),
+  mem = gen_rtx_MEM (Pmode, buf_addr);
+  MEM_ALIAS_SET (mem) = setjmp_alias_set;
+  emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
+
+  mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
+  MEM_ALIAS_SET (mem) = setjmp_alias_set;
+
+  emit_move_insn (validize_mem (mem),
                  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
 
   stack_save = gen_rtx_MEM (sa_mode,
                            plus_constant (buf_addr,
                                           2 * GET_MODE_SIZE (Pmode)));
+  MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
 
   /* If there is further processing to do, do it.  */
@@ -464,6 +476,9 @@ expand_builtin_longjmp (buf_addr, value)
   rtx fp, lab, stack;
   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
 
+  if (setjmp_alias_set == -1)
+    setjmp_alias_set = new_alias_set ();
+
 #ifdef POINTERS_EXTEND_UNSIGNED
   buf_addr = convert_memory_address (Pmode, buf_addr);
 #endif
@@ -489,6 +504,8 @@ expand_builtin_longjmp (buf_addr, value)
 
       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
                                                   2 * GET_MODE_SIZE (Pmode)));
+      MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
+       = setjmp_alias_set;
 
       /* Pick up FP, label, and SP from the block and jump.  This code is
         from expand_goto in stmt.c; see there for detailed comments.  */
@@ -513,53 +530,34 @@ expand_builtin_longjmp (buf_addr, value)
     }
 }
 
-/* Get a MEM rtx for expression EXP which can be used in a string instruction
-   (cmpstrsi, movstrsi, ..).  */
+/* Get a MEM rtx for expression EXP which is the address of an operand
+   to be used to be used in a string instruction (cmpstrsi, movstrsi, ..).  */
+
 static rtx
 get_memory_rtx (exp)
      tree exp;
 {
-  rtx mem;
-  int is_aggregate;
-
-  mem = gen_rtx_MEM (BLKmode,
-                    memory_address (BLKmode,
-                                    expand_expr (exp, NULL_RTX,
-                                                 ptr_mode, EXPAND_SUM)));
-
-  RTX_UNCHANGING_P (mem) = TREE_READONLY (exp);
-
-  /* Figure out the type of the object pointed to.  Set MEM_IN_STRUCT_P
-     if the value is the address of a structure or if the expression is
-     cast to a pointer to structure type.  */
-  is_aggregate = 0;
-
-  while (TREE_CODE (exp) == NOP_EXPR)
-    {
-      tree cast_type = TREE_TYPE (exp);
-      if (TREE_CODE (cast_type) == POINTER_TYPE
-         && AGGREGATE_TYPE_P (TREE_TYPE (cast_type)))
-       {
-         is_aggregate = 1;
-         break;
-       }
-      exp = TREE_OPERAND (exp, 0);
-    }
-
-  if (is_aggregate == 0)
-    {
-      tree type;
-
-      if (TREE_CODE (exp) == ADDR_EXPR)
-       /* If this is the address of an object, check whether the
-          object is an array.  */
-       type = TREE_TYPE (TREE_OPERAND (exp, 0));
-      else
-       type = TREE_TYPE (TREE_TYPE (exp));
-      is_aggregate = AGGREGATE_TYPE_P (type);
-    }
+  rtx mem = gen_rtx_MEM (BLKmode,
+                        memory_address (BLKmode,
+                                        expand_expr (exp, NULL_RTX,
+                                                     ptr_mode, EXPAND_SUM)));
+
+  /* Get an expression we can use to find the attributes to assign to MEM.
+     If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
+     we can.  First remove any nops.  */
+  while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
+        || TREE_CODE (exp) == NON_LVALUE_EXPR)
+        && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
+    exp = TREE_OPERAND (exp, 0);
+
+  if (TREE_CODE (exp) == ADDR_EXPR)
+    exp = TREE_OPERAND (exp, 0);
+  else if (POINTER_TYPE_P (TREE_TYPE (exp)))
+    exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
+  else
+    return mem;
 
-  MEM_SET_IN_STRUCT_P (mem, is_aggregate);
+  set_mem_attributes (mem, exp, 0);
   return mem;
 }
 \f
@@ -1306,6 +1304,7 @@ expand_builtin_mathfn (exp, target, subtarget)
    if we failed the caller should emit a normal call, otherwise
    try to get the result in TARGET, if convenient (and in mode MODE if that's
    convenient).  */
+
 static rtx
 expand_builtin_strlen (exp, target, mode)
      tree exp;
@@ -1377,8 +1376,9 @@ expand_builtin_strlen (exp, target, mode)
                           TYPE_MODE (integer_type_node));
 
       char_rtx = const0_rtx;
-      char_mode = insn_data[(int)icode].operand[2].mode;
-      if (! (*insn_data[(int)icode].operand[2].predicate) (char_rtx, char_mode))
+      char_mode = insn_data[(int) icode].operand[2].mode;
+      if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
+                                                           char_mode))
        char_rtx = copy_to_mode_reg (char_mode, char_rtx);
 
       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
@@ -1390,7 +1390,7 @@ expand_builtin_strlen (exp, target, mode)
       /* Now that we are assured of success, expand the source.  */
       start_sequence ();
       pat = memory_address (BLKmode, 
-               expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
+                           expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
       if (pat != src_reg)
        emit_move_insn (src_reg, pat);
       pat = gen_sequence ();
@@ -1814,6 +1814,7 @@ expand_builtin_saveregs ()
 /* __builtin_args_info (N) returns word N of the arg space info
    for the current function.  The number and meanings of words
    is controlled by the definition of CUMULATIVE_ARGS.  */
+
 static rtx
 expand_builtin_args_info (exp)
      tree exp;
@@ -2007,19 +2008,9 @@ expand_builtin_va_start (stdarg_p, arglist)
   return const0_rtx;
 }
 
-/* Allocate an alias set for use in storing and reading from the varargs
-   spill area.  */
-int
-get_varargs_alias_set ()
-{
-  static int set = -1;
-  if (set == -1)
-    set = new_alias_set ();
-  return set;
-}
-
 /* The "standard" implementation of va_arg: read the value from the
    current (padded) address and increment by the (padded) size.  */
+
 rtx
 std_expand_builtin_va_arg (valist, type)
      tree valist, type;
@@ -2063,6 +2054,7 @@ std_expand_builtin_va_arg (valist, type)
 
 /* Expand __builtin_va_arg, which is not really a builtin function, but
    a very special sort of operator.  */
+
 rtx
 expand_builtin_va_arg (valist, type)
      tree valist, type;
@@ -2146,6 +2138,7 @@ expand_builtin_va_arg (valist, type)
 }
 
 /* Expand ARGLIST, from a call to __builtin_va_end.  */
+
 static rtx
 expand_builtin_va_end (arglist)
      tree arglist;
@@ -2168,6 +2161,7 @@ expand_builtin_va_end (arglist)
 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a 
    builtin rather than just as an assignment in stdarg.h because of the
    nastiness of array-type va_list types.  */
+
 static rtx
 expand_builtin_va_copy (arglist)
      tree arglist;
index 6989d40..5cc34c9 100644 (file)
@@ -156,7 +156,6 @@ static void init_attributes         PARAMS ((void));
 static void record_function_format     PARAMS ((tree, tree, enum format_type,
                                                 int, int));
 static void record_international_format        PARAMS ((tree, tree, int));
-static tree c_find_base_decl            PARAMS ((tree));
 static int default_valid_lang_attribute PARAMS ((tree, tree, tree, tree));
 
 /* Keep a stack of if statements.  We record the number of compound
@@ -3245,10 +3244,10 @@ c_apply_type_quals_to_decl (type_quals, decl)
             alias set for the type pointed to by the type of the
             decl.  */
 
-         int pointed_to_alias_set
+         HOST_WIDE_INT pointed_to_alias_set
            = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
 
-         if (!pointed_to_alias_set)
+         if (pointed_to_alias_set == 0)
            /* It's not legal to make a subset of alias set zero.  */
            ;
          else
@@ -3261,91 +3260,16 @@ c_apply_type_quals_to_decl (type_quals, decl)
     }
 }
 
-/* T is an expression with pointer type.  Find the DECL on which this
-   expression is based.  (For example, in `a[i]' this would be `a'.)
-   If there is no such DECL, or a unique decl cannot be determined,
-   NULL_TREE is retured.  */
-
-static tree
-c_find_base_decl (t)
-     tree t;
-{
-  int i;
-  tree decl;
-
-  if (t == NULL_TREE || t == error_mark_node)
-    return NULL_TREE;
-
-  if (!POINTER_TYPE_P (TREE_TYPE (t)))
-    return NULL_TREE;
-
-  decl = NULL_TREE;
-
-  if (TREE_CODE (t) == FIELD_DECL
-      || TREE_CODE (t) == PARM_DECL
-      || TREE_CODE (t) == VAR_DECL)
-    /* Aha, we found a pointer-typed declaration.  */
-    return t;
-
-  /* It would be nice to deal with COMPONENT_REFs here.  If we could
-     tell that `a' and `b' were the same, then `a->f' and `b->f' are
-     also the same.  */
-
-  /* Handle general expressions.  */
-  switch (TREE_CODE_CLASS (TREE_CODE (t)))
-    {
-    case '1':
-    case '2':
-    case '3':
-      for (i = TREE_CODE_LENGTH (TREE_CODE (t)); --i >= 0;)
-       {
-         tree d = c_find_base_decl (TREE_OPERAND (t, i));
-         if (d)
-           {
-             if (!decl)
-               decl = d;
-             else if (d && d != decl)
-               /* Two different declarations.  That's confusing; let's
-                  just assume we don't know what's going on.  */
-               decl = NULL_TREE;
-           }
-       }
-      break;
-
-    default:
-      break;
-    }
-
-  return decl;
-}
 
 /* Return the typed-based alias set for T, which may be an expression
-   or a type.  */
+   or a type.  Return -1 if we don't do anything special.  */
 
-int
+HOST_WIDE_INT
 c_get_alias_set (t)
      tree t;
 {
-  tree type;
   tree u;
 
-  if (t == error_mark_node)
-    return 0;
-
-  /* For a bit field reference that's not to a specific field,
-     all we can say is the aliasing information for the underlying object. */
-  if (TREE_CODE (t) == BIT_FIELD_REF)
-    t = TREE_OPERAND (t, 0);
-
-  /* If this is a type, use it, otherwise get the type of the expression.
-     If the type is an error type, say this may alias anything.  */
-  type = TYPE_P (t) ? t : TREE_TYPE (t);
-  if (type == error_mark_node)
-    return 0;
-
-  /* Deal with special cases first; for certain kinds of references
-     we're interested in more than just the type.  */
-
   /* Permit type-punning when accessing a union, provided the access
      is directly through the union.  For example, this code does not
      permit taking the address of a union member and then storing
@@ -3359,81 +3283,37 @@ c_get_alias_set (t)
        && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
       return 0;
 
-  if (TREE_CODE (t) == INDIRECT_REF)
-    {
-      /* Check for accesses through restrict-qualified pointers.  */
-      tree op = TREE_OPERAND (t, 0);
-      tree decl = c_find_base_decl (op);
-
-      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 this is a char *, the ANSI C standard says it can alias
-         anything.  */
-      if (TREE_CODE (TREE_TYPE (op)) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (op))
-             == TYPE_PRECISION (char_type_node)))
-       return 0;
-    }
+  /* If this is a char *, the ANSI C standard says it can alias
+     anything.  */
+  else if (TREE_CODE (t) == INDIRECT_REF
+          && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == INTEGER_TYPE
+          && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
+              == TYPE_PRECISION (char_type_node)))
+    return 0;
 
-  /* From here on, only the type matters.  */
-
-  if (TREE_CODE (t) == COMPONENT_REF
-      && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)))
-    /* Since build_modify_expr calls get_unwidened for stores to
-       component references, the type of a bit field can be changed
-       from (say) `unsigned int : 16' to `unsigned short' or from
-       `enum E : 16' to `short'.  We want the real type of the
-       bit-field in this case, not some the integral equivalent.  */
-    type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1));
-
-  if (TYPE_ALIAS_SET_KNOWN_P (type))
-    /* If we've already calculated the value, just return it.  */
-    return TYPE_ALIAS_SET (type);
-  else if (TYPE_MAIN_VARIANT (type) != type)
-    /* The C standard specifically allows aliasing between
-       cv-qualified variants of types.  */
-    TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
-  else if (TREE_CODE (type) == INTEGER_TYPE)
-    {
-      tree signed_variant;
+  /* That's all the expressions we handle specially.  */
+  if (! TYPE_P (t))
+    return -1;
 
+  if (TREE_CODE (t) == INTEGER_TYPE)
+    {
       /* The C standard specifically allows aliasing between signed and
         unsigned variants of the same type.  We treat the signed
         variant as canonical.  */
-      signed_variant = signed_type (type);
+      tree signed_variant = signed_type (t);
 
-      if (signed_variant != type)
-       TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
-      else if (signed_variant == signed_char_type_node)
+      if (signed_variant == signed_char_type_node)
        /* The C standard guarantess that any object may be accessed
           via an lvalue that has character type.  We don't have to
           check for unsigned_char_type_node or char_type_node because
           we are specifically looking at the signed variant.  */
-       TYPE_ALIAS_SET (type) = 0;
+       return 0;
+      else if (signed_variant  != t)
+       return get_alias_set (signed_variant);
     }
-  else if (TREE_CODE (type) == ARRAY_TYPE)
-    /* Anything that can alias one of the array elements can alias
-       the entire array as well.  */
-    TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type));
-  else if (TREE_CODE (type) == FUNCTION_TYPE)
-    /* 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 and references to functions, but that's
-       different.)  */
-    TYPE_ALIAS_SET (type) = 0;
-  else if (TREE_CODE (type) == RECORD_TYPE
-          || TREE_CODE (type) == UNION_TYPE)
-    /* If TYPE is a struct or union type then we're reading or
-       writing an entire struct.  Thus, we don't know anything about
-       aliasing.  (In theory, such an access can only alias objects
-       whose type is the same as one of the fields, recursively, but
-       we don't yet make any use of that information.)  */
-    TYPE_ALIAS_SET (type) = 0;
-  else if (POINTER_TYPE_P (type))
+  else if (POINTER_TYPE_P (t))
     {
-      tree t;
+      tree t1;
 
       /* Unfortunately, there is no canonical form of a pointer type.
         In particular, if we have `typedef int I', then `int *', and
@@ -3458,19 +3338,14 @@ c_get_alias_set (t)
         can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
         the pointed-to types.  This issue has been reported to the
         C++ committee.  */
-      t = TYPE_MAIN_VARIANT (TREE_TYPE (type));
-      t = ((TREE_CODE (type) == POINTER_TYPE)
-          ? build_pointer_type (t) : build_reference_type (t));
-      if (t != type)
-       TYPE_ALIAS_SET (type) = c_get_alias_set (t);
+      t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+      t1 = ((TREE_CODE (t) == POINTER_TYPE)
+          ? build_pointer_type (t1) : build_reference_type (t1));
+      if (t1 != t)
+       return get_alias_set (t1);
     }
 
-  if (! TYPE_ALIAS_SET_KNOWN_P (type))
-    /* TYPE is something we haven't seen before.  Put it in a new
-       alias set.  */
-    TYPE_ALIAS_SET (type) = new_alias_set ();
-
-  return TYPE_ALIAS_SET (type);
+  return -1;
 }
 
 /* Build tree nodes and builtin functions common to both C and C++ language
@@ -3480,6 +3355,7 @@ c_get_alias_set (t)
    NO_BUILTINS and NO_NONANSI_BUILTINS contain the respective values of
    the language frontend flags flag_no_builtin and
    flag_no_nonansi_builtin.  */
+
 void
 c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
     int cplus_mode, no_builtins, no_nonansi_builtins;
index 0d25b2a..30f58f8 100644 (file)
@@ -97,7 +97,7 @@ extern void decl_attributes                   PARAMS ((tree, tree, tree));
 extern void init_function_format_info          PARAMS ((void));
 extern void check_function_format              PARAMS ((tree, tree, tree));
 extern void c_apply_type_quals_to_decl         PARAMS ((int, tree));
-extern int c_get_alias_set                     PARAMS ((tree));
+extern HOST_WIDE_INT c_get_alias_set           PARAMS ((tree));
 /* Print an error message for invalid operands to arith operation CODE.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error                    PARAMS ((enum tree_code));
index 0f01c57..1d86242 100644 (file)
@@ -313,6 +313,7 @@ common_type (t1, t2)
          return build_type_attribute_variant (t2, attributes);
        /* Merge the element types, and have a size if either arg has one.  */
        t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+       record_component_aliases (t1);
        return build_type_attribute_variant (t1, attributes);
       }
 
index 305894e..f939de7 100644 (file)
@@ -256,6 +256,7 @@ void
 setup_save_areas ()
 {
   int i, j, k;
+  unsigned int r;
   HARD_REG_SET hard_regs_used;
 
   /* Allocate space in the save area for the largest multi-register
@@ -267,16 +268,13 @@ setup_save_areas ()
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
     if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
       {
-       int regno = reg_renumber[i];
-       int endregno 
+       unsigned int regno = reg_renumber[i];
+       unsigned int endregno 
          = regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
-       int nregs = endregno - regno;
 
-       for (j = 0; j < nregs; j++)
-         {
-           if (call_used_regs[regno+j]) 
-             SET_HARD_REG_BIT (hard_regs_used, regno+j);
-         }
+       for (r = regno; r < endregno; r++)
+         if (call_used_regs[r])
+           SET_HARD_REG_BIT (hard_regs_used, r);
       }
 
   /* Now run through all the call-used hard-registers and allocate
@@ -322,16 +320,24 @@ setup_save_areas ()
          {
            /* This should not depend on WORDS_BIG_ENDIAN.
               The order of words in regs is the same as in memory.  */
-           rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1], 
+           rtx temp = gen_rtx_MEM (regno_save_mode[i + k][1], 
                                    XEXP (regno_save_mem[i][j], 0));
 
-           regno_save_mem[i+k][1] 
+           regno_save_mem[i + k][1] 
              = adj_offsettable_operand (temp, k * UNITS_PER_WORD);
          }
       }
+
+  /* Now loop again and set the alias set of any save areas we made to
+     the alias set used to represent frame objects.  */
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    for (j = MOVE_MAX_WORDS; j > 0; j--)
+      if (regno_save_mem[i][j] != 0)
+       MEM_ALIAS_SET (regno_save_mem[i][j]) = get_frame_alias_set ();
 }
 \f
 /* Find the places where hard regs are live across calls and save them.  */
+
 void
 save_call_clobbered_regs ()
 {
index bf33ebd..d59c15b 100644 (file)
@@ -850,6 +850,7 @@ precompute_register_parameters (num_actuals, args, reg_parm_seen)
   /* The argument list is the property of the called routine and it
      may clobber it.  If the fixed area has been used for previous
      parameters, we must save and restore it.  */
+
 static rtx
 save_fixed_argument_area (reg_parm_stack_space, argblock,
                          low_to_save, high_to_save)
@@ -891,10 +892,11 @@ save_fixed_argument_area (reg_parm_stack_space, argblock,
        save_mode = BLKmode;
 
 #ifdef ARGS_GROW_DOWNWARD
-      stack_area = gen_rtx_MEM (save_mode,
-                               memory_address (save_mode,
-                                               plus_constant (argblock,
-                                                              - *high_to_save)));
+      stack_area
+       = gen_rtx_MEM (save_mode,
+                      memory_address (save_mode,
+                                      plus_constant (argblock,
+                                                     - *high_to_save)));
 #else
       stack_area = gen_rtx_MEM (save_mode,
                                memory_address (save_mode,
@@ -1191,17 +1193,12 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
                    }
 
                  copy = gen_rtx_MEM (BLKmode,
-                                     allocate_dynamic_stack_space (size_rtx,
-                                                                   NULL_RTX,
-                                                                   TYPE_ALIGN (type)));
+                                     allocate_dynamic_stack_space
+                                     (size_rtx, NULL_RTX, TYPE_ALIGN (type)));
+                 set_mem_attributes (copy, type, 1);
                }
              else
-               {
-                 int size = int_size_in_bytes (type);
-                 copy = assign_stack_temp (TYPE_MODE (type), size, 0);
-               }
-
-             MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
+               copy = assign_temp (type, 0, 1, 0);
 
              store_expr (args[i].tree_value, copy, 0);
              *ecf_flags &= ~(ECF_CONST | ECF_PURE);
@@ -1585,9 +1582,8 @@ compute_argument_addresses (args, argblock, num_actuals)
 
          addr = plus_constant (addr, arg_offset);
          args[i].stack = gen_rtx_MEM (args[i].mode, addr);
-         MEM_SET_IN_STRUCT_P 
-           (args[i].stack,
-            AGGREGATE_TYPE_P (TREE_TYPE (args[i].tree_value)));
+         set_mem_attributes (args[i].stack,
+                             TREE_TYPE (args[i].tree_value), 1);
 
          if (GET_CODE (slot_offset) == CONST_INT)
            addr = plus_constant (arg_reg, INTVAL (slot_offset));
@@ -1596,6 +1592,8 @@ compute_argument_addresses (args, argblock, num_actuals)
 
          addr = plus_constant (addr, arg_offset);
          args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
+         set_mem_attributes (args[i].stack_slot,
+                             TREE_TYPE (args[i].tree_value), 1);
        }
     }
 }
@@ -3058,11 +3056,11 @@ expand_call (exp, target, ignore)
        {
          if (target == 0 || GET_CODE (target) != MEM)
            {
-             target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
-                                   memory_address (TYPE_MODE (TREE_TYPE (exp)),
-                                                   structure_value_addr));
-             MEM_SET_IN_STRUCT_P (target,
-                                  AGGREGATE_TYPE_P (TREE_TYPE (exp)));
+             target
+               = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
+                              memory_address (TYPE_MODE (TREE_TYPE (exp)),
+                                              structure_value_addr));
+             set_mem_attributes (target, exp, 1);
            }
        }
       else if (pcc_struct_value)
@@ -3072,7 +3070,7 @@ expand_call (exp, target, ignore)
             never use this value more than once in one expression.  */
          target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
                                copy_to_reg (valreg));
-         MEM_SET_IN_STRUCT_P (target, AGGREGATE_TYPE_P (TREE_TYPE (exp)));
+         set_mem_attributes (target, exp, 1);
        }
       /* Handle calls that return values in multiple non-contiguous locations.
         The Irix 6 ABI has examples of this.  */
index 6120852..ffe112a 100644 (file)
@@ -1,3 +1,12 @@
+Wed May 31 14:09:00 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * Makefile.in (decl.o): Include ../expr.h.
+       * decl.c (expr.h): Include.
+       (init_decl_processing): Call record_component_aliases for arrays.
+       (grokdeclarator): Likewise.
+       Set TREE_ADDRESSABLE for fields that aren't bitfields.
+       * tree.c (build_cplus_array_type_1): Call record_component_aliases.
+
 2000-05-31  Mark Mitchell  <mark@codesourcery.com>
 
        * decl.c (build_cp_library_fn): Set DECL_CONTEXT.
index 5284e7d..e162294 100644 (file)
@@ -256,7 +256,7 @@ lex.o : lex.c $(CXX_TREE_H) \
   $(srcdir)/../output.h $(srcdir)/../mbchar.h $(GGC_H) \
   $(srcdir)/../input.h operators.def
 decl.o : decl.c $(CXX_TREE_H) $(srcdir)/../flags.h \
-  lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h  \
+  lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h $(srcdir)/../expr.h \
   $(srcdir)/../except.h $(srcdir)/../toplev.h \
   $(srcdir)/../hash.h $(GGC_H) $(RTL_H) operators.def
 decl2.o : decl2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
index 69f6e74..6640b90 100644 (file)
@@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "tree.h"
 #include "rtl.h"
+#include "expr.h"
 #include "flags.h"
 #include "cp-tree.h"
 #include "decl.h"
@@ -6455,10 +6456,14 @@ init_decl_processing ()
      array type.  */
   char_array_type_node
     = build_array_type (char_type_node, array_domain_type);
+
   /* Likewise for arrays of ints.  */
   int_array_type_node
     = build_array_type (integer_type_node, array_domain_type);
 
+  record_component_aliases (char_array_type_node);
+  record_component_aliases (int_array_type_node);
+
   if (flag_new_abi)
     delta_type_node = ptrdiff_type_node;
   else if (flag_huge_objects)
@@ -6522,6 +6527,7 @@ init_decl_processing ()
   /* This is for wide string constants.  */
   wchar_array_type_node
     = build_array_type (wchar_type_node, array_domain_type);
+  record_component_aliases (wchar_array_type_node);
 
   if (flag_vtable_thunks)
     {
@@ -11588,6 +11594,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            else
              {
                decl = build_decl (FIELD_DECL, declarator, type);
+               TREE_ADDRESSABLE (decl) = ! bitfield;
                if (RIDBIT_SETP (RID_MUTABLE, specbits))
                  {
                    DECL_MUTABLE_P (decl) = 1;
index 382e254..95fafad 100644 (file)
@@ -500,7 +500,10 @@ build_cplus_array_type_1 (elt_type, index_type)
       TYPE_DOMAIN (t) = index_type;
     }
   else
-    t = build_array_type (elt_type, index_type);
+    {
+      t = build_array_type (elt_type, index_type);
+      record_component_aliases (t);
+    }
 
   /* Push these needs up so that initialization takes place
      more easily.  */
index f689b88..6ca93bc 100644 (file)
@@ -628,6 +628,61 @@ validize_mem (ref)
   return change_address (ref, GET_MODE (ref), XEXP (ref, 0));
 }
 \f
+/* Given REF, a MEM, and T, either the type of X or the expression
+   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
+   if we are making a new object of this type.  */
+
+void
+set_mem_attributes (ref, t, objectp)
+     rtx ref;
+     tree t;
+     int objectp;
+{
+  tree 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.  */
+  MEM_ALIAS_SET (ref) = get_alias_set (t);
+  RTX_UNCHANGING_P (ref) = TYPE_READONLY (type);
+  MEM_VOLATILE_P (ref) = TYPE_VOLATILE (type);
+  MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
+
+  /* If we are making an object of this type, we know that it is a scalar if
+     the type is not an aggregate. */
+  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
+     to deduce some more information about the expression.  */
+  if (TYPE_P (t))
+    return;
+
+  if (TREE_READONLY (t) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
+    RTX_UNCHANGING_P (ref) = 1;
+  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);
+
+  /* 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.  */
+  if (DECL_P (t))
+    MEM_SCALAR_P (ref) = 1;
+  else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
+          || TREE_CODE (t) == BIT_FIELD_REF)
+    MEM_IN_STRUCT_P (ref) = 1;
+}
+\f
 /* Return a modified copy of X with its memory address copied
    into a temporary register to protect it from side effects.
    If X is not a MEM, it is returned unchanged (and not copied).
@@ -638,25 +693,17 @@ stabilize (x)
      rtx x;
 {
   register rtx addr;
+
   if (GET_CODE (x) != MEM)
     return x;
+
   addr = XEXP (x, 0);
   if (rtx_unstable_p (addr))
     {
-      rtx temp = copy_all_regs (addr);
-      rtx mem;
-
-      if (GET_CODE (temp) != REG)
-       temp = copy_to_reg (temp);
-      mem = gen_rtx_MEM (GET_MODE (x), temp);
-
-      /* Mark returned memref with in_struct if it's in an array or
-        structure.  Copy everything else from original memref.  */
+      rtx temp = force_reg (Pmode, copy_all_regs (addr));
+      rtx mem = gen_rtx_MEM (GET_MODE (x), temp);
 
       MEM_COPY_ATTRIBUTES (mem, x);
-      if (GET_CODE (addr) == PLUS)
-       MEM_SET_IN_STRUCT_P (mem, 1);
-
       return mem;
     }
   return x;
index 5cef748..cb39728 100644 (file)
@@ -115,16 +115,12 @@ struct move_by_pieces
   rtx to_addr;
   int autinc_to;
   int explicit_inc_to;
-  int to_struct;
-  int to_readonly;
   rtx from;
   rtx from_addr;
   int autinc_from;
   int explicit_inc_from;
-  int from_struct;
-  int from_readonly;
-  int len;
-  int offset;
+  unsigned HOST_WIDE_INT len;
+  HOST_WIDE_INT offset;
   int reverse;
 };
 
@@ -137,9 +133,8 @@ struct clear_by_pieces
   rtx to_addr;
   int autinc_to;
   int explicit_inc_to;
-  int to_struct;
-  int len;
-  int offset;
+  unsigned HOST_WIDE_INT len;
+  HOST_WIDE_INT offset;
   int reverse;
 };
 
@@ -148,10 +143,13 @@ extern struct obstack permanent_obstack;
 static rtx get_push_address    PARAMS ((int));
 
 static rtx enqueue_insn                PARAMS ((rtx, rtx));
-static int move_by_pieces_ninsns PARAMS ((unsigned int, unsigned int));
+static unsigned HOST_WIDE_INT move_by_pieces_ninsns
+                               PARAMS ((unsigned HOST_WIDE_INT,
+                                        unsigned int));
 static void move_by_pieces_1   PARAMS ((rtx (*) (rtx, ...), enum machine_mode,
                                         struct move_by_pieces *));
-static void clear_by_pieces    PARAMS ((rtx, int, unsigned int));
+static void clear_by_pieces    PARAMS ((rtx, unsigned HOST_WIDE_INT,
+                                        unsigned int));
 static void clear_by_pieces_1  PARAMS ((rtx (*) (rtx, ...),
                                         enum machine_mode,
                                         struct clear_by_pieces *));
@@ -1381,7 +1379,7 @@ convert_modes (mode, oldmode, x, unsignedp)
 void
 move_by_pieces (to, from, len, align)
      rtx to, from;
-     int len;
+     unsigned HOST_WIDE_INT len;
      unsigned int align;
 {
   struct move_by_pieces data;
@@ -1410,11 +1408,6 @@ move_by_pieces (to, from, len, align)
   if (data.reverse) data.offset = len;
   data.len = len;
 
-  data.to_struct = MEM_IN_STRUCT_P (to);
-  data.from_struct = MEM_IN_STRUCT_P (from);
-  data.to_readonly = RTX_UNCHANGING_P (to);
-  data.from_readonly = RTX_UNCHANGING_P (from);
-
   /* If copying requires more than two move insns,
      copy addresses to registers (to make displacements shorter)
      and use post-increment if available.  */
@@ -1489,13 +1482,13 @@ move_by_pieces (to, from, len, align)
 /* Return number of insns required to move L bytes by pieces.
    ALIGN (in bytes) is maximum alignment we can assume.  */
 
-static int
+static unsigned HOST_WIDE_INT
 move_by_pieces_ninsns (l, align)
-     unsigned int l;
+     unsigned HOST_WIDE_INT l;
      unsigned int align;
 {
-  register int n_insns = 0;
-  unsigned int max_size = MOVE_MAX + 1;
+  unsigned HOST_WIDE_INT n_insns = 0;
+  unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1;
 
   if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
       || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
@@ -1534,29 +1527,31 @@ move_by_pieces_1 (genfun, mode, data)
      enum machine_mode mode;
      struct move_by_pieces *data;
 {
-  register int size = GET_MODE_SIZE (mode);
-  register rtx to1, from1;
+  unsigned int size = GET_MODE_SIZE (mode);
+  rtx to1, from1;
 
   while (data->len >= size)
     {
-      if (data->reverse) data->offset -= size;
-
-      to1 = (data->autinc_to
-            ? gen_rtx_MEM (mode, data->to_addr)
-            : copy_rtx (change_address (data->to, mode,
-                                        plus_constant (data->to_addr,
-                                                       data->offset))));
-      MEM_IN_STRUCT_P (to1) = data->to_struct;
-      RTX_UNCHANGING_P (to1) = data->to_readonly;
-
-      from1
-       = (data->autinc_from
-          ? gen_rtx_MEM (mode, data->from_addr)
-          : copy_rtx (change_address (data->from, mode,
-                                      plus_constant (data->from_addr,
-                                                     data->offset))));
-      MEM_IN_STRUCT_P (from1) = data->from_struct;
-      RTX_UNCHANGING_P (from1) = data->from_readonly;
+      if (data->reverse)
+       data->offset -= size;
+
+      if (data->autinc_to)
+       {
+         to1 = gen_rtx_MEM (mode, data->to_addr);
+         MEM_COPY_ATTRIBUTES (to1, data->to);
+       }
+      else
+       to1 = change_address (data->to, mode,
+                             plus_constant (data->to_addr, data->offset));
+
+      if (data->autinc_from)
+       {
+         from1 = gen_rtx_MEM (mode, data->from_addr);
+         MEM_COPY_ATTRIBUTES (from1, data->from);
+       }
+      else
+       from1 = change_address (data->from, mode,
+                               plus_constant (data->from_addr, data->offset));
 
       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
        emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
@@ -1564,12 +1559,14 @@ move_by_pieces_1 (genfun, mode, data)
        emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
 
       emit_insn ((*genfun) (to1, from1));
+
       if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
        emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
       if (HAVE_POST_INCREMENT && data->explicit_inc_from > 0)
        emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
 
-      if (! data->reverse) data->offset += size;
+      if (! data->reverse)
+       data->offset += size;
 
       data->len -= size;
     }
@@ -2243,12 +2240,12 @@ use_group_regs (call_fusage, regs)
 static void
 clear_by_pieces (to, len, align)
      rtx to;
-     int len;
+     unsigned HOST_WIDE_INT len;
      unsigned int align;
 {
   struct clear_by_pieces data;
   rtx to_addr = XEXP (to, 0);
-  unsigned int max_size = MOVE_MAX_PIECES + 1;
+  unsigned HOST_WIDE_INT max_size = MOVE_MAX_PIECES + 1;
   enum machine_mode mode = VOIDmode, tmode;
   enum insn_code icode;
 
@@ -2265,8 +2262,6 @@ clear_by_pieces (to, len, align)
   if (data.reverse) data.offset = len;
   data.len = len;
 
-  data.to_struct = MEM_IN_STRUCT_P (to);
-
   /* If copying requires more than two move insns,
      copy addresses to registers (to make displacements shorter)
      and use post-increment if available.  */
@@ -2285,13 +2280,16 @@ clear_by_pieces (to, len, align)
          data.autinc_to = 1;
          data.explicit_inc_to = -1;
        }
-      if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
+
+      if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse
+         && ! data.autinc_to)
        {
          data.to_addr = copy_addr_to_reg (to_addr);
          data.autinc_to = 1;
          data.explicit_inc_to = 1;
        }
-      if (!data.autinc_to && CONSTANT_P (to_addr))
+
+      if ( !data.autinc_to && CONSTANT_P (to_addr))
        data.to_addr = copy_addr_to_reg (to_addr);
     }
 
@@ -2334,28 +2332,33 @@ clear_by_pieces_1 (genfun, mode, data)
      enum machine_mode mode;
      struct clear_by_pieces *data;
 {
-  register int size = GET_MODE_SIZE (mode);
-  register rtx to1;
+  unsigned int size = GET_MODE_SIZE (mode);
+  rtx to1;
 
   while (data->len >= size)
     {
-      if (data->reverse) data->offset -= size;
+      if (data->reverse)
+       data->offset -= size;
 
-      to1 = (data->autinc_to
-            ? gen_rtx_MEM (mode, data->to_addr)
-            : copy_rtx (change_address (data->to, mode,
-                                        plus_constant (data->to_addr,
-                                                       data->offset))));
-      MEM_IN_STRUCT_P (to1) = data->to_struct;
+      if (data->autinc_to)
+       {
+         to1 = gen_rtx_MEM (mode, data->to_addr);
+         MEM_COPY_ATTRIBUTES (to1, data->to);
+       }
+      else 
+       to1 = change_address (data->to, mode,
+                             plus_constant (data->to_addr, data->offset));
 
       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
        emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
 
       emit_insn ((*genfun) (to1, const0_rtx));
+
       if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
        emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
 
-      if (! data->reverse) data->offset += size;
+      if (! data->reverse)
+       data->offset += size;
 
       data->len -= size;
     }
@@ -2627,17 +2630,17 @@ emit_move_insn_1 (x, y)
             regardless of machine's endianness.  */
 #ifdef STACK_GROWS_DOWNWARD
          emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-                    (gen_rtx_MEM (submode, (XEXP (x, 0))),
+                    (gen_rtx_MEM (submode, XEXP (x, 0)),
                      gen_imagpart (submode, y)));
          emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-                    (gen_rtx_MEM (submode, (XEXP (x, 0))),
+                    (gen_rtx_MEM (submode, XEXP (x, 0)),
                      gen_realpart (submode, y)));
 #else
          emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-                    (gen_rtx_MEM (submode, (XEXP (x, 0))),
+                    (gen_rtx_MEM (submode, XEXP (x, 0)),
                      gen_realpart (submode, y)));
          emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-                    (gen_rtx_MEM (submode, (XEXP (x, 0))),
+                    (gen_rtx_MEM (submode, XEXP (x, 0)),
                      gen_imagpart (submode, y)));
 #endif
        }
@@ -2866,7 +2869,7 @@ push_block (size, extra, below)
                              - INTVAL (size) - (below ? 0 : extra));
       else if (extra != 0 && !below)
        temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
-                       negate_rtx (Pmode, plus_constant (size, extra)));
+                            negate_rtx (Pmode, plus_constant (size, extra)));
       else
        temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
                             negate_rtx (Pmode, size));
@@ -3105,6 +3108,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
          if (GET_CODE (size) == CONST_INT
              && MOVE_BY_PIECES_P ((unsigned) INTVAL (size), align))
            {
+             rtx target = gen_rtx_MEM (BLKmode, temp);
+
+             if (type != 0)
+               set_mem_attributes (target, type, 1);
+
              move_by_pieces (gen_rtx_MEM (BLKmode, temp), xinner,
                              INTVAL (size), align);
              goto ret;
@@ -3115,6 +3123,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
              enum machine_mode mode;
              rtx target = gen_rtx_MEM (BLKmode, temp);
 
+             if (type != 0)
+               set_mem_attributes (target, type, 1);
+
              for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
                   mode != VOIDmode;
                   mode = GET_MODE_WIDER_MODE (mode))
@@ -3251,6 +3262,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
     {
       rtx addr;
       rtx target = NULL_RTX;
+      rtx dest;
 
       /* Push padding now if padding above and stack grows down,
         or if padding below and stack grows up.
@@ -3279,7 +3291,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
          target = addr;
        }
 
-      emit_move_insn (gen_rtx_MEM (mode, addr), x);
+      dest = gen_rtx_MEM (mode, addr);
+      if (type != 0)
+       set_mem_attributes (dest, type, 1);
+
+      emit_move_insn (dest, x);
 
       if (current_function_check_memory_usage && ! in_check_memory_usage)
        {
@@ -3994,6 +4010,10 @@ store_expr (exp, target, want_value)
 
              if (size != const0_rtx)
                {
+                 rtx dest = gen_rtx_MEM (BLKmode, addr);
+
+                 MEM_COPY_ATTRIBUTES (dest, target);
+
                  /* Be sure we can write on ADDR.  */
                  in_check_memory_usage = 1;
                  if (current_function_check_memory_usage)
@@ -4003,7 +4023,7 @@ store_expr (exp, target, want_value)
                                       GEN_INT (MEMORY_USE_WO), 
                                       TYPE_MODE (integer_type_node));
                  in_check_memory_usage = 0;
-                 clear_storage (gen_rtx_MEM (BLKmode, addr), size, align);
+                 clear_storage (target, size, align);
                }
 
              if (label)
@@ -5980,10 +6000,11 @@ expand_expr (exp, target, tmode, modifier)
            abort ();
          addr = XEXP (DECL_RTL (exp), 0);
          if (GET_CODE (addr) == MEM)
-           addr = gen_rtx_MEM (Pmode,
-                               fix_lexical_addr (XEXP (addr, 0), exp));
+           addr = change_address (addr, Pmode, 
+                                  fix_lexical_addr (XEXP (addr, 0), exp));
          else
            addr = fix_lexical_addr (addr, exp);
+
          temp = change_address (DECL_RTL (exp), mode, addr);
        }
 
@@ -6418,7 +6439,6 @@ expand_expr (exp, target, tmode, modifier)
     case INDIRECT_REF:
       {
        tree exp1 = TREE_OPERAND (exp, 0);
-       tree exp2;
        tree index;
        tree string = string_constant (exp1, &index);
  
@@ -6456,19 +6476,7 @@ expand_expr (exp, target, tmode, modifier)
          }
 
        temp = gen_rtx_MEM (mode, op0);
-       /* If address was computed by addition,
-          mark this as an element of an aggregate.  */
-       if (TREE_CODE (exp1) == PLUS_EXPR
-           || (TREE_CODE (exp1) == SAVE_EXPR
-               && TREE_CODE (TREE_OPERAND (exp1, 0)) == PLUS_EXPR)
-           || AGGREGATE_TYPE_P (TREE_TYPE (exp))
-           || (TREE_CODE (exp1) == ADDR_EXPR
-               && (exp2 = TREE_OPERAND (exp1, 0))
-               && AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
-         MEM_SET_IN_STRUCT_P (temp, 1);
-
-       MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) | flag_volatile;
-       MEM_ALIAS_SET (temp) = get_alias_set (exp);
+       set_mem_attributes (temp, exp, 0);
 
        /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY
           here, because, in C and C++, the fact that a location is accessed
@@ -6893,13 +6901,10 @@ expand_expr (exp, target, tmode, modifier)
                                plus_constant (XEXP (op0, 0),
                                               (bitpos / BITS_PER_UNIT)));
 
-       if (GET_CODE (op0) == MEM)
-         MEM_ALIAS_SET (op0) = get_alias_set (exp);
+       set_mem_attributes (op0, exp, 0);
        if (GET_CODE (XEXP (op0, 0)) == REG)
          mark_reg_pointer (XEXP (op0, 0), alignment);
 
-       MEM_SET_IN_STRUCT_P (op0, 1);
        MEM_VOLATILE_P (op0) |= volatilep;
        if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
            || modifier == EXPAND_CONST_ADDRESS
index 8d7a9d8..ca82ab1 100644 (file)
@@ -94,8 +94,8 @@ struct args_size
 
 #define ADD_PARM_SIZE(TO, INC) \
 { tree inc = (INC);                            \
-  if (TREE_CODE (inc) == INTEGER_CST)          \
-    (TO).constant += TREE_INT_CST_LOW (inc);   \
+  if (host_integerp (inc, 0))                  \
+    (TO).constant += tree_low_cst (inc, 0);    \
   else if ((TO).var == 0)                      \
     (TO).var = inc;                            \
   else                                         \
@@ -103,8 +103,8 @@ struct args_size
 
 #define SUB_PARM_SIZE(TO, DEC) \
 { tree dec = (DEC);                            \
-  if (TREE_CODE (dec) == INTEGER_CST)          \
-    (TO).constant -= TREE_INT_CST_LOW (dec);   \
+  if (host_integerp (dec, 0))                  \
+    (TO).constant -= tree_low_cst (dec, 0);    \
   else if ((TO).var == 0)                      \
     (TO).var = size_binop (MINUS_EXPR, ssize_int (0), dec); \
   else                                         \
@@ -915,7 +915,16 @@ extern rtx expand_builtin_va_arg PARAMS ((tree, tree));
 extern rtx expand_builtin_setjmp PARAMS ((rtx, rtx, rtx, rtx));
 extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
 extern rtx expand_builtin_saveregs PARAMS ((void));
-extern int get_varargs_alias_set PARAMS ((void));
+extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
+extern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
+extern void record_base_value          PARAMS ((unsigned int, rtx, int));
+extern void record_alias_subset         PARAMS ((HOST_WIDE_INT,
+                                                HOST_WIDE_INT));
+#ifdef TREE_CODE
+extern HOST_WIDE_INT get_alias_set             PARAMS ((tree));
+extern HOST_WIDE_INT (*lang_get_alias_set)     PARAMS ((tree));
+#endif
+extern HOST_WIDE_INT new_alias_set             PARAMS ((void));
 \f
 /* Functions from expr.c:  */
 
@@ -1013,10 +1022,9 @@ extern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx,
                                    int, rtx));
 
 /* Emit library call.  */
-extern void emit_library_call PARAMS ((rtx orgfun, int no_queue,
-  enum machine_mode outmode, int nargs, ...));
-extern rtx emit_library_call_value PARAMS ((rtx orgfun, rtx value, int no_queue,
-  enum machine_mode outmode, int nargs, ...));
+extern void emit_library_call PARAMS ((rtx, int, enum machine_mode, int, ...));
+extern rtx emit_library_call_value PARAMS ((rtx, rtx, int, enum machine_mode,
+                                           int, ...));
 
 /* Expand an assignment that stores the value of FROM into TO. */
 extern rtx expand_assignment PARAMS ((tree, tree, int, int));
@@ -1100,10 +1108,17 @@ extern rtx prepare_call_address PARAMS ((rtx, tree, rtx *, int));
 
 extern rtx expand_call PARAMS ((tree, rtx, int));
 
-extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree, rtx, int));
-extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int));
-extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *, struct args_size *));
+extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree,
+                                rtx, int));
+extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
+                                 rtx, rtx, int));
+extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
+                                        struct args_size *,
+                                        struct args_size *,
+                                        struct args_size *,
+                                        struct args_size *));
 extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
+
 /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
 extern rtx label_rtx PARAMS ((tree));
 #endif
@@ -1132,9 +1147,15 @@ extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
 
 /* Return a memory reference like MEMREF, but which is known to have a
    valid address.  */
-
 extern rtx validize_mem PARAMS ((rtx));
 
+#ifdef TREE_CODE
+/* Given REF, a MEM, and T, either the type of X or the expression
+   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
+   if we are making a new object of this type.  */
+extern void set_mem_attributes PARAMS ((rtx, tree, int));
+#endif
+
 /* Assemble the static constant template for function entry trampolines.  */
 extern rtx assemble_trampoline_template PARAMS ((void));
 
index 1c67eec..978dc81 100644 (file)
@@ -204,7 +204,7 @@ struct temp_slot
      imposed on the memory.  For example, if the stack slot is the
      call frame for an inline functioned, we have no idea what alias
      sets will be assigned to various pieces of the call frame.  */
-  int alias_set;
+  HOST_WIDE_INT alias_set;
   /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
   tree rtl_expr;
   /* Non-zero if this temporary is currently in use.  */
@@ -628,6 +628,7 @@ assign_stack_local_1 (mode, size, align, function)
 
 /* Wrapper around assign_stack_local_1;  assign a local stack slot for the
    current function.  */
+
 rtx
 assign_stack_local (mode, size, align)
      enum machine_mode mode;
@@ -662,7 +663,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
      tree type;
 {
   int align;
-  int alias_set;
+  HOST_WIDE_INT alias_set;
   struct temp_slot *p, *best_p = 0;
 
   /* If SIZE is -1 it means that somebody tried to allocate a temporary
@@ -684,6 +685,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
 
   if (! type)
     type = type_for_mode (mode, 0);
+
   if (type)
     align = LOCAL_ALIGNMENT (type, align);
 
@@ -693,7 +695,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
   for (p = temp_slots; p; p = p->next)
     if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode
        && ! p->in_use
-       && (!flag_strict_aliasing
+       && (! flag_strict_aliasing
            || (alias_set && p->alias_set == alias_set))
        && (best_p == 0 || best_p->size > p->size
            || (best_p->size == p->size && best_p->align > p->align)))
@@ -712,11 +714,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
       /* If there are enough aligned bytes left over, make them into a new
         temp_slot so that the extra bytes don't get wasted.  Do this only
         for BLKmode slots, so that we can be sure of the alignment.  */
-      if (GET_MODE (best_p->slot) == BLKmode
-         /* We can't split slots if -fstrict-aliasing because the
-            information about the alias set for the new slot will be
-            lost.  */
-         && !flag_strict_aliasing)
+      if (GET_MODE (best_p->slot) == BLKmode)
        {
          int alignment = best_p->align / BITS_PER_UNIT;
          HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
@@ -734,6 +732,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
              p->align = best_p->align;
              p->address = 0;
              p->rtl_expr = 0;
+             p->alias_set = best_p->alias_set;
              p->next = temp_slots;
              temp_slots = p;
 
@@ -824,7 +823,11 @@ assign_stack_temp_for_type (mode, size, keep, type)
   RTX_UNCHANGING_P (p->slot) = 0;
   MEM_IN_STRUCT_P (p->slot) = 0;
   MEM_SCALAR_P (p->slot) = 0;
-  MEM_ALIAS_SET (p->slot) = 0;
+  MEM_ALIAS_SET (p->slot) = alias_set;
+
+  if (type != 0)
+    MEM_SET_IN_STRUCT_P (p->slot, AGGREGATE_TYPE_P (type));
+
   return p->slot;
 }
 
@@ -875,11 +878,10 @@ assign_temp (type, keep, memory_required, dont_promote)
         instead.  This is the case for Chill variable-sized strings.  */
       if (size == -1 && TREE_CODE (type) == ARRAY_TYPE
          && TYPE_ARRAY_MAX_SIZE (type) != NULL_TREE
-         && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type)) == INTEGER_CST)
-       size = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type));
+         && host_integerp (TYPE_ARRAY_MAX_SIZE (type), 1))
+       size = tree_low_cst (TYPE_ARRAY_MAX_SIZE (type), 1);
 
       tmp = assign_stack_temp_for_type (mode, size, keep, type);
-      MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
       return tmp;
     }
 
@@ -1397,8 +1399,12 @@ put_var_into_stack (decl)
       else
        put_reg_into_stack (function, reg, TREE_TYPE (decl),
                            promoted_mode, decl_mode,
-                           TREE_SIDE_EFFECTS (decl), 0,
-                           TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+                           (TREE_CODE (decl) != SAVE_EXPR
+                            && TREE_THIS_VOLATILE (decl)),
+                           0,
+                           (TREE_USED (decl)
+                            || (TREE_CODE (decl) != SAVE_EXPR
+                                && DECL_INITIAL (decl) != 0)),
                            0);
     }
   else if (GET_CODE (reg) == CONCAT)
@@ -2840,9 +2846,14 @@ put_addressof_into_stack (r, ht)
     abort ();
 
   put_reg_into_stack (0, reg, TREE_TYPE (decl), GET_MODE (reg),
-                     DECL_MODE (decl), TREE_SIDE_EFFECTS (decl),
+                     GET_MODE (reg),
+                     (TREE_CODE (decl) != SAVE_EXPR
+                      && TREE_THIS_VOLATILE (decl)),
                      ADDRESSOF_REGNO (r),
-                     TREE_USED (decl) || DECL_INITIAL (decl) != 0, ht);
+                     (TREE_USED (decl)
+                      || (TREE_CODE (decl) != SAVE_EXPR
+                          && DECL_INITIAL (decl) != 0)),
+                     ht);
 }
 
 /* List of replacements made below in purge_addressof_1 when creating
@@ -4168,7 +4179,6 @@ assign_parms (fndecl)
 
   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
     {
-      int aggregate = AGGREGATE_TYPE_P (TREE_TYPE (parm));
       struct args_size stack_offset;
       struct args_size arg_size;
       int passed_pointer = 0;
@@ -4325,12 +4335,7 @@ assign_parms (fndecl)
                                                  internal_arg_pointer,
                                                  offset_rtx));
 
-       /* If this is a memory ref that contains aggregate components,
-          mark it as such for cse and loop optimize.  Likewise if it
-          is readonly.  */
-       MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
-       RTX_UNCHANGING_P (stack_parm) = TREE_READONLY (parm);
-       MEM_ALIAS_SET (stack_parm) = get_alias_set (parm);
+       set_mem_attributes (stack_parm, parm, 1);
       }
 
       /* If this parameter was passed both in registers and in the stack,
@@ -4435,38 +4440,6 @@ assign_parms (fndecl)
          && nominal_mode != BLKmode && nominal_mode != passed_mode)
        stack_parm = 0;
 
-#if 0
-      /* Now adjust STACK_PARM to the mode and precise location
-        where this parameter should live during execution,
-        if we discover that it must live in the stack during execution.
-        To make debuggers happier on big-endian machines, we store
-        the value in the last bytes of the space available.  */
-
-      if (nominal_mode != BLKmode && nominal_mode != passed_mode
-         && stack_parm != 0)
-       {
-         rtx offset_rtx;
-
-         if (BYTES_BIG_ENDIAN
-             && GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
-           stack_offset.constant += (GET_MODE_SIZE (passed_mode)
-                                     - GET_MODE_SIZE (nominal_mode));
-
-         offset_rtx = ARGS_SIZE_RTX (stack_offset);
-         if (offset_rtx == const0_rtx)
-           stack_parm = gen_rtx_MEM (nominal_mode, internal_arg_pointer);
-         else
-           stack_parm = gen_rtx_MEM (nominal_mode,
-                                     gen_rtx_PLUS (Pmode,
-                                                   internal_arg_pointer,
-                                                   offset_rtx));
-
-         /* If this is a memory ref that contains aggregate components,
-            mark it as such for cse and loop optimize.  */
-         MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
-       }
-#endif /* 0 */
-
       /* ENTRY_PARM is an RTX for the parameter as it arrives,
         in the mode in which it arrives.
         STACK_PARM is an RTX for a stack slot where the parameter can live
@@ -4506,18 +4479,12 @@ assign_parms (fndecl)
                  stack_parm
                    = assign_stack_local (GET_MODE (entry_parm),
                                          size_stored, 0);
-
-                 /* If this is a memory ref that contains aggregate
-                    components, mark it as such for cse and loop optimize.  */
-                 MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
+                 set_mem_attributes (stack_parm, parm, 1);
                }
 
              else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
                abort ();
 
-             if (TREE_READONLY (parm))
-               RTX_UNCHANGING_P (stack_parm) = 1;
-
              /* Handle calls that pass values in multiple non-contiguous
                 locations.  The Irix 6 ABI has examples of this.  */
              if (GET_CODE (entry_parm) == PARALLEL)
@@ -4566,7 +4533,7 @@ assign_parms (fndecl)
            {
              DECL_RTL (parm)
                = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
-             MEM_SET_IN_STRUCT_P (DECL_RTL (parm), aggregate);
+             set_mem_attributes (DECL_RTL (parm), parm, 1);
            }
          else
            DECL_RTL (parm) = parmreg;
@@ -4672,8 +4639,7 @@ assign_parms (fndecl)
              else
                copy = assign_stack_temp (TYPE_MODE (type),
                                          int_size_in_bytes (type), 1);
-             MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
-             RTX_UNCHANGING_P (copy) = TREE_READONLY (parm);
+             set_mem_attributes (copy, parm);
 
              store_expr (parm, copy, 0);
              emit_move_insn (parmreg, XEXP (copy, 0));
@@ -4824,9 +4790,7 @@ assign_parms (fndecl)
                  stack_parm
                    = assign_stack_local (GET_MODE (entry_parm),
                                          GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
-                 /* If this is a memory ref that contains aggregate components,
-                    mark it as such for cse and loop optimize.  */
-                 MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
+                 set_mem_attributes (stack_parm, parm, 1);
                }
 
              if (promoted_mode != nominal_mode)
@@ -4863,19 +4827,12 @@ assign_parms (fndecl)
       if (parm == function_result_decl)
        {
          tree result = DECL_RESULT (fndecl);
-         tree restype = TREE_TYPE (result);
 
          DECL_RTL (result)
            = gen_rtx_MEM (DECL_MODE (result), DECL_RTL (parm));
 
-         MEM_SET_IN_STRUCT_P (DECL_RTL (result), 
-                              AGGREGATE_TYPE_P (restype));
+         set_mem_attributes (DECL_RTL (result), result, 1);
        }
-
-      if (TREE_THIS_VOLATILE (parm))
-       MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
-      if (TREE_READONLY (parm))
-       RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
     }
 
   /* Output all parameter conversion instructions (possibly including calls)
@@ -5398,7 +5355,9 @@ fix_lexical_addr (addr, var)
       addr = fix_lexical_addr (XEXP (fp->x_arg_pointer_save_area, 0), var);
       addr = memory_address (Pmode, addr);
 
-      base = copy_to_reg (gen_rtx_MEM (Pmode, addr));
+      base = gen_rtx_MEM (Pmode, addr);
+      MEM_ALIAS_SET (base) = get_frame_alias_set ();
+      base = copy_to_reg (base);
 #else
       displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
       base = lookup_static_chain (var);
@@ -6149,10 +6108,8 @@ expand_function_start (subr, parms_have_cleanups)
        {
          DECL_RTL (DECL_RESULT (subr))
            = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
-         MEM_SET_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)),
-                              AGGREGATE_TYPE_P (TREE_TYPE
-                                                (DECL_RESULT
-                                                 (subr))));
+         set_mem_attributes (DECL_RTL (DECL_RESULT (subr)),
+                             DECL_RESULT (subr), 1);
        }
     }
   else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
@@ -6247,9 +6204,9 @@ expand_function_start (subr, parms_have_cleanups)
 #ifdef FRAME_GROWS_DOWNWARD
          last_ptr = plus_constant (last_ptr, - GET_MODE_SIZE (Pmode));
 #endif
-         last_ptr = copy_to_reg (gen_rtx_MEM (Pmode,
-                                              memory_address (Pmode,
-                                                              last_ptr)));
+         last_ptr = gen_rtx_MEM (Pmode, memory_address (Pmode, last_ptr));
+         MEM_ALIAS_SET (last_ptr) = get_frame_alias_set ();
+         last_ptr = copy_to_reg (last_ptr);
 
          /* If we are not optimizing, ensure that we know that this
             piece of context is live over the entire function.  */
index ed4b135..556f9f9 100644 (file)
@@ -1939,11 +1939,10 @@ mode_independent_operand (op, mode)
   return 0;
 }
 
-/* Given an operand OP that is a valid memory reference
-   which satisfies offsettable_memref_p,
-   return a new memory reference whose address has been adjusted by OFFSET.
-   OFFSET should be positive and less than the size of the object referenced.
-*/
+/* Given an operand OP that is a valid memory reference which
+   satisfies offsettable_memref_p, return a new memory reference whose
+   address has been adjusted by OFFSET.  OFFSET should be positive and
+   less than the size of the object referenced.  */
 
 rtx
 adj_offsettable_operand (op, offset)
@@ -1961,7 +1960,7 @@ adj_offsettable_operand (op, offset)
        {
          new = gen_rtx_MEM (GET_MODE (op),
                             plus_constant_for_output (y, offset));
-         RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
+         MEM_COPY_ATTRIBUTES (new, op);
          return new;
        }
 
@@ -1981,7 +1980,7 @@ adj_offsettable_operand (op, offset)
        }
 
       new = gen_rtx_MEM (GET_MODE (op), plus_constant_for_output (y, offset));
-      RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
+      MEM_COPY_ATTRIBUTES (new, op);
       return new;
     }
   abort ();
index 5b244a0..44d63e2 100644 (file)
@@ -2234,6 +2234,8 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
   for (ml = memlist; ml ; ml = ml->next)
     {
       HOST_WIDE_INT c = ml->sp_offset - delta;
+      rtx new = gen_rtx_MEM (GET_MODE (*ml->mem),
+                            plus_constant (stack_pointer_rtx, c));
 
       /* Don't reference memory below the stack pointer.  */
       if (c < 0)
@@ -2242,9 +2244,8 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
          return 0;
        }
 
-      validate_change (ml->insn, ml->mem,
-                      gen_rtx_MEM (GET_MODE (*ml->mem),
-                                   plus_constant (stack_pointer_rtx, c)), 1);
+      MEM_COPY_ATTRIBUTES (new, *ml->mem);
+      validate_change (ml->insn, ml->mem, new, 1);
     }
 
   if (apply_change_group ())
index d19b1d8..0a6d14c 100644 (file)
@@ -860,10 +860,20 @@ push_reload (in, out, inloc, outloc, class,
     {
       if (GET_CODE (XEXP (in, 0)) == POST_INC
          || GET_CODE (XEXP (in, 0)) == POST_DEC)
-       in = gen_rtx_MEM (GET_MODE (in), XEXP (XEXP (in, 0), 0));
+       {
+         rtx new = gen_rtx_MEM (GET_MODE (in), XEXP (XEXP (in, 0), 0));
+
+         MEM_COPY_ATTRIBUTES (new, in);
+         in = new;
+       }
       if (GET_CODE (XEXP (in, 0)) == PRE_INC
          || GET_CODE (XEXP (in, 0)) == PRE_DEC)
-       out = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
+       {
+         rtx new = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
+
+         MEM_COPY_ATTRIBUTES (new, out);
+         out = new;
+       }
     }
 
   /* If we are reloading a (SUBREG constant ...), really reload just the
@@ -4344,7 +4354,7 @@ make_memloc (ad, regno)
     tem = copy_rtx (tem);
 
   tem = gen_rtx_MEM (GET_MODE (ad), tem);
-  RTX_UNCHANGING_P (tem) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
+  MEM_COPY_ATTRIBUTES (tem, reg_equiv_memory_loc[regno]);
   return tem;
 }
 
index c0bf424..3378a68 100644 (file)
@@ -1913,13 +1913,18 @@ alter_reg (i, from_reg)
            adjust = inherent_size - total_size;
 
          RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
+
+         /* Nothing can alias this slot except this pseudo.  */
+         MEM_ALIAS_SET (x) = new_alias_set ();
        }
+
       /* Reuse a stack slot if possible.  */
       else if (spill_stack_slot[from_reg] != 0
               && spill_stack_slot_width[from_reg] >= total_size
               && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
                   >= inherent_size))
        x = spill_stack_slot[from_reg];
+
       /* Allocate a bigger slot.  */
       else
        {
@@ -1927,6 +1932,7 @@ alter_reg (i, from_reg)
             and for total size.  */
          enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
          rtx stack_slot;
+
          if (spill_stack_slot[from_reg])
            {
              if (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
@@ -1935,10 +1941,18 @@ alter_reg (i, from_reg)
              if (spill_stack_slot_width[from_reg] > total_size)
                total_size = spill_stack_slot_width[from_reg];
            }
+
          /* Make a slot with that size.  */
          x = assign_stack_local (mode, total_size,
                                  inherent_size == total_size ? 0 : -1);
          stack_slot = x;
+
+         /* All pseudos mapped to this slot can alias each other.  */
+         if (spill_stack_slot[from_reg])
+           MEM_ALIAS_SET (x) = MEM_ALIAS_SET (spill_stack_slot[from_reg]);
+         else
+           MEM_ALIAS_SET (x) = new_alias_set ();
+
          if (BYTES_BIG_ENDIAN)
            {
              /* Cancel the  big-endian correction done in assign_stack_local.
@@ -1952,6 +1966,7 @@ alter_reg (i, from_reg)
                                                         MODE_INT, 1),
                                          plus_constant (XEXP (x, 0), adjust));
            }
+
          spill_stack_slot[from_reg] = stack_slot;
          spill_stack_slot_width[from_reg] = total_size;
        }
@@ -1965,16 +1980,11 @@ alter_reg (i, from_reg)
         wrong mode, make a new stack slot.  */
       if (adjust != 0 || GET_MODE (x) != GET_MODE (regno_reg_rtx[i]))
        {
-         x = gen_rtx_MEM (GET_MODE (regno_reg_rtx[i]),
-                          plus_constant (XEXP (x, 0), adjust));
-
-         /* If this was shared among registers, must ensure we never
-            set it readonly since that can cause scheduling
-            problems.  Note we would only have in this adjustment
-            case in any event, since the code above doesn't set it.  */
+         rtx new = gen_rtx_MEM (GET_MODE (regno_reg_rtx[i]),
+                                plus_constant (XEXP (x, 0), adjust));
 
-         if (from_reg == -1)
-           RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
+         MEM_COPY_ATTRIBUTES (new, x);
+         x = new;
        }
 
       /* Save the stack slot for later.   */
@@ -2496,9 +2506,7 @@ eliminate_regs (x, mem_mode, insn)
       if (new != XEXP (x, 0))
        {
          new = gen_rtx_MEM (GET_MODE (x), new);
-         new->volatil = x->volatil;
-         new->unchanging = x->unchanging;
-         new->in_struct = x->in_struct;
+         MEM_COPY_ATTRIBUTES (new, x);
          return new;
        }
       else
index 1f628aa..dc0d95b 100644 (file)
@@ -628,7 +628,7 @@ DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o')
 
 /* A memory location; operand is the address.  Can be nested inside a
    VOLATILE.  The second operand is the alias set to which this MEM
-   belongs.  We use `0' instead of `i' for this field so that the
+   belongs.  We use `0' instead of `w' for this field so that the
    field need not be specified in machine descriptions.  */
 DEF_RTL_EXPR(MEM, "mem", "e0", 'o')
 
index de0c37d..cca5d52 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -746,8 +746,10 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
 #define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC ((RTX), 4, ASM_OPERANDS)
 #define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP ((RTX), 3, (N), ASM_OPERANDS)
 #define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN ((RTX), 3, ASM_OPERANDS)
-#define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) XSTR (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS), 0)
-#define ASM_OPERANDS_INPUT_MODE(RTX, N) GET_MODE (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS))
+#define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \
+                       XSTR (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS), 0)
+#define ASM_OPERANDS_INPUT_MODE(RTX, N)  \
+                       GET_MODE (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS))
 #define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR ((RTX), 5, ASM_OPERANDS)
 #define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT ((RTX), 6, ASM_OPERANDS)
 
@@ -755,22 +757,15 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
    Also in an ASM_OPERANDS rtx.  */
 #define MEM_VOLATILE_P(RTX) ((RTX)->volatil)
 
-/* For a MEM rtx, 1 if it refers to a field of an aggregate.  If zero,
-   RTX may or may not refer to a field of an aggregate.  */
+/* For a MEM rtx, 1 if it refers to an aggregate, either to the
+   aggregate itself of to a field of the aggregate.  If zero, RTX may
+   or may not be such a refrence.  */
 #define MEM_IN_STRUCT_P(RTX) ((RTX)->in_struct)
 
 /* For a MEM rtx, 1 if it refers to a scalar.  If zero, RTX may or may
    not refer to a scalar.*/
 #define MEM_SCALAR_P(RTX) ((RTX)->frame_related)
 
-/* Copy the attributes that apply to memory locations from RHS to LHS.  */
-#define MEM_COPY_ATTRIBUTES(LHS, RHS)                  \
-  (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS),                \
-   MEM_IN_STRUCT_P (LHS) = MEM_IN_STRUCT_P (RHS),      \
-   MEM_SCALAR_P (LHS) = MEM_SCALAR_P (RHS),            \
-   MEM_ALIAS_SET (LHS) = MEM_ALIAS_SET (RHS),          \
-   RTX_UNCHANGING_P (LHS) = RTX_UNCHANGING_P (RHS))
-
 /* If VAL is non-zero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in
    RTX.  Otherwise, vice versa.  Use this macro only when you are
    *sure* that you know that the MEM is in a structure, or is a
@@ -797,7 +792,15 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
    some front-ends, these numbers may correspond in some way to types,
    or other language-level entities, but they need not, and the
    back-end makes no such assumptions.  */
-#define MEM_ALIAS_SET(RTX) XCINT(RTX, 1, MEM)
+#define MEM_ALIAS_SET(RTX) XCWINT(RTX, 1, MEM)
+
+/* Copy the attributes that apply to memory locations from RHS to LHS.  */
+#define MEM_COPY_ATTRIBUTES(LHS, RHS)                  \
+  (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS),                \
+   MEM_IN_STRUCT_P (LHS) = MEM_IN_STRUCT_P (RHS),      \
+   MEM_SCALAR_P (LHS) = MEM_SCALAR_P (RHS),            \
+   MEM_ALIAS_SET (LHS) = MEM_ALIAS_SET (RHS),          \
+   RTX_UNCHANGING_P (LHS) = RTX_UNCHANGING_P (RHS))
 
 /* For a LABEL_REF, 1 means that this reference is to a label outside the
    loop containing the reference.  */
@@ -1645,7 +1648,9 @@ extern int preserve_subexpressions_p      PARAMS ((void));
 
 /* In expr.c */
 extern void init_expr_once             PARAMS ((void));
-extern void move_by_pieces             PARAMS ((rtx, rtx, int, unsigned int));
+extern void move_by_pieces             PARAMS ((rtx, rtx,
+                                                unsigned HOST_WIDE_INT,
+                                                unsigned int));
 
 /* In flow.c */
 extern void allocate_bb_life_data      PARAMS ((void));
@@ -1821,9 +1826,6 @@ extern void mark_constant_function        PARAMS ((void));
 extern void init_alias_once            PARAMS ((void));
 extern void init_alias_analysis                PARAMS ((void));
 extern void end_alias_analysis         PARAMS ((void));
-
-extern void record_base_value          PARAMS ((unsigned int, rtx, int));
-extern void record_alias_subset         PARAMS ((int, int));
 extern rtx addr_side_effect_eval       PARAMS ((rtx, int, int));
 
 /* In sibcall.c */
index 3d26748..f134de1 100644 (file)
@@ -3792,7 +3792,8 @@ expand_decl (decl)
        /* An initializer is going to decide the size of this array.
           Until we know the size, represent its address with a reg.  */
        DECL_RTL (decl) = gen_rtx_MEM (BLKmode, gen_reg_rtx (Pmode));
-      MEM_SET_IN_STRUCT_P (DECL_RTL (decl), AGGREGATE_TYPE_P (type));
+
+      set_mem_attributes (DECL_RTL (decl), decl, 1);
     }
   else if (DECL_MODE (decl) != BLKmode
           /* If -ffloat-store, don't put explicit float vars
@@ -3817,6 +3818,8 @@ expand_decl (decl)
        mark_reg_pointer (DECL_RTL (decl),
                          TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
                          
+      if (TREE_READONLY (decl))
+       RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
     }
 
   else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
@@ -3841,8 +3844,6 @@ expand_decl (decl)
        }
 
       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)));
 
       /* Set alignment we actually gave this decl.  */
       DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT
@@ -3854,20 +3855,6 @@ expand_decl (decl)
          if (addr != oldaddr)
            emit_move_insn (oldaddr, addr);
        }
-
-      /* If this is a memory ref that contains aggregate components,
-        mark it as such for cse and loop optimize.  */
-      MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
-                          AGGREGATE_TYPE_P (TREE_TYPE (decl)));
-#if 0
-      /* If this is in memory because of -ffloat-store,
-        set the volatile bit, to prevent optimizations from
-        undoing the effects.  */
-      if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
-       MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
-#endif
-
-      MEM_ALIAS_SET (DECL_RTL (decl)) = get_alias_set (decl);
     }
   else
     /* Dynamic-size object: must push space on the stack.  */
@@ -3905,10 +3892,7 @@ expand_decl (decl)
       /* Reference the variable indirect through that rtx.  */
       DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl), address);
 
-      /* If this is a memory ref that contains aggregate components,
-        mark it as such for cse and loop optimize.  */
-      MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
-                          AGGREGATE_TYPE_P (TREE_TYPE (decl)));
+      set_mem_attributes (DECL_RTL (decl), decl, 1);
 
       /* Indicate the alignment we actually gave this variable.  */
 #ifdef STACK_BOUNDARY
@@ -3917,12 +3901,6 @@ expand_decl (decl)
       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
 #endif
     }
-
-  if (TREE_THIS_VOLATILE (decl))
-    MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
-
-  if (TREE_READONLY (decl))
-    RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
 }
 \f
 /* Emit code to perform the initialization of a declaration DECL.  */
index b28432b..a581d1f 100644 (file)
@@ -1173,6 +1173,9 @@ finish_record_layout (rli)
       rli->pending_statics = TREE_CHAIN (rli->pending_statics);
     }
 
+  /* Show any alias subsetting we need.  */
+  record_component_aliases (rli->t);
+
   /* Clean up.  */
   free (rli);
 }
index ef26426..5fa9851 100644 (file)
@@ -2090,13 +2090,13 @@ compile_file (name)
                  || flag_test_coverage
                  || warn_notreached);
   init_regs ();
+  init_alias_once ();
   init_decl_processing ();
   init_optabs ();
   init_stmt ();
   init_eh ();
   init_loop ();
   init_reload ();
-  init_alias_once ();
   init_function_once ();
   init_stor_layout_once ();
   init_varasm_once ();
index c2bfab8..2a356ed 100644 (file)
@@ -246,10 +246,6 @@ static int next_decl_uid;
 /* Unique id for next type created.  */
 static int next_type_uid = 1;
 
-/* The language-specific function for alias analysis.  If NULL, the
-   language does not do any special alias analysis.  */
-int (*lang_get_alias_set) PARAMS ((tree));
-
 /* Here is how primitive or already-canonicalized types' hash
    codes are made.  */
 #define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
@@ -5614,38 +5610,6 @@ tree_class_check_failed (node, cl, file, line, function)
 
 #endif /* ENABLE_TREE_CHECKING */
 
-/* Return the alias set for T, which may be either a type or an
-   expression.  */
-
-int
-get_alias_set (t)
-     tree t;
-{
-  /* If we're not doing any lanaguage-specific alias analysis, just
-     assume everything aliases everything else.  */
-  if (! flag_strict_aliasing || lang_get_alias_set == 0)
-    return 0;
-
-  /* If this is a type with a known alias set, return it since this must
-     be the correct thing to do.  */
-  else if (TYPE_P (t) && TYPE_ALIAS_SET_KNOWN_P (t))
-    return TYPE_ALIAS_SET (t);
-  else
-    return (*lang_get_alias_set) (t);
-}
-
-/* Return a brand-new alias set.  */
-
-int
-new_alias_set ()
-{
-  static int last_alias_set;
-
-  if (flag_strict_aliasing)
-    return ++last_alias_set;
-  else
-    return 0;
-}
 \f
 #ifndef CHAR_TYPE_SIZE
 #define CHAR_TYPE_SIZE BITS_PER_UNIT
index 13d079a..09758cb 100644 (file)
@@ -1114,7 +1114,7 @@ struct tree_type
   union tree_node *noncopied_parts;
   union tree_node *context;
   struct obstack *obstack;
-  int alias_set;
+  HOST_WIDE_INT alias_set;
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_type *lang_specific;
 };
@@ -1620,7 +1620,7 @@ struct tree_decl
   } u2;
 
   union tree_node *vindex;
-  int pointer_alias_set;
+  HOST_WIDE_INT pointer_alias_set;
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_decl *lang_specific;
 };
@@ -2373,9 +2373,6 @@ extern tree get_file_function_name_long   PARAMS ((const char *));
 extern tree get_set_constructor_bits           PARAMS ((tree, char *, int));
 extern tree get_set_constructor_bytes          PARAMS ((tree,
                                                       unsigned char *, int));
-extern int get_alias_set                        PARAMS ((tree));
-extern int new_alias_set                       PARAMS ((void));
-extern int (*lang_get_alias_set)                PARAMS ((tree));
 extern tree get_callee_fndecl                   PARAMS ((tree));
 \f
 /* In stmt.c */