From patchwork Sun Jul 17 14:18:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 105058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E5087B6F68 for ; Mon, 18 Jul 2011 00:19:20 +1000 (EST) Received: (qmail 23816 invoked by alias); 17 Jul 2011 14:19:19 -0000 Received: (qmail 23802 invoked by uid 22791); 17 Jul 2011 14:19:17 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SARE_OBFU_PART_ORE, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-ww0-f51.google.com (HELO mail-ww0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 17 Jul 2011 14:19:02 +0000 Received: by wwj26 with SMTP id 26so2272373wwj.8 for ; Sun, 17 Jul 2011 07:19:01 -0700 (PDT) Received: by 10.227.174.194 with SMTP id u2mr4774197wbz.83.1310912341205; Sun, 17 Jul 2011 07:19:01 -0700 (PDT) Received: from localhost (rsandifo.gotadsl.co.uk [82.133.89.107]) by mx.google.com with ESMTPS id fn12sm2658598wbb.21.2011.07.17.07.18.59 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 17 Jul 2011 07:19:00 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: [1/5] Add a mode_mem_attrs array References: <87k4bhuh62.fsf@firetop.home> Date: Sun, 17 Jul 2011 15:18:58 +0100 In-Reply-To: <87k4bhuh62.fsf@firetop.home> (Richard Sandiford's message of "Sun, 17 Jul 2011 15:15:49 +0100") Message-ID: <87fwm5uh0t.fsf@firetop.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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.) 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. */