diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/alias.c | 3 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 50 | ||||
-rw-r--r-- | gcc/expr.c | 49 | ||||
-rw-r--r-- | gcc/expr.h | 1 | ||||
-rw-r--r-- | gcc/gensupport.c | 14 | ||||
-rw-r--r-- | gcc/rtl.h | 22 |
7 files changed, 123 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c5c931..c65ba80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ Thu Oct 25 08:46:06 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + * alias.c (can_address_p): No longer static. + * emit-rtl.c (get_mem_attrs): New parameter, MODE; all callers changed. + Return 0 if all parameters are default values. + (set_mem_attributes): Set MEM_KEEP_ALIAS_SET_P. + (adjust_address_1): Try harder to compute a size. + * expr.c (expand_assignment, store_constructor): If can't address, + set MEM_KEEP_ALIAS_SET_P. + (store_constructor_field): Don't change set if MEM_KEEP_ALIAS_SET_P. + (store_field): Likewise. + (store_constructor): Simplify call to store_constructor_field. + * expr.h (can_address_p): New declaration. + * gensupport.c (gen_rtx_CONST_INT): New function. + * rtl.h (MEM_KEEP_ALIAS_SET_P): New macro. + (MEM_SIZE): Get size from mode, if not set and not BLKmode. + (MEM_COPY_ATTRIBUTES): Copy MEM_KEEP_ALIAS_SET_P. + * stmt.c (expand_end_case): Remove orig_minval and use tree_low_cst. 2001-10-24 Christopher Faylor <cgf@redhat.com> diff --git a/gcc/alias.c b/gcc/alias.c index 3de48b2..c754e6e 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -95,7 +95,6 @@ static rtx find_base_term PARAMS ((rtx)); static int base_alias_check PARAMS ((rtx, rtx, enum machine_mode, enum machine_mode)); static int handled_component_p PARAMS ((tree)); -static int can_address_p PARAMS ((tree)); static rtx find_base_value PARAMS ((rtx)); static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx)); static int insert_subset_children PARAMS ((splay_tree_node, void*)); @@ -426,7 +425,7 @@ handled_component_p (t) /* Return 1 if all the nested component references handled by get_inner_reference in T are such that we can address the object in T. */ -static int +int can_address_p (t) tree t; { diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 3142a41..008ceaa 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -192,7 +192,8 @@ static int mem_attrs_htab_eq PARAMS ((const void *, const void *)); static void mem_attrs_mark PARAMS ((const void *)); static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx, - rtx, unsigned int)); + rtx, unsigned int, + enum machine_mode)); /* Probability of the conditional branch currently proceeded by try_split. Set to -1 otherwise. */ @@ -269,19 +270,29 @@ mem_attrs_mark (x) } /* Allocate a new mem_attrs structure and insert it into the hash table if - one identical to it is not already in the table. */ + one identical to it is not already in the table. We are doing this for + MEM of mode MODE. */ static mem_attrs * -get_mem_attrs (alias, decl, offset, size, align) +get_mem_attrs (alias, decl, offset, size, align, mode) HOST_WIDE_INT alias; tree decl; rtx offset; rtx size; unsigned int align; + enum machine_mode mode; { mem_attrs attrs; void **slot; + /* If everything is the default, we can just return zero. */ + if (alias == 0 && decl == 0 && offset == 0 + && (size == 0 + || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size))) + && (align == 1 + || (mode != BLKmode && align == GET_MODE_ALIGNMENT (mode)))) + return 0; + attrs.alias = alias; attrs.decl = decl; attrs.offset = offset; @@ -1706,6 +1717,11 @@ set_mem_attributes (ref, t, objectp) || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == SAVE_EXPR) t = TREE_OPERAND (t, 0); + /* If this expression can't be addressed (e.g., it contains a reference + to a non-addressable field), show we don't change its alias set. */ + if (! can_address_p (t)) + MEM_KEEP_ALIAS_SET_P (ref) = 1; + /* If this is a decl, set the attributes of the MEM from it. */ if (DECL_P (t)) { @@ -1723,7 +1739,8 @@ set_mem_attributes (ref, t, objectp) } /* Now set the attributes we computed above. */ - MEM_ATTRS (ref) = get_mem_attrs (alias, decl, offset, size, align); + MEM_ATTRS (ref) + = get_mem_attrs (alias, decl, offset, size, align, GET_MODE (ref)); /* If this is already known to be a scalar or aggregate, we are done. */ if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref)) @@ -1751,7 +1768,8 @@ set_mem_alias_set (mem, set) #endif MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem), - MEM_SIZE (mem), MEM_ALIGN (mem)); + MEM_SIZE (mem), MEM_ALIGN (mem), + GET_MODE (mem)); } /* Set the alignment of MEM to ALIGN bits. */ @@ -1762,7 +1780,8 @@ set_mem_align (mem, align) unsigned int align; { MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_DECL (mem), - MEM_OFFSET (mem), MEM_SIZE (mem), align); + MEM_OFFSET (mem), MEM_SIZE (mem), align, + GET_MODE (mem)); } /* Return a memory reference like MEMREF, but with its mode changed to MODE @@ -1822,7 +1841,8 @@ change_address (memref, mode, addr) = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode)), (mmode == BLKmode ? 1 - : GET_MODE_ALIGNMENT (mmode) / BITS_PER_UNIT)); + : GET_MODE_ALIGNMENT (mmode) / BITS_PER_UNIT), + mmode); return new; } @@ -1841,6 +1861,7 @@ adjust_address_1 (memref, mode, offset, validate) rtx addr = XEXP (memref, 0); rtx new; rtx memoffset = MEM_OFFSET (memref); + rtx size = 0; unsigned int memalign = MEM_ALIGN (memref); /* If MEMREF is a LO_SUM and the offset is within the alignment of the @@ -1870,10 +1891,14 @@ adjust_address_1 (memref, mode, offset, validate) if (offset != 0) memalign = MIN (memalign, (offset & -offset) * BITS_PER_UNIT); - MEM_ATTRS (new) - = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), memoffset, - mode == BLKmode - ? 0 : GEN_INT (GET_MODE_SIZE (mode)), memalign); + /* We can compute the size in a number of ways. */ + if (mode != BLKmode) + size = GEN_INT (GET_MODE_SIZE (mode)); + else if (MEM_SIZE (memref)) + size = plus_constant (MEM_SIZE (memref), -offset); + + MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), + memoffset, size, memalign, GET_MODE (new)); /* At some point, we should validate that this offset is within the object, if all the appropriate values are known. */ @@ -1898,7 +1923,8 @@ offset_address (memref, offset, pow2) we don't know. */ MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), 0, 0, MIN (MEM_ALIGN (memref), - pow2 * BITS_PER_UNIT)); + pow2 * BITS_PER_UNIT), + GET_MODE (new)); return new; } @@ -3841,6 +3841,12 @@ expand_assignment (to, from, want_value, suggest_reg) } else { + if (! can_address_p (to)) + { + to_rtx = copy_rtx (to_rtx); + MEM_KEEP_ALIAS_SET_P (to_rtx) = 1; + } + result = store_field (to_rtx, bitsize, bitpos, mode1, from, (want_value /* Spurious cast for HPUX compiler. */ @@ -4479,7 +4485,9 @@ store_constructor_field (target, bitsize, bitpos, set, if required. */ if (bitpos != 0) align = MIN (align, (unsigned int) bitpos & - bitpos); - if (GET_CODE (target) == MEM) + + if (GET_CODE (target) == MEM && ! MEM_KEEP_ALIAS_SET_P (target) + && MEM_ALIAS_SET (target) != 0) set_mem_alias_set (target, alias_set); store_constructor (exp, target, align, cleared, bitsize / BITS_PER_UNIT); @@ -4681,12 +4689,17 @@ store_constructor (exp, target, align, cleared, size) mode = word_mode; } #endif + + if (GET_CODE (to_rtx) == MEM && !MEM_KEEP_ALIAS_SET_P (to_rtx) + && DECL_NONADDRESSABLE_P (field)) + { + to_rtx = copy_rtx (to_rtx); + MEM_KEEP_ALIAS_SET_P (to_rtx) = 1; + } + store_constructor_field (to_rtx, bitsize, bitpos, mode, TREE_VALUE (elt), type, align, cleared, - (DECL_NONADDRESSABLE_P (field) - && GET_CODE (to_rtx) == MEM) - ? MEM_ALIAS_SET (to_rtx) - : get_alias_set (TREE_TYPE (field))); + get_alias_set (TREE_TYPE (field))); } } else if (TREE_CODE (type) == ARRAY_TYPE) @@ -4824,11 +4837,18 @@ store_constructor (exp, target, align, cleared, size) for (; lo <= hi; lo++) { bitpos = lo * tree_low_cst (TYPE_SIZE (elttype), 0); + + if (GET_CODE (target) == MEM + && !MEM_KEEP_ALIAS_SET_P (target) + && TYPE_NONALIASED_COMPONENT (type)) + { + target = copy_rtx (target); + MEM_KEEP_ALIAS_SET_P (target) = 1; + } + store_constructor_field (target, bitsize, bitpos, mode, value, type, align, - cleared, - TYPE_NONALIASED_COMPONENT (type) - ? MEM_ALIAS_SET (target) : get_alias_set (elttype)); + cleared, get_alias_set (elttype)); } } else @@ -4916,11 +4936,15 @@ store_constructor (exp, target, align, cleared, size) else bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1)); + if (GET_CODE (target) == MEM && !MEM_KEEP_ALIAS_SET_P (target) + && TYPE_NONALIASED_COMPONENT (type)) + { + target = copy_rtx (target); + MEM_KEEP_ALIAS_SET_P (target) = 1; + } + store_constructor_field (target, bitsize, bitpos, mode, value, type, align, cleared, - TYPE_NONALIASED_COMPONENT (type) - && GET_CODE (target) == MEM - ? MEM_ALIAS_SET (target) : get_alias_set (elttype)); } @@ -5329,7 +5353,8 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, bitpos / BITS_PER_UNIT)); MEM_SET_IN_STRUCT_P (to_rtx, 1); - set_mem_alias_set (to_rtx, alias_set); + if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0) + set_mem_alias_set (to_rtx, alias_set); return store_expr (exp, to_rtx, value_mode != VOIDmode); } @@ -371,6 +371,7 @@ extern void record_base_value PARAMS ((unsigned int, rtx, int)); extern void record_alias_subset PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT)); extern HOST_WIDE_INT new_alias_set PARAMS ((void)); +extern int can_address_p PARAMS ((tree)); /* Functions from expr.c: */ diff --git a/gcc/gensupport.c b/gcc/gensupport.c index fcd73b2..83be3c7 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -92,6 +92,20 @@ message_with_line VPARAMS ((int lineno, const char *msg, ...)) VA_CLOSE (ap); } + +/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in + the gensupport programs. */ + +rtx +gen_rtx_CONST_INT (mode, arg) + enum machine_mode mode ATTRIBUTE_UNUSED; + HOST_WIDE_INT arg; +{ + rtx rt = rtx_alloc (CONST_INT); + + XWINT (rt, 0) = arg; + return rt; +} /* Queue PATTERN on LIST_TAIL. */ @@ -129,6 +129,7 @@ struct rtx_def /* 1 in an INSN if it can alter flow of control within this function. + MEM_KEEP_ALIAS_SET_P in a MEM. LINK_COST_ZERO in an INSN_LIST. */ unsigned int jump : 1; /* 1 in an INSN if it can call another function. @@ -855,6 +856,11 @@ extern unsigned int subreg_regno PARAMS ((rtx)); #define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR ((RTX), 5, ASM_OPERANDS) #define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT ((RTX), 6, ASM_OPERANDS) +/* For a MEM RTX, 1 if we should keep the alias set for this mem + unchanged when we access a component. Set to 1, or example, when we + are already in a non-addressable component of an aggregate. */ +#define MEM_KEEP_ALIAS_SET_P(RTX) ((RTX)->jump) + /* For a MEM rtx, 1 if it's a volatile reference. Also in an ASM_OPERANDS rtx. */ #define MEM_VOLATILE_P(RTX) ((RTX)->volatil) @@ -910,7 +916,10 @@ extern unsigned int subreg_regno PARAMS ((rtx)); /* For a MEM rtx, the size in bytes of the MEM, if known, as an RTX that is always a CONST_INT. */ -#define MEM_SIZE(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->size) +#define MEM_SIZE(RTX) \ +(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->size \ + : GET_MODE (RTX) != BLKmode ? GEN_INT (GET_MODE_SIZE (GET_MODE (RTX))) \ + : 0) /* For a MEM rtx, the alignment in bits. */ #define MEM_ALIGN(RTX) \ @@ -920,11 +929,12 @@ extern unsigned int subreg_regno PARAMS ((rtx)); /* 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), \ - RTX_UNCHANGING_P (LHS) = RTX_UNCHANGING_P (RHS), \ +#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), \ + RTX_UNCHANGING_P (LHS) = RTX_UNCHANGING_P (RHS), \ + MEM_KEEP_ALIAS_SET_P (LHS) = MEM_KEEP_ALIAS_SET_P (RHS), \ MEM_ATTRS (LHS) = MEM_ATTRS (RHS)) /* For a LABEL_REF, 1 means that this reference is to a label outside the |