On Sun, Jul 17, 2011 at 4:18 PM, Richard Sandiford
<[email protected]> wrote:
> This patch adds an array, mode_mem_attrs, that gives the default attributes
> for a given mode. The defaults depend on STRICT_ALIGNMENT, which on rs6000
> and v850 depends on command-line flags, and which could therefore in
> principle be changed by __attribute__((optimize)). Although we might not
> cope with that properly in all cases, it does mean that the new array
> rightly belongs in target_rtl; it shouldn't be a run-time-invariant global.
>
> The patch also adds a get_mem_attrs function that always returns
> the memory's attributes. This meant renaming a local emit-rtl.c
> function out of the way. (The next patch changes that function
> anyway; I just split it out for "ease" of review.)
Looks reasonable - but I'd call find_mem_attrs lookup_mem_attrs instead.
Thanks,
Richard.
> Richard
>
>
> gcc/
> * rtl.h (MEM_ALIAS_SET, MEM_EXPR, MEM_OFFSET, MEM_ADDR_SPACE)
> (MEM_SIZE, MEM_ALIGN): Redefine in terms of get_mem_attrs.
> Provide a dummy definition of MEM_ADDR_SPACE for generators.
> (target_rtl): Add x_mode_mem_attrs.
> (mode_mem_attrs): New macro.
> (get_mem_attrs): New function.
> * emit-rtl.c (get_mem_attrs): Rename to...
> (find_mem_attrs): ...this.
> (set_mem_attributes_minus_bitpos, set_mem_alias_set)
> (set_mem_addr_space, set_mem_align, set_mem_expr, set_mem_offset)
> (set_mem_size, change_address, adjust_address_1, offset_address)
> (widen_memory_access, get_spill_slot_decl, set_mem_attrs_for_spill):
> Update accordingly.
> (init_emit_regs): Initialize mode_mem_attrs.
>
> Index: gcc/rtl.h
> ===================================================================
> --- gcc/rtl.h 2011-07-17 10:03:05.000000000 +0100
> +++ gcc/rtl.h 2011-07-17 10:03:07.000000000 +0100
> @@ -1289,39 +1289,36 @@ #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1
> in the block and provide defaults if none specified. */
> #define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
>
> +#ifndef GENERATOR_FILE
> /* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
> set, and may alias anything. Otherwise, the MEM can only alias
> MEMs in a conflicting alias set. This value is set in a
> language-dependent manner in the front-end, and should not be
> altered in the back-end. These set numbers are tested with
> alias_sets_conflict_p. */
> -#define MEM_ALIAS_SET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS
> (RTX)->alias)
> +#define MEM_ALIAS_SET(RTX) (get_mem_attrs (RTX)->alias)
>
> /* For a MEM rtx, the decl it is known to refer to, if it is known to
> refer to part of a DECL. It may also be a COMPONENT_REF. */
> -#define MEM_EXPR(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->expr)
> +#define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
>
> /* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a
> RTX that is always a CONST_INT. */
> -#define MEM_OFFSET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->offset)
> +#define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
>
> /* For a MEM rtx, the address space. */
> -#define MEM_ADDR_SPACE(RTX) (MEM_ATTRS (RTX) == 0 ? ADDR_SPACE_GENERIC \
> - : MEM_ATTRS
> (RTX)->addrspace)
> +#define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace)
>
> /* 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 ? MEM_ATTRS (RTX)->size \
> - : GET_MODE (RTX) != BLKmode ? GEN_INT (GET_MODE_SIZE (GET_MODE (RTX)))
> \
> - : 0)
> +#define MEM_SIZE(RTX) (get_mem_attrs (RTX)->size)
>
> /* For a MEM rtx, the alignment in bits. We can use the alignment of the
> mode as a default when STRICT_ALIGNMENT, but not if not. */
> -#define MEM_ALIGN(RTX) \
> -(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align \
> - : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode \
> - ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
> +#define MEM_ALIGN(RTX) (get_mem_attrs (RTX)->align)
> +#else
> +#define MEM_ADDR_SPACE(RTX) ADDR_SPACE_GENERIC
> +#endif
>
> /* For a REG rtx, the decl it is known to refer to, if it is known to
> refer to part of a DECL. */
> @@ -2120,6 +2117,9 @@ struct GTY(()) target_rtl {
> /* Static hunks of RTL used by the aliasing code; these are treated
> as persistent to avoid unnecessary RTL allocations. */
> rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
> +
> + /* The default memory attributes for each mode. */
> + struct mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
> };
>
> extern GTY(()) struct target_rtl default_target_rtl;
> @@ -2137,6 +2137,8 @@ #define return_address_pointer_rtx \
> (this_target_rtl->x_return_address_pointer_rtx)
> #define top_of_stack \
> (this_target_rtl->x_top_of_stack)
> +#define mode_mem_attrs \
> + (this_target_rtl->x_mode_mem_attrs)
>
> /* Standard pieces of rtx, to be substituted directly into things. */
> #define pc_rtx (global_rtl[GR_PC])
> @@ -2151,6 +2153,20 @@ #define frame_pointer_rtx (global_
> #define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER])
> #define arg_pointer_rtx (global_rtl[GR_ARG_POINTER])
>
> +#ifndef GENERATOR_FILE
> +/* Return the attributes of a MEM rtx. */
> +static inline struct mem_attrs *
> +get_mem_attrs (const_rtx x)
> +{
> + struct mem_attrs *attrs;
> +
> + attrs = MEM_ATTRS (x);
> + if (!attrs)
> + attrs = mode_mem_attrs[(int) GET_MODE (x)];
> + return attrs;
> +}
> +#endif
> +
> /* Include the RTL generation functions. */
>
> #ifndef GENERATOR_FILE
> Index: gcc/emit-rtl.c
> ===================================================================
> --- gcc/emit-rtl.c 2011-07-17 10:03:05.000000000 +0100
> +++ gcc/emit-rtl.c 2011-07-17 10:06:49.000000000 +0100
> @@ -157,8 +157,6 @@ static int const_fixed_htab_eq (const vo
> static rtx lookup_const_fixed (rtx);
> static hashval_t mem_attrs_htab_hash (const void *);
> static int mem_attrs_htab_eq (const void *, const void *);
> -static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned
> int,
> - addr_space_t, enum machine_mode);
> static hashval_t reg_attrs_htab_hash (const void *);
> static int reg_attrs_htab_eq (const void *, const void *);
> static reg_attrs *get_reg_attrs (tree, int);
> @@ -286,8 +284,9 @@ mem_attrs_htab_eq (const void *x, const
> MEM of mode MODE. */
>
> static mem_attrs *
> -get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
> - unsigned int align, addr_space_t addrspace, enum machine_mode
> mode)
> +find_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
> + unsigned int align, addr_space_t addrspace,
> + enum machine_mode mode)
> {
> mem_attrs attrs;
> void **slot;
> @@ -1833,8 +1832,8 @@ set_mem_attributes_minus_bitpos (rtx ref
>
> /* Now set the attributes we computed above. */
> MEM_ATTRS (ref)
> - = get_mem_attrs (alias, expr, offset, size, align,
> - TYPE_ADDR_SPACE (type), GET_MODE (ref));
> + = find_mem_attrs (alias, expr, offset, size, align,
> + TYPE_ADDR_SPACE (type), 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))
> @@ -1862,9 +1861,9 @@ set_mem_alias_set (rtx mem, alias_set_ty
> /* If the new and old alias sets don't conflict, something is wrong. */
> gcc_checking_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
>
> - MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
> - MEM_SIZE (mem), MEM_ALIGN (mem),
> - MEM_ADDR_SPACE (mem), GET_MODE (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
> + MEM_SIZE (mem), MEM_ALIGN (mem),
> + MEM_ADDR_SPACE (mem), GET_MODE (mem));
> }
>
> /* Set the address space of MEM to ADDRSPACE (target-defined). */
> @@ -1872,9 +1871,9 @@ set_mem_alias_set (rtx mem, alias_set_ty
> void
> set_mem_addr_space (rtx mem, addr_space_t addrspace)
> {
> - MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> - MEM_OFFSET (mem), MEM_SIZE (mem),
> - MEM_ALIGN (mem), addrspace, GET_MODE
> (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> + MEM_OFFSET (mem), MEM_SIZE (mem),
> + MEM_ALIGN (mem), addrspace, GET_MODE
> (mem));
> }
>
> /* Set the alignment of MEM to ALIGN bits. */
> @@ -1882,9 +1881,9 @@ set_mem_addr_space (rtx mem, addr_space_
> void
> set_mem_align (rtx mem, unsigned int align)
> {
> - MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> - MEM_OFFSET (mem), MEM_SIZE (mem), align,
> - MEM_ADDR_SPACE (mem), GET_MODE (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> + MEM_OFFSET (mem), MEM_SIZE (mem), align,
> + MEM_ADDR_SPACE (mem), GET_MODE (mem));
> }
>
> /* Set the expr for MEM to EXPR. */
> @@ -1893,9 +1892,9 @@ set_mem_align (rtx mem, unsigned int ali
> set_mem_expr (rtx mem, tree expr)
> {
> MEM_ATTRS (mem)
> - = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
> - MEM_SIZE (mem), MEM_ALIGN (mem),
> - MEM_ADDR_SPACE (mem), GET_MODE (mem));
> + = find_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
> + MEM_SIZE (mem), MEM_ALIGN (mem),
> + MEM_ADDR_SPACE (mem), GET_MODE (mem));
> }
>
> /* Set the offset of MEM to OFFSET. */
> @@ -1903,9 +1902,9 @@ set_mem_expr (rtx mem, tree expr)
> void
> set_mem_offset (rtx mem, rtx offset)
> {
> - MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> - offset, MEM_SIZE (mem), MEM_ALIGN (mem),
> - MEM_ADDR_SPACE (mem), GET_MODE (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> + offset, MEM_SIZE (mem), MEM_ALIGN (mem),
> + MEM_ADDR_SPACE (mem), GET_MODE (mem));
> }
>
> /* Set the size of MEM to SIZE. */
> @@ -1913,9 +1912,9 @@ set_mem_offset (rtx mem, rtx offset)
> void
> set_mem_size (rtx mem, rtx size)
> {
> - MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> - MEM_OFFSET (mem), size, MEM_ALIGN (mem),
> - MEM_ADDR_SPACE (mem), GET_MODE (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
> + MEM_OFFSET (mem), size, MEM_ALIGN (mem),
> + MEM_ADDR_SPACE (mem), GET_MODE (mem));
> }
>
> /* Return a memory reference like MEMREF, but with its mode changed to MODE
> @@ -1984,8 +1983,8 @@ change_address (rtx memref, enum machine
> }
>
> MEM_ATTRS (new_rtx)
> - = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align,
> - MEM_ADDR_SPACE (memref), mmode);
> + = find_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align,
> + MEM_ADDR_SPACE (memref), mmode);
>
> return new_rtx;
> }
> @@ -2069,9 +2068,10 @@ adjust_address_1 (rtx memref, enum machi
> else if (MEM_SIZE (memref))
> size = plus_constant (MEM_SIZE (memref), -offset);
>
> - MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR
> (memref),
> - memoffset, size, memalign, as,
> - GET_MODE (new_rtx));
> + MEM_ATTRS (new_rtx) = find_mem_attrs (MEM_ALIAS_SET (memref),
> + MEM_EXPR (memref),
> + memoffset, size, memalign, as,
> + GET_MODE (new_rtx));
>
> /* At some point, we should validate that this offset is within the object,
> if all the appropriate values are known. */
> @@ -2129,9 +2129,9 @@ offset_address (rtx memref, rtx offset,
> /* Update the alignment to reflect the offset. Reset the offset, which
> we don't know. */
> MEM_ATTRS (new_rtx)
> - = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
> - MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
> - as, GET_MODE (new_rtx));
> + = find_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
> + MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
> + as, GET_MODE (new_rtx));
> return new_rtx;
> }
>
> @@ -2234,9 +2234,9 @@ widen_memory_access (rtx memref, enum ma
> /* The widened memory may alias other stuff, so zap the alias set. */
> /* ??? Maybe use get_alias_set on any remaining expression. */
>
> - MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
> - MEM_ALIGN (new_rtx),
> - MEM_ADDR_SPACE (new_rtx), mode);
> + MEM_ATTRS (new_rtx) = find_mem_attrs (0, expr, memoffset, GEN_INT (size),
> + MEM_ALIGN (new_rtx),
> + MEM_ADDR_SPACE (new_rtx), mode);
>
> return new_rtx;
> }
> @@ -2262,8 +2262,8 @@ get_spill_slot_decl (bool force_build_p)
>
> rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
> MEM_NOTRAP_P (rd) = 1;
> - MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx,
> - NULL_RTX, 0, ADDR_SPACE_GENERIC, BLKmode);
> + MEM_ATTRS (rd) = find_mem_attrs (new_alias_set (), d, const0_rtx,
> + NULL_RTX, 0, ADDR_SPACE_GENERIC, BLKmode);
> SET_DECL_RTL (d, rd);
>
> return d;
> @@ -2294,9 +2294,9 @@ set_mem_attrs_for_spill (rtx mem)
> && CONST_INT_P (XEXP (addr, 1)))
> offset = XEXP (addr, 1);
>
> - MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset,
> - MEM_SIZE (mem), MEM_ALIGN (mem),
> - ADDR_SPACE_GENERIC, GET_MODE (mem));
> + MEM_ATTRS (mem) = find_mem_attrs (alias, expr, offset,
> + MEM_SIZE (mem), MEM_ALIGN (mem),
> + ADDR_SPACE_GENERIC, GET_MODE (mem));
> MEM_NOTRAP_P (mem) = 1;
> }
>
> @@ -5442,6 +5442,8 @@ gen_rtx_CONST_VECTOR (enum machine_mode
> init_emit_regs (void)
> {
> int i;
> + enum machine_mode mode;
> + mem_attrs *attrs;
>
> /* Reset register attributes */
> htab_empty (reg_attrs_htab);
> @@ -5483,6 +5485,21 @@ init_emit_regs (void)
> pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
> else
> pic_offset_table_rtx = NULL_RTX;
> +
> + for (i = 0; i < (int) MAX_MACHINE_MODE; i++)
> + {
> + mode = (enum machine_mode) i;
> + attrs = ggc_alloc_cleared_mem_attrs ();
> + attrs->align = BITS_PER_UNIT;
> + attrs->addrspace = ADDR_SPACE_GENERIC;
> + if (mode != BLKmode)
> + {
> + attrs->size = GEN_INT (GET_MODE_SIZE (mode));
> + if (STRICT_ALIGNMENT)
> + attrs->align = GET_MODE_ALIGNMENT (mode);
> + }
> + mode_mem_attrs[i] = attrs;
> + }
> }
>
> /* Create some permanent unique rtl objects shared between all functions. */
>