This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Aliasing patches


This patch does a number of things.

The major one is a reworking of the get_alias_set function and the
addition of a set_mem_attributes function that is used consistently.

It also adds a few more places where MEM_COPY_ATTRIBUTES is called.

It used the alias set for a RECORD_TYPE for all accesses to that record and
creates subset aliases for all individually-addressable fields in the record.

I also made alias sets HOST_WIDE_INT in case some front end wants to allocate
them sparely.

This also adds alias sets for frame values and for spilled registers.

I tested this on Alpha.

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.
	* 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.
	
*** Makefile.in	2000/05/28 02:17:58	1.455
--- Makefile.in	2000/05/31 11:36:39
*************** $(srcdir)/c-gperf.h: c-parse.gperf
*** 1093,1102 ****
  	 $(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-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-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 \
--- 1093,1103 ----
  	 $(SHELL) $(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.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-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 \
*** alias.c	2000/05/22 10:51:27	1.82
--- alias.c	2000/05/31 11:36:43
*************** Boston, MA 02111-1307, USA.  */
*** 58,65 ****
     `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.
  
     Alias set zero is implicitly a superset of all other alias sets.
--- 58,65 ----
     `superset' and that those for `int' and `double' are `subsets'.
  
!    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.
*************** typedef struct alias_set_entry
*** 70,74 ****
  {
    /* The alias set number, as stored in MEM_ALIAS_SET.  */
!   int alias_set;
  
    /* The children of the alias set.  These are not just the immediate
--- 70,74 ----
  {
    /* The alias set number, as stored in MEM_ALIAS_SET.  */
!   HOST_WIDE_INT alias_set;
  
    /* The children of the alias set.  These are not just the immediate
*************** typedef struct alias_set_entry
*** 82,85 ****
--- 82,89 ----
  } *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 find_base_value		PARAMS ((rtx
*** 94,100 ****
  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 rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
! 						      int (*)(rtx)));
  static int aliases_everything_p         PARAMS ((rtx));
  static int write_dependence_p           PARAMS ((rtx, rtx, int));
--- 98,105 ----
  static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx));
  static int insert_subset_children       PARAMS ((splay_tree_node, void*));
! static tree find_base_decl            PARAMS ((tree));
! static 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)));
  static int aliases_everything_p         PARAMS ((rtx));
  static int write_dependence_p           PARAMS ((rtx, rtx, int));
*************** static unsigned int reg_base_value_size;
*** 141,145 ****
  
  #define REG_BASE_VALUE(X) \
!   ((unsigned) REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
  
  /* Vector of known invariant relationships between registers.  Set in
--- 146,150 ----
  
  #define REG_BASE_VALUE(X) \
!   (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
  
  /* Vector of known invariant relationships between registers.  Set in
*************** static splay_tree alias_sets;
*** 188,192 ****
  static alias_set_entry
  get_alias_set_entry (alias_set)
!      int alias_set;
  {
    splay_tree_node sn
--- 193,197 ----
  static alias_set_entry
  get_alias_set_entry (alias_set)
!      HOST_WIDE_INT alias_set;
  {
    splay_tree_node sn
*************** mems_in_disjoint_alias_sets_p (mem1, mem
*** 237,242 ****
      return 0;
  
!   /* Iterate through each of the children of the first alias set,
!      comparing it with the second alias set.  */
    ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
    if (ase != 0 && splay_tree_lookup (ase->children,
--- 242,246 ----
      return 0;
  
!   /* 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,
*************** insert_subset_children (node, data)
*** 267,271 ****
--- 271,437 ----
    return 0;
  }
+ 
+ /* 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
*************** insert_subset_children (node, data)
*** 279,284 ****
  void
  record_alias_subset (superset, subset)
!      int superset;
!      int subset;
  {
    alias_set_entry superset_entry;
--- 445,450 ----
  void
  record_alias_subset (superset, subset)
!      HOST_WIDE_INT superset;
!      HOST_WIDE_INT subset;
  {
    alias_set_entry superset_entry;
*************** record_component_aliases (type)
*** 327,332 ****
       tree type;
  {
!   int superset = get_alias_set (type);
!   int subset;
    tree field;
  
--- 493,498 ----
       tree type;
  {
!   HOST_WIDE_INT superset = get_alias_set (type);
!   HOST_WIDE_INT subset;
    tree field;
  
*************** record_component_aliases (type)
*** 337,341 ****
      {
      case ARRAY_TYPE:
-     case COMPLEX_TYPE:
        subset = get_alias_set (TREE_TYPE (type));
        if (subset != 0)
--- 503,506 ----
*************** record_component_aliases (type)
*** 359,362 ****
--- 524,555 ----
  }
  
+ /* 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.  */
  
*** builtins.c	2000/05/27 22:34:05	1.49
--- builtins.c	2000/05/31 11:36:51
*************** expand_builtin_return_addr (fndecl_code,
*** 289,292 ****
--- 289,293 ----
        tem = memory_address (Pmode, tem);
        tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
+       MEM_ALIAS_SET (tem) = get_frame_alias_set ();
      }
  
*************** expand_builtin_return_addr (fndecl_code,
*** 303,310 ****
--- 304,315 ----
  			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
*************** expand_builtin_setjmp (buf_addr, target,
*** 327,333 ****
--- 332,342 ----
    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);
*************** expand_builtin_setjmp (buf_addr, target,
*** 349,359 ****
  #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)))),
  		  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
  
--- 358,370 ----
  #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
  #endif
+ 
+   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)));
  
*************** expand_builtin_setjmp (buf_addr, target,
*** 361,364 ****
--- 372,376 ----
  			    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);
  
*************** expand_builtin_longjmp (buf_addr, value)
*** 465,468 ****
--- 477,483 ----
    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);
*************** expand_builtin_longjmp (buf_addr, value)
*** 490,493 ****
--- 505,510 ----
        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
*************** expand_builtin_longjmp (buf_addr, value)
*** 514,564 ****
  }
  
! /* Get a MEM rtx for expression EXP which can 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);
!     }
  
!   MEM_SET_IN_STRUCT_P (mem, is_aggregate);
    return mem;
  }
--- 531,562 ----
  }
  
! /* 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 = 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;
  
!   set_mem_attributes (mem, exp, 0);
    return mem;
  }
*************** expand_builtin_va_start (stdarg_p, argli
*** 2008,2024 ****
  }
  
- /* 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)
--- 2009,2015 ----
  }
  
  /* 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)
*** c-common.c	2000/05/27 15:21:15	1.111
--- c-common.c	2000/05/31 11:37:01
*************** static void record_function_format	PARAM
*** 157,161 ****
  						 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));
  
--- 157,160 ----
*************** c_apply_type_quals_to_decl (type_quals, 
*** 3246,3253 ****
  	     decl.  */
  
! 	  int pointed_to_alias_set
  	    = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
  
! 	  if (!pointed_to_alias_set)
  	    /* It's not legal to make a subset of alias set zero.  */
  	    ;
--- 3245,3252 ----
  	     decl.  */
  
! 	  HOST_WIDE_INT pointed_to_alias_set
  	    = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
  
! 	  if (pointed_to_alias_set == 0)
  	    /* It's not legal to make a subset of alias set zero.  */
  	    ;
*************** c_apply_type_quals_to_decl (type_quals, 
*** 3262,3350 ****
  }
  
- /* 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.  */
  
! 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
--- 3261,3274 ----
  }
  
  
  /* Return the typed-based alias set for T, which may be an expression
!    or a type.  Return -1 if we don't do anything special.  */
  
! HOST_WIDE_INT
  c_get_alias_set (t)
       tree t;
  {
    tree u;
  
    /* Permit type-punning when accessing a union, provided the access
       is directly through the union.  For example, this code does not
*************** c_get_alias_set (t)
*** 3360,3438 ****
        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;
!     }
  
!   /* 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;
- 
        /* 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);
  
!       if (signed_variant != type)
! 	TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
!       else 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;
      }
!   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))
      {
!       tree t;
  
        /* Unfortunately, there is no canonical form of a pointer type.
--- 3284,3318 ----
        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;
  
!   /* 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.  */
!       tree signed_variant = signed_type (t);
  
!       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.  */
! 	return 0;
!       else if (signed_variant  != t)
! 	return get_alias_set (signed_variant);
      }
!   else if (POINTER_TYPE_P (t))
      {
!       tree t1;
  
        /* Unfortunately, there is no canonical form of a pointer type.
*************** c_get_alias_set (t)
*** 3459,3475 ****
  	 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);
      }
- 
-   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);
  }
  
--- 3339,3350 ----
  	 the pointed-to types.  This issue has been reported to the
  	 C++ committee.  */
!       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);
      }
  
!   return -1;
  }
  
*************** c_get_alias_set (t)
*** 3481,3484 ****
--- 3356,3360 ----
     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)
*** c-common.h	2000/05/18 17:53:04	1.12
--- c-common.h	2000/05/31 11:37:01
*************** extern void init_function_format_info		P
*** 98,102 ****
  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));
  /* Print an error message for invalid operands to arith operation CODE.
     NOP_EXPR is used as a special case (see truthvalue_conversion).  */
--- 98,102 ----
  extern void check_function_format		PARAMS ((tree, tree, tree));
  extern void c_apply_type_quals_to_decl		PARAMS ((int, 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).  */
*** c-decl.c	2000/05/24 09:08:42	1.113
--- c-decl.c	2000/05/31 11:37:12
*************** Boston, MA 02111-1307, USA.  */
*** 31,37 ****
--- 31,39 ----
  #include "system.h"
  #include "tree.h"
+ #include "rtl.h"
  #include "flags.h"
  #include "function.h"
  #include "output.h"
+ #include "expr.h"
  #include "c-tree.h"
  #include "c-lex.h"
*************** init_decl_processing ()
*** 3013,3023 ****
--- 3015,3031 ----
    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);
+ 
    /* This is for wide string constants.  */
    wchar_array_type_node
      = build_array_type (wchar_type_node, array_domain_type);
  
+   record_component_aliases (char_array_type_node);
+   record_component_aliases (int_array_type_node);
+   record_component_aliases (wchar_array_type_node);
+ 
    void_list_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
  
*************** grokdeclarator (declarator, declspecs, d
*** 4400,4403 ****
--- 4408,4412 ----
  	  if (type_quals)
  	    type = c_build_qualified_type (type, type_quals);
+ 	  record_component_aliases (type);
  
  #if 0	/* don't clear these; leave them set so that the array type
*************** grokdeclarator (declarator, declspecs, d
*** 4572,4575 ****
--- 4581,4585 ----
      {
        type = build_array_type (TREE_TYPE (type), 0);
+       record_component_aliases (type);
        if (size_varies)
  	C_TYPE_VARIABLE_SIZE (type) = 1;
*************** grokdeclarator (declarator, declspecs, d
*** 4684,4687 ****
--- 4694,4698 ----
  							     type_quals),
  				     TYPE_DOMAIN (type));
+ 	    record_component_aliases (type);
  #if 0 /* Leave the field const or volatile as well.  */
  	    type_quals = TYPE_UNQUALIFIED;
*************** grokdeclarator (declarator, declspecs, d
*** 4689,4692 ****
--- 4700,4704 ----
  	  }
  	decl = build_decl (FIELD_DECL, declarator, type);
+ 	TREE_ADDRESSABLE (decl) = ! bitfield;
  	if (size_varies)
  	  C_DECL_VARIABLE_SIZE (decl) = 1;
*************** grokdeclarator (declarator, declspecs, d
*** 4764,4767 ****
--- 4776,4780 ----
  							     type_quals),
  				     TYPE_DOMAIN (type));
+ 	    record_component_aliases (type);
  #if 0 /* Leave the variable const or volatile as well.  */
  	    type_quals = TYPE_UNQUALIFIED;
*** c-typeck.c	2000/05/17 08:15:25	1.66
--- c-typeck.c	2000/05/31 11:37:28
*************** common_type (t1, t2)
*** 314,317 ****
--- 314,318 ----
  	/* 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);
        }
*** caller-save.c	2000/02/26 05:45:17	1.30
--- caller-save.c	2000/05/31 11:37:30
*************** setup_save_areas ()
*** 257,260 ****
--- 257,261 ----
  {
    int i, j, k;
+   unsigned int r;
    HARD_REG_SET hard_regs_used;
  
*************** setup_save_areas ()
*** 268,281 ****
      if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
        {
! 	int regno = reg_renumber[i];
! 	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);
! 	  }
        }
  
--- 269,279 ----
      if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
        {
! 	unsigned int regno = reg_renumber[i];
! 	unsigned int endregno 
  	  = regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
  
! 	for (r = regno; r < endregno; r++)
! 	  if (call_used_regs[r])
! 	    SET_HARD_REG_BIT (hard_regs_used, r);
        }
  
*************** setup_save_areas ()
*** 323,336 ****
  	    /* 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], 
  				    XEXP (regno_save_mem[i][j], 0));
  
! 	    regno_save_mem[i+k][1] 
  	      = adj_offsettable_operand (temp, k * UNITS_PER_WORD);
  	  }
        }
  }
  
  /* Find the places where hard regs are live across calls and save them.  */
  void
  save_call_clobbered_regs ()
--- 321,342 ----
  	    /* 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], 
  				    XEXP (regno_save_mem[i][j], 0));
  
! 	    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 ();
  }
  
  /* Find the places where hard regs are live across calls and save them.  */
+ 
  void
  save_call_clobbered_regs ()
*** calls.c	2000/05/27 22:34:05	1.138
--- calls.c	2000/05/31 11:37:36
*************** initialize_argument_information (num_act
*** 1192,1206 ****
  
  		  copy = gen_rtx_MEM (BLKmode,
! 				      allocate_dynamic_stack_space (size_rtx,
! 								    NULL_RTX,
! 								    TYPE_ALIGN (type)));
  		}
  	      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));
  
  	      store_expr (args[i].tree_value, copy, 0);
--- 1194,1203 ----
  
  		  copy = gen_rtx_MEM (BLKmode,
! 				      allocate_dynamic_stack_space
! 				      (size_rtx, NULL_RTX, TYPE_ALIGN (type)));
! 		  set_mem_attributes (copy, type, 1);
  		}
  	      else
! 		copy = assign_temp (type, 0, 1, 0);
  
  	      store_expr (args[i].tree_value, copy, 0);
*************** compute_argument_addresses (args, argblo
*** 1586,1592 ****
  	  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)));
  
  	  if (GET_CODE (slot_offset) == CONST_INT)
--- 1583,1588 ----
  	  addr = plus_constant (addr, arg_offset);
  	  args[i].stack = gen_rtx_MEM (args[i].mode, addr);
! 	  set_mem_attributes (args[i].stack,
! 			      TREE_TYPE (args[i].tree_value), 1);
  
  	  if (GET_CODE (slot_offset) == CONST_INT)
*************** compute_argument_addresses (args, argblo
*** 1597,1600 ****
--- 1593,1598 ----
  	  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);
  	}
      }
*************** expand_call (exp, target, ignore)
*** 3059,3067 ****
  	  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)));
  	    }
  	}
--- 3057,3065 ----
  	  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));
! 	      set_mem_attributes (target, exp, 1);
  	    }
  	}
*************** expand_call (exp, target, ignore)
*** 3073,3077 ****
  	  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)));
  	}
        /* Handle calls that return values in multiple non-contiguous locations.
--- 3071,3075 ----
  	  target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
  				copy_to_reg (valreg));
! 	  set_mem_attributes (target, exp, 1);
  	}
        /* Handle calls that return values in multiple non-contiguous locations.
*** explow.c	2000/05/25 21:38:48	1.48
--- explow.c	2000/05/31 11:37:56
*************** validize_mem (ref)
*** 629,632 ****
--- 629,687 ----
  }
  
+ /* 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;
+ }
+ 
  /* Return a modified copy of X with its memory address copied
     into a temporary register to protect it from side effects.
*************** stabilize (x)
*** 639,661 ****
  {
    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.  */
- 
        MEM_COPY_ATTRIBUTES (mem, x);
-       if (GET_CODE (addr) == PLUS)
- 	MEM_SET_IN_STRUCT_P (mem, 1);
- 
        return mem;
      }
--- 694,708 ----
  {
    register rtx addr;
+ 
    if (GET_CODE (x) != MEM)
      return x;
+ 
    addr = XEXP (x, 0);
    if (rtx_unstable_p (addr))
      {
!       rtx temp = force_reg (Pmode, copy_all_regs (addr));
!       rtx mem = gen_rtx_MEM (GET_MODE (x), temp);
  
        MEM_COPY_ATTRIBUTES (mem, x);
        return mem;
      }
*** expr.c	2000/05/27 15:21:15	1.242
--- expr.c	2000/05/31 11:38:15
*************** struct move_by_pieces
*** 116,129 ****
    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;
    int reverse;
  };
--- 116,125 ----
    int autinc_to;
    int explicit_inc_to;
    rtx from;
    rtx from_addr;
    int autinc_from;
    int explicit_inc_from;
!   unsigned HOST_WIDE_INT len;
!   HOST_WIDE_INT offset;
    int reverse;
  };
*************** struct clear_by_pieces
*** 138,144 ****
    int autinc_to;
    int explicit_inc_to;
!   int to_struct;
!   int len;
!   int offset;
    int reverse;
  };
--- 134,139 ----
    int autinc_to;
    int explicit_inc_to;
!   unsigned HOST_WIDE_INT len;
!   HOST_WIDE_INT offset;
    int reverse;
  };
*************** static rtx get_push_address	PARAMS ((int
*** 149,156 ****
  
  static rtx enqueue_insn		PARAMS ((rtx, rtx));
! static int move_by_pieces_ninsns PARAMS ((unsigned 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_1	PARAMS ((rtx (*) (rtx, ...),
  					 enum machine_mode,
--- 144,154 ----
  
  static rtx enqueue_insn		PARAMS ((rtx, rtx));
! 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, unsigned HOST_WIDE_INT,
! 					 unsigned int));
  static void clear_by_pieces_1	PARAMS ((rtx (*) (rtx, ...),
  					 enum machine_mode,
*************** void
*** 1382,1386 ****
  move_by_pieces (to, from, len, align)
       rtx to, from;
!      int len;
       unsigned int align;
  {
--- 1380,1384 ----
  move_by_pieces (to, from, len, align)
       rtx to, from;
!      unsigned HOST_WIDE_INT len;
       unsigned int align;
  {
*************** move_by_pieces (to, from, len, align)
*** 1411,1419 ****
    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)
--- 1409,1412 ----
*************** move_by_pieces (to, from, len, align)
*** 1490,1500 ****
     ALIGN (in bytes) is maximum alignment we can assume.  */
  
! static int
  move_by_pieces_ninsns (l, align)
!      unsigned int l;
       unsigned int align;
  {
!   register int n_insns = 0;
!   unsigned int max_size = MOVE_MAX + 1;
  
    if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
--- 1483,1493 ----
     ALIGN (in bytes) is maximum alignment we can assume.  */
  
! static unsigned HOST_WIDE_INT
  move_by_pieces_ninsns (l, align)
!      unsigned HOST_WIDE_INT l;
       unsigned int align;
  {
!   unsigned HOST_WIDE_INT n_insns = 0;
!   unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1;
  
    if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
*************** move_by_pieces_1 (genfun, mode, data)
*** 1535,1562 ****
       struct move_by_pieces *data;
  {
!   register int size = GET_MODE_SIZE (mode);
!   register 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 (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
  	emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
--- 1528,1557 ----
       struct move_by_pieces *data;
  {
!   unsigned int size = GET_MODE_SIZE (mode);
!   rtx to1, from1;
  
    while (data->len >= size)
      {
!       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)));
*************** static void
*** 2244,2253 ****
  clear_by_pieces (to, len, align)
       rtx to;
!      int len;
       unsigned int align;
  {
    struct clear_by_pieces data;
    rtx to_addr = XEXP (to, 0);
!   unsigned int max_size = MOVE_MAX_PIECES + 1;
    enum machine_mode mode = VOIDmode, tmode;
    enum insn_code icode;
--- 2241,2250 ----
  clear_by_pieces (to, len, align)
       rtx to;
!      unsigned HOST_WIDE_INT len;
       unsigned int align;
  {
    struct clear_by_pieces data;
    rtx to_addr = XEXP (to, 0);
!   unsigned HOST_WIDE_INT max_size = MOVE_MAX_PIECES + 1;
    enum machine_mode mode = VOIDmode, tmode;
    enum insn_code icode;
*************** clear_by_pieces (to, len, align)
*** 2266,2271 ****
    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)
--- 2263,2266 ----
*************** clear_by_pieces (to, len, align)
*** 2286,2290 ****
  	  data.explicit_inc_to = -1;
  	}
!       if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
  	{
  	  data.to_addr = copy_addr_to_reg (to_addr);
--- 2281,2287 ----
  	  data.explicit_inc_to = -1;
  	}
! 
!       if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse
! 	  && ! data.autinc_to)
  	{
  	  data.to_addr = copy_addr_to_reg (to_addr);
*************** clear_by_pieces (to, len, align)
*** 2292,2296 ****
  	  data.explicit_inc_to = 1;
  	}
!       if (!data.autinc_to && CONSTANT_P (to_addr))
  	data.to_addr = copy_addr_to_reg (to_addr);
      }
--- 2289,2294 ----
  	  data.explicit_inc_to = 1;
  	}
! 
!       if ( !data.autinc_to && CONSTANT_P (to_addr))
  	data.to_addr = copy_addr_to_reg (to_addr);
      }
*************** clear_by_pieces_1 (genfun, mode, data)
*** 2335,2351 ****
       struct clear_by_pieces *data;
  {
!   register int size = GET_MODE_SIZE (mode);
!   register rtx to1;
  
    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;
  
        if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
--- 2333,2352 ----
       struct clear_by_pieces *data;
  {
!   unsigned int size = GET_MODE_SIZE (mode);
!   rtx to1;
  
    while (data->len >= size)
      {
!       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 (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
*************** clear_by_pieces_1 (genfun, mode, data)
*** 2353,2360 ****
  
        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;
  
        data->len -= size;
--- 2354,2363 ----
  
        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;
  
        data->len -= size;
*************** emit_push_insn (x, mode, type, size, ali
*** 3106,3109 ****
--- 3109,3117 ----
  	      && 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);
*************** emit_push_insn (x, mode, type, size, ali
*** 3116,3119 ****
--- 3124,3130 ----
  	      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;
*************** emit_push_insn (x, mode, type, size, ali
*** 3252,3255 ****
--- 3263,3267 ----
        rtx addr;
        rtx target = NULL_RTX;
+       rtx dest;
  
        /* Push padding now if padding above and stack grows down,
*************** emit_push_insn (x, mode, type, size, ali
*** 3279,3284 ****
  	  target = addr;
  	}
  
!       emit_move_insn (gen_rtx_MEM (mode, addr), x);
  
        if (current_function_check_memory_usage && ! in_check_memory_usage)
--- 3291,3300 ----
  	  target = addr;
  	}
+ 
+       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)
*************** store_expr (exp, target, want_value)
*** 3995,3998 ****
--- 4011,4018 ----
  	      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;
*************** store_expr (exp, target, want_value)
*** 4004,4008 ****
  				       TYPE_MODE (integer_type_node));
  		  in_check_memory_usage = 0;
! 		  clear_storage (gen_rtx_MEM (BLKmode, addr), size, align);
  		}
  
--- 4024,4028 ----
  				       TYPE_MODE (integer_type_node));
  		  in_check_memory_usage = 0;
! 		  clear_storage (target, size, align);
  		}
  
*************** expand_expr (exp, target, tmode, modifie
*** 5981,5988 ****
  	  addr = XEXP (DECL_RTL (exp), 0);
  	  if (GET_CODE (addr) == MEM)
! 	    addr = gen_rtx_MEM (Pmode,
! 				fix_lexical_addr (XEXP (addr, 0), exp));
  	  else
  	    addr = fix_lexical_addr (addr, exp);
  	  temp = change_address (DECL_RTL (exp), mode, addr);
  	}
--- 6001,6009 ----
  	  addr = XEXP (DECL_RTL (exp), 0);
  	  if (GET_CODE (addr) == MEM)
! 	    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);
  	}
*************** expand_expr (exp, target, tmode, modifie
*** 6419,6423 ****
        {
  	tree exp1 = TREE_OPERAND (exp, 0);
- 	tree exp2;
  	tree index;
   	tree string = string_constant (exp1, &index);
--- 6440,6443 ----
*************** expand_expr (exp, target, tmode, modifie
*** 6457,6473 ****
  
  	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);
  
  	/* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY
--- 6477,6481 ----
  
  	temp = gen_rtx_MEM (mode, op0);
! 	set_mem_attributes (temp, exp, 0);
  
  	/* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY
*************** expand_expr (exp, target, tmode, modifie
*** 6894,6904 ****
  					       (bitpos / BITS_PER_UNIT)));
  
! 	if (GET_CODE (op0) == MEM)
! 	  MEM_ALIAS_SET (op0) = get_alias_set (exp);
!  
  	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
--- 6902,6909 ----
  					       (bitpos / BITS_PER_UNIT)));
  
! 	set_mem_attributes (op0, exp, 0);
  	if (GET_CODE (XEXP (op0, 0)) == REG)
  	  mark_reg_pointer (XEXP (op0, 0), alignment);
  
  	MEM_VOLATILE_P (op0) |= volatilep;
  	if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
*** expr.h	2000/04/17 19:21:09	1.62
--- expr.h	2000/05/31 11:38:18
*************** struct args_size
*** 95,100 ****
  #define ADD_PARM_SIZE(TO, INC)	\
  { tree inc = (INC);				\
!   if (TREE_CODE (inc) == INTEGER_CST)		\
!     (TO).constant += TREE_INT_CST_LOW (inc);	\
    else if ((TO).var == 0)			\
      (TO).var = inc;				\
--- 95,100 ----
  #define ADD_PARM_SIZE(TO, INC)	\
  { tree inc = (INC);				\
!   if (host_integerp (inc, 0))			\
!     (TO).constant += tree_low_cst (inc, 0);	\
    else if ((TO).var == 0)			\
      (TO).var = inc;				\
*************** struct args_size
*** 104,109 ****
  #define SUB_PARM_SIZE(TO, DEC)	\
  { tree dec = (DEC);				\
!   if (TREE_CODE (dec) == INTEGER_CST)		\
!     (TO).constant -= TREE_INT_CST_LOW (dec);	\
    else if ((TO).var == 0)			\
      (TO).var = size_binop (MINUS_EXPR, ssize_int (0), dec); \
--- 104,109 ----
  #define SUB_PARM_SIZE(TO, DEC)	\
  { tree dec = (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); \
*************** extern rtx expand_builtin_setjmp PARAMS 
*** 916,920 ****
  extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
  extern rtx expand_builtin_saveregs PARAMS ((void));
! extern int get_varargs_alias_set PARAMS ((void));
  
  /* Functions from expr.c:  */
--- 916,929 ----
  extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
  extern rtx expand_builtin_saveregs 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));
  
  /* Functions from expr.c:  */
*************** extern rtx change_address PARAMS ((rtx, 
*** 1133,1138 ****
  /* Return a memory reference like MEMREF, but which is known to have a
     valid address.  */
- 
  extern rtx validize_mem PARAMS ((rtx));
  
  /* Assemble the static constant template for function entry trampolines.  */
--- 1148,1159 ----
  /* 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.  */
*** function.c	2000/05/29 08:18:30	1.201
--- function.c	2000/05/31 11:39:12
*************** struct temp_slot
*** 205,209 ****
       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;
    /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
    tree rtl_expr;
--- 205,209 ----
       call frame for an inline functioned, we have no idea what alias
       sets will be assigned to various pieces of the call frame.  */
!   HOST_WIDE_INT alias_set;
    /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
    tree rtl_expr;
*************** assign_stack_temp_for_type (mode, size, 
*** 663,667 ****
  {
    int align;
!   int alias_set;
    struct temp_slot *p, *best_p = 0;
  
--- 664,668 ----
  {
    int align;
!   HOST_WIDE_INT alias_set;
    struct temp_slot *p, *best_p = 0;
  
*************** assign_stack_temp_for_type (mode, size, 
*** 713,721 ****
  	 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)
  	{
  	  int alignment = best_p->align / BITS_PER_UNIT;
--- 715,719 ----
  	 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)
  	{
  	  int alignment = best_p->align / BITS_PER_UNIT;
*************** assign_stack_temp_for_type (mode, size, 
*** 735,738 ****
--- 733,737 ----
  	      p->address = 0;
  	      p->rtl_expr = 0;
+ 	      p->alias_set = best_p->alias_set;
  	      p->next = temp_slots;
  	      temp_slots = p;
*************** assign_stack_temp_for_type (mode, size, 
*** 825,829 ****
    MEM_IN_STRUCT_P (p->slot) = 0;
    MEM_SCALAR_P (p->slot) = 0;
!   MEM_ALIAS_SET (p->slot) = 0;
    return p->slot;
  }
--- 824,832 ----
    MEM_IN_STRUCT_P (p->slot) = 0;
    MEM_SCALAR_P (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;
  }
*************** assign_temp (type, keep, memory_required
*** 876,884 ****
        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));
  
        tmp = assign_stack_temp_for_type (mode, size, keep, type);
-       MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
        return tmp;
      }
--- 879,886 ----
        if (size == -1 && TREE_CODE (type) == ARRAY_TYPE
  	  && TYPE_ARRAY_MAX_SIZE (type) != NULL_TREE
! 	  && 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);
        return tmp;
      }
*************** put_var_into_stack (decl)
*** 1398,1403 ****
  	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,
  			    0);
      }
--- 1400,1409 ----
  	put_reg_into_stack (function, reg, TREE_TYPE (decl),
  			    promoted_mode, decl_mode,
! 			    (TREE_CODE (decl) != SAVE_EXPR
! 			     && TREE_THIS_VOLATILE (decl)),
! 			    0,
! 			    (TREE_USED (decl)
! 			     || (TREE_CODE (decl) != SAVE_EXPR
! 				 && DECL_INITIAL (decl) != 0)),
  			    0);
      }
*************** put_addressof_into_stack (r, ht)
*** 2841,2847 ****
  
    put_reg_into_stack (0, reg, TREE_TYPE (decl), GET_MODE (reg),
! 		      DECL_MODE (decl), TREE_SIDE_EFFECTS (decl),
  		      ADDRESSOF_REGNO (r),
! 		      TREE_USED (decl) || DECL_INITIAL (decl) != 0, ht);
  }
  
--- 2847,2858 ----
  
    put_reg_into_stack (0, reg, TREE_TYPE (decl), GET_MODE (reg),
! 		      GET_MODE (reg),
! 		      (TREE_CODE (decl) != SAVE_EXPR
! 		       && TREE_THIS_VOLATILE (decl)),
  		      ADDRESSOF_REGNO (r),
! 		      (TREE_USED (decl)
! 		       || (TREE_CODE (decl) != SAVE_EXPR
! 			   && DECL_INITIAL (decl) != 0)),
! 		      ht);
  }
  
*************** assign_parms (fndecl)
*** 4169,4173 ****
    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;
--- 4180,4183 ----
*************** assign_parms (fndecl)
*** 4326,4335 ****
  						  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);
        }
  
--- 4336,4340 ----
  						  offset_rtx));
  
! 	set_mem_attributes (stack_parm, parm, 1);
        }
  
*************** assign_parms (fndecl)
*** 4436,4471 ****
  	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.
--- 4441,4444 ----
*************** assign_parms (fndecl)
*** 4507,4514 ****
  		    = 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);
  		}
  
--- 4480,4484 ----
  		    = assign_stack_local (GET_MODE (entry_parm),
  					  size_stored, 0);
! 		  set_mem_attributes (stack_parm, parm, 1);
  		}
  
*************** assign_parms (fndecl)
*** 4516,4522 ****
  		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.  */
--- 4486,4489 ----
*************** assign_parms (fndecl)
*** 4567,4571 ****
  	      DECL_RTL (parm)
  		= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
! 	      MEM_SET_IN_STRUCT_P (DECL_RTL (parm), aggregate);
  	    }
  	  else
--- 4534,4538 ----
  	      DECL_RTL (parm)
  		= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
! 	      set_mem_attributes (DECL_RTL (parm), parm, 1);
  	    }
  	  else
*************** assign_parms (fndecl)
*** 4673,4678 ****
  		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);
  
  	      store_expr (parm, copy, 0);
--- 4640,4644 ----
  		copy = assign_stack_temp (TYPE_MODE (type),
  					  int_size_in_bytes (type), 1);
! 	      set_mem_attributes (copy, parm);
  
  	      store_expr (parm, copy, 0);
*************** assign_parms (fndecl)
*** 4825,4831 ****
  		    = 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);
  		}
  
--- 4791,4795 ----
  		    = assign_stack_local (GET_MODE (entry_parm),
  					  GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
! 		  set_mem_attributes (stack_parm, parm, 1);
  		}
  
*************** assign_parms (fndecl)
*** 4864,4880 ****
  	{
  	  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));
  	}
- 
-       if (TREE_THIS_VOLATILE (parm))
- 	MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
-       if (TREE_READONLY (parm))
- 	RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
      }
  
--- 4828,4837 ----
  	{
  	  tree result = DECL_RESULT (fndecl);
  
  	  DECL_RTL (result)
  	    = gen_rtx_MEM (DECL_MODE (result), DECL_RTL (parm));
  
! 	  set_mem_attributes (DECL_RTL (result), result, 1);
  	}
      }
  
*************** fix_lexical_addr (addr, var)
*** 5399,5403 ****
        addr = memory_address (Pmode, addr);
  
!       base = copy_to_reg (gen_rtx_MEM (Pmode, addr));
  #else
        displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
--- 5356,5362 ----
        addr = memory_address (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);
*************** expand_function_start (subr, parms_have_
*** 6150,6157 ****
  	  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))));
  	}
      }
--- 6109,6114 ----
  	  DECL_RTL (DECL_RESULT (subr))
  	    = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
! 	  set_mem_attributes (DECL_RTL (DECL_RESULT (subr)),
! 			      DECL_RESULT (subr), 1);
  	}
      }
*************** expand_function_start (subr, parms_have_
*** 6248,6254 ****
  	  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)));
  
  	  /* If we are not optimizing, ensure that we know that this
--- 6205,6211 ----
  	  last_ptr = plus_constant (last_ptr, - GET_MODE_SIZE (Pmode));
  #endif
! 	  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
*** integrate.c	2000/05/25 21:38:49	1.107
--- integrate.c	2000/05/31 11:39:19
*************** expand_inline_function (fndecl, parms, t
*** 1187,1191 ****
  			    memory_address (TYPE_MODE (type),
  					    structure_value_addr));
!       MEM_SET_IN_STRUCT_P (target, 1);
      }
  
--- 1187,1191 ----
  			    memory_address (TYPE_MODE (type),
  					    structure_value_addr));
!       set_mem_attributes (target, type, 1);
      }
  
*** recog.c	2000/05/28 02:17:58	1.62
--- recog.c	2000/05/31 11:39:29
*************** adj_offsettable_operand (op, offset)
*** 1962,1966 ****
  	  new = gen_rtx_MEM (GET_MODE (op),
  			     plus_constant_for_output (y, offset));
! 	  RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
  	  return new;
  	}
--- 1961,1965 ----
  	  new = gen_rtx_MEM (GET_MODE (op),
  			     plus_constant_for_output (y, offset));
! 	  MEM_COPY_ATTRIBUTES (new, op);
  	  return new;
  	}
*************** adj_offsettable_operand (op, offset)
*** 1982,1986 ****
  
        new = gen_rtx_MEM (GET_MODE (op), plus_constant_for_output (y, offset));
!       RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
        return new;
      }
--- 1981,1985 ----
  
        new = gen_rtx_MEM (GET_MODE (op), plus_constant_for_output (y, offset));
!       MEM_COPY_ATTRIBUTES (new, op);
        return new;
      }
*** regmove.c	2000/04/28 23:27:40	1.86
--- regmove.c	2000/05/31 11:39:43
*************** try_apply_stack_adjustment (insn, memlis
*** 2235,2238 ****
--- 2235,2240 ----
      {
        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.  */
*************** try_apply_stack_adjustment (insn, memlis
*** 2243,2249 ****
  	}
  
!       validate_change (ml->insn, ml->mem,
! 		       gen_rtx_MEM (GET_MODE (*ml->mem),
! 				    plus_constant (stack_pointer_rtx, c)), 1);
      }
  
--- 2245,2250 ----
  	}
  
!       MEM_COPY_ATTRIBUTES (new, *ml->mem);
!       validate_change (ml->insn, ml->mem, new, 1);
      }
  
*** reload.c	2000/05/28 01:07:18	1.109
--- reload.c	2000/05/31 11:40:01
*************** push_reload (in, out, inloc, outloc, cla
*** 861,868 ****
        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));
        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));
      }
  
--- 861,878 ----
        if (GET_CODE (XEXP (in, 0)) == POST_INC
  	  || GET_CODE (XEXP (in, 0)) == POST_DEC)
! 	{
! 	  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)
! 	{
! 	  rtx new = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
! 
! 	  MEM_COPY_ATTRIBUTES (new, out);
! 	  out = new;
! 	}
      }
  
*************** make_memloc (ad, regno)
*** 4345,4349 ****
  
    tem = gen_rtx_MEM (GET_MODE (ad), tem);
!   RTX_UNCHANGING_P (tem) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
    return tem;
  }
--- 4355,4359 ----
  
    tem = gen_rtx_MEM (GET_MODE (ad), tem);
!   MEM_COPY_ATTRIBUTES (tem, reg_equiv_memory_loc[regno]);
    return tem;
  }
*** reload1.c	2000/05/23 17:13:36	1.214
--- reload1.c	2000/05/31 11:40:19
*************** alter_reg (i, from_reg)
*** 1914,1918 ****
--- 1914,1922 ----
  
  	  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
*************** alter_reg (i, from_reg)
*** 1921,1924 ****
--- 1925,1929 ----
  		   >= inherent_size))
  	x = spill_stack_slot[from_reg];
+ 
        /* Allocate a bigger slot.  */
        else
*************** alter_reg (i, from_reg)
*** 1928,1931 ****
--- 1933,1937 ----
  	  enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
  	  rtx stack_slot;
+ 
  	  if (spill_stack_slot[from_reg])
  	    {
*************** alter_reg (i, from_reg)
*** 1936,1943 ****
--- 1942,1957 ----
  		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)
  	    {
*************** alter_reg (i, from_reg)
*** 1953,1956 ****
--- 1967,1971 ----
  					  plus_constant (XEXP (x, 0), adjust));
  	    }
+ 
  	  spill_stack_slot[from_reg] = stack_slot;
  	  spill_stack_slot_width[from_reg] = total_size;
*************** alter_reg (i, from_reg)
*** 1966,1979 ****
        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.  */
  
! 	  if (from_reg == -1)
! 	    RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  	}
  
--- 1981,1989 ----
        if (adjust != 0 || GET_MODE (x) != GET_MODE (regno_reg_rtx[i]))
  	{
! 	  rtx new = gen_rtx_MEM (GET_MODE (regno_reg_rtx[i]),
! 				 plus_constant (XEXP (x, 0), adjust));
  
! 	  MEM_COPY_ATTRIBUTES (new, x);
! 	  x = new;
  	}
  
*************** eliminate_regs (x, mem_mode, insn)
*** 2497,2503 ****
  	{
  	  new = gen_rtx_MEM (GET_MODE (x), new);
! 	  new->volatil = x->volatil;
! 	  new->unchanging = x->unchanging;
! 	  new->in_struct = x->in_struct;
  	  return new;
  	}
--- 2507,2511 ----
  	{
  	  new = gen_rtx_MEM (GET_MODE (x), new);
! 	  MEM_COPY_ATTRIBUTES (new, x);
  	  return new;
  	}
*** rtl.def	2000/05/17 01:44:03	1.39
--- rtl.def	2000/05/31 11:40:21
*************** DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o'
*** 629,633 ****
  /* 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
     field need not be specified in machine descriptions.  */
  DEF_RTL_EXPR(MEM, "mem", "e0", 'o')
--- 629,633 ----
  /* 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 `w' for this field so that the
     field need not be specified in machine descriptions.  */
  DEF_RTL_EXPR(MEM, "mem", "e0", 'o')
*** rtl.h	2000/05/25 16:41:30	1.207
--- rtl.h	2000/05/31 11:40:24
*************** extern const char * const note_insn_name
*** 764,775 ****
  #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
--- 767,770 ----
*************** extern const char * const note_insn_name
*** 798,802 ****
     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)
  
  /* For a LABEL_REF, 1 means that this reference is to a label outside the
--- 793,805 ----
     or other language-level entities, but they need not, and the
     back-end makes no such assumptions.  */
! #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
*************** extern int preserve_subexpressions_p	PAR
*** 1646,1650 ****
  /* In expr.c */
  extern void init_expr_once		PARAMS ((void));
! extern void move_by_pieces		PARAMS ((rtx, rtx, int, unsigned int));
  
  /* In flow.c */
--- 1649,1655 ----
  /* In expr.c */
  extern void init_expr_once		PARAMS ((void));
! extern void move_by_pieces		PARAMS ((rtx, rtx,
! 						 unsigned HOST_WIDE_INT,
! 						 unsigned int));
  
  /* In flow.c */
*************** extern void init_alias_once		PARAMS ((vo
*** 1822,1828 ****
  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));
  
--- 1827,1830 ----
*** stmt.c	2000/05/31 10:57:19	1.148
--- stmt.c	2000/05/31 11:40:38
*************** expand_decl (decl)
*** 3793,3797 ****
  	   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));
      }
    else if (DECL_MODE (decl) != BLKmode
--- 3793,3798 ----
  	   Until we know the size, represent its address with a reg.  */
  	DECL_RTL (decl) = gen_rtx_MEM (BLKmode, gen_reg_rtx (Pmode));
! 
!       set_mem_attributes (DECL_RTL (decl), decl, 1);
      }
    else if (DECL_MODE (decl) != BLKmode
*************** expand_decl (decl)
*** 3818,3821 ****
--- 3819,3824 ----
  			  TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
  			  
+       if (TREE_READONLY (decl))
+ 	RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
      }
  
*************** expand_decl (decl)
*** 3842,3847 ****
  
        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.  */
--- 3845,3848 ----
*************** expand_decl (decl)
*** 3855,3872 ****
  	    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
--- 3856,3859 ----
*************** expand_decl (decl)
*** 3906,3913 ****
        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)));
  
        /* Indicate the alignment we actually gave this variable.  */
--- 3893,3897 ----
        DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl), address);
  
!       set_mem_attributes (DECL_RTL (decl), decl, 1);
  
        /* Indicate the alignment we actually gave this variable.  */
*************** expand_decl (decl)
*** 3918,3927 ****
  #endif
      }
- 
-   if (TREE_THIS_VOLATILE (decl))
-     MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
- 
-   if (TREE_READONLY (decl))
-     RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
  }
  
--- 3902,3905 ----
*** stor-layout.c	2000/05/29 21:46:43	1.75
--- stor-layout.c	2000/05/31 11:40:43
*************** finish_record_layout (rli)
*** 1174,1177 ****
--- 1174,1180 ----
      }
  
+   /* Show any alias subsetting we need.  */
+   record_component_aliases (rli->t);
+ 
    /* Clean up.  */
    free (rli);
*** toplev.c	2000/05/29 07:09:53	1.347
--- toplev.c	2000/05/31 11:40:59
*************** compile_file (name)
*** 2091,2094 ****
--- 2091,2095 ----
  		  || warn_notreached);
    init_regs ();
+   init_alias_once ();
    init_decl_processing ();
    init_optabs ();
*************** compile_file (name)
*** 2097,2101 ****
    init_loop ();
    init_reload ();
-   init_alias_once ();
    init_function_once ();
    init_stor_layout_once ();
--- 2098,2101 ----
*** tree.c	2000/05/27 15:21:15	1.146
--- tree.c	2000/05/31 11:41:17
*************** static int next_decl_uid;
*** 247,254 ****
  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.  */
--- 247,250 ----
*************** tree_class_check_failed (node, cl, file,
*** 5615,5650 ****
  #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;
- }
  
  #ifndef CHAR_TYPE_SIZE
--- 5611,5614 ----
*** tree.h	2000/05/27 15:21:15	1.173
--- tree.h	2000/05/31 11:41:28
*************** struct tree_type
*** 1115,1119 ****
    union tree_node *context;
    struct obstack *obstack;
!   int alias_set;
    /* Points to a structure whose details depend on the language in use.  */
    struct lang_type *lang_specific;
--- 1115,1119 ----
    union tree_node *context;
    struct obstack *obstack;
!   HOST_WIDE_INT alias_set;
    /* Points to a structure whose details depend on the language in use.  */
    struct lang_type *lang_specific;
*************** struct tree_decl
*** 1621,1625 ****
  
    union tree_node *vindex;
!   int pointer_alias_set;
    /* Points to a structure whose details depend on the language in use.  */
    struct lang_decl *lang_specific;
--- 1621,1625 ----
  
    union tree_node *vindex;
!   HOST_WIDE_INT pointer_alias_set;
    /* Points to a structure whose details depend on the language in use.  */
    struct lang_decl *lang_specific;
*************** extern tree get_set_constructor_bits		PA
*** 2374,2380 ****
  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));
  
--- 2374,2377 ----
*** varasm.c	2000/05/25 15:21:50	1.121
--- varasm.c	2000/05/31 11:41:41
*************** make_function_rtl (decl)
*** 560,567 ****
  	= gen_rtx_MEM (DECL_MODE (decl),
  		       gen_rtx_SYMBOL_REF (Pmode, name));
  
!       /* Optionally set flags or add text to the name to record information
! 	 such as that it is a function name.  If the name is changed, the macro
! 	 ASM_OUTPUT_LABELREF will have to know how to strip this information.  */
  #ifdef ENCODE_SECTION_INFO
        ENCODE_SECTION_INFO (decl);
--- 560,569 ----
  	= gen_rtx_MEM (DECL_MODE (decl),
  		       gen_rtx_SYMBOL_REF (Pmode, name));
+       set_mem_attributes (DECL_RTL (decl), decl, 1);
  
!       /* Optionally set flags or add text to the name to record
! 	 information such as that it is a function name.  If the name
! 	 is changed, the macro ASM_OUTPUT_LABELREF will have to know
! 	 how to strip this information.  */
  #ifdef ENCODE_SECTION_INFO
        ENCODE_SECTION_INFO (decl);
*************** make_decl_rtl (decl, asmspec, top_level)
*** 799,826 ****
  	    }
  
  	  DECL_ASSEMBLER_NAME (decl)
  	    = get_identifier (name[0] == '*' ? name + 1 : name);
  	  DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
  					 gen_rtx_SYMBOL_REF (Pmode, name));
! 	  MEM_ALIAS_SET (DECL_RTL (decl)) = get_alias_set (decl);
! 
! 	  /* If this variable is to be treated as volatile, show its
! 	     tree node has side effects.  If it has side effects, either
! 	     because of this test or from TREE_THIS_VOLATILE also
! 	     being set, show the MEM is volatile.  */
! 	  if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL
! 	      && TREE_PUBLIC (decl))
! 	    TREE_SIDE_EFFECTS (decl) = 1;
! 	  else if (flag_volatile_static && TREE_CODE (decl) == VAR_DECL
! 	       && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))
! 	    TREE_SIDE_EFFECTS (decl) = 1;
! 
! 	  if (TREE_SIDE_EFFECTS (decl))
! 	    MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
! 
! 	  if (TREE_READONLY (decl))
! 	    RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
! 	  MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
! 			       AGGREGATE_TYPE_P (TREE_TYPE (decl)));
  
  	  /* Optionally set flags or add text to the name to record information
--- 801,817 ----
  	    }
  
+ 	  /* If this variable is to be treated as volatile, show its
+ 	     tree node has side effects.   */
+ 	  if ((flag_volatile_global && TREE_CODE (decl) == VAR_DECL
+ 	       && TREE_PUBLIC (decl))
+ 	      || ((flag_volatile_static && TREE_CODE (decl) == VAR_DECL
+ 		   && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))))
+ 	    TREE_SIDE_EFFECTS (decl) = 1;
+ 
  	  DECL_ASSEMBLER_NAME (decl)
  	    = get_identifier (name[0] == '*' ? name + 1 : name);
  	  DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
  					 gen_rtx_SYMBOL_REF (Pmode, name));
! 	  set_mem_attributes (DECL_RTL (decl), decl, 1);
  
  	  /* Optionally set flags or add text to the name to record information
*************** output_constant_def (exp)
*** 3110,3117 ****
  		       gen_rtx_SYMBOL_REF (Pmode, desc->label));
  
!       RTX_UNCHANGING_P (desc->rtl) = 1;
!       if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
! 	MEM_SET_IN_STRUCT_P (desc->rtl, 1);
! 
        pop_obstacks ();
  
--- 3101,3105 ----
  		       gen_rtx_SYMBOL_REF (Pmode, desc->label));
  
!       set_mem_attributes (desc->rtl, exp, 1);
        pop_obstacks ();
  
*************** force_const_mem (mode, x)
*** 3669,3674 ****
  
    def = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, found));
! 
    RTX_UNCHANGING_P (def) = 1;
    /* Mark the symbol_ref as belonging to this constants pool.  */
    CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
--- 3657,3663 ----
  
    def = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, found));
!   set_mem_attributes (def, type_for_mode (mode, 0), 1);
    RTX_UNCHANGING_P (def) = 1;
+ 
    /* Mark the symbol_ref as belonging to this constants pool.  */
    CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
*** cp/Makefile.in	2000/05/28 02:58:13	1.85
--- cp/Makefile.in	2000/05/31 11:41:49
*************** lex.o : lex.c $(CXX_TREE_H) \
*** 257,261 ****
    $(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  \
    $(srcdir)/../except.h $(srcdir)/../toplev.h \
    $(srcdir)/../hash.h $(GGC_H) $(RTL_H) operators.def
--- 257,261 ----
    $(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 $(srcdir)/../expr.h \
    $(srcdir)/../except.h $(srcdir)/../toplev.h \
    $(srcdir)/../hash.h $(GGC_H) $(RTL_H) operators.def
*** cp/decl.c	2000/05/31 08:14:29	1.617
--- cp/decl.c	2000/05/31 11:42:52
*************** Boston, MA 02111-1307, USA.  */
*** 33,36 ****
--- 33,37 ----
  #include "tree.h"
  #include "rtl.h"
+ #include "expr.h"
  #include "flags.h"
  #include "cp-tree.h"
*************** init_decl_processing ()
*** 6456,6463 ****
--- 6457,6468 ----
    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;
*************** init_decl_processing ()
*** 6523,6526 ****
--- 6528,6532 ----
    wchar_array_type_node
      = build_array_type (wchar_type_node, array_domain_type);
+   record_component_aliases (wchar_array_type_node);
  
    if (flag_vtable_thunks)
*************** grokdeclarator (declarator, declspecs, d
*** 11588,11591 ****
--- 11594,11598 ----
  	      {
  		decl = build_decl (FIELD_DECL, declarator, type);
+ 		TREE_ADDRESSABLE (decl) = ! bitfield;
  		if (RIDBIT_SETP (RID_MUTABLE, specbits))
  		  {
*** cp/tree.c	2000/05/28 02:58:19	1.200
--- cp/tree.c	2000/05/31 11:43:22
*************** build_cplus_array_type_1 (elt_type, inde
*** 501,505 ****
      }
    else
!     t = build_array_type (elt_type, index_type);
  
    /* Push these needs up so that initialization takes place
--- 501,508 ----
      }
    else
!     {
!       t = build_array_type (elt_type, index_type);
!       record_component_aliases (t);
!     }
  
    /* Push these needs up so that initialization takes place


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]