This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Aliasing patches
- To: gcc-patches at gcc dot gnu dot org
- Subject: Aliasing patches
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- Date: Wed, 31 May 00 15:04:03 EDT
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