From patchwork Mon May 18 18:19:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 473541 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D633714012C for ; Tue, 19 May 2015 04:19:49 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=wInCcZbY; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=bhQ jTC09jI/1SYOldEIdYpAwAfO+8Q/3riM08xIRGw/jHD6LgW791H++ZgE7mk8kxeZ F9h3MHG1sAjUlRe3564M2/ciQJ6ca9EQs2bEB++x8XSAthpVELzxmqemvsKHBK1m kI8HGjalrWFMMtS5YgJYm5pgvZ1HlPIgqTzwO5YQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=default; bh=yvYrPK1ly x2woZQj1h+PF7XHUZo=; b=wInCcZbYWKMLZuqXncRkZINZeGzDh22XPqHj0jS34 RJe86x5QbuTFMeb/Q+RVjMD4kB8DwDtD2uMs9oF9d0qzwYigIpA4apEJvjSiewG6 1rRpylW7VM4VOgXuleBjTjYIYQY2/CyqopYERyxUYgbCXjYixI2vkaiM6d+CWJus f0= Received: (qmail 77631 invoked by alias); 18 May 2015 18:19:38 -0000 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 Received: (qmail 77622 invoked by uid 89); 18 May 2015 18:19:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL, BAYES_50, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 May 2015 18:19:35 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by uk-mta-7.uk.mimecast.lan; Mon, 18 May 2015 19:19:32 +0100 Received: from localhost ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 18 May 2015 19:19:32 +0100 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [4/9] Add a dedicated rtx union member for REGs References: <87oalhu59s.fsf@e105548-lin.cambridge.arm.com> Date: Mon, 18 May 2015 19:19:32 +0100 In-Reply-To: <87oalhu59s.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Mon, 18 May 2015 19:09:19 +0100") Message-ID: <87617pu4sr.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-MC-Unique: kPFV5IeuRI-coiF3amj54g-1 This patch replaces the current REG "i0" format with a dedicated structure, so that we can make use of the extra 32 bits in the "i" field. Of the places that iterate on formats and do something for 'i's, most already handled REGs specially before the format walk and so don't need to check for 'r'. Otherwise it's mostly just a case of adding dummy 'r' cases in order avoid the default gcc_unreachable () (in cases where we do the same for 'i'). The main exceptions are the cselib.c and lra-constraints.c changes. final.c:leaf_renumber_regs_insn handled REGs specially but then went on to do a no-op walk of the format. I just added an early exit instead of an empty 'r' case. gcc/ * rtl.def (REG): Change format to "r". * rtl.h (rtunion): Remove rt_reg. (reg_info): New structure. (rtx_def): Add reg field to main union. (X0REGATTR): Delete. (REG_CHECK): New macro. (SET_REGNO_RAW, rhs_regno, REG_ATTRS): Use it. * rtl.c (rtx_format): Document "r". (rtx_code_size): Handle REG specially. * gengenrtl.c (special_format): Return true for formats that include 'r'. * gengtype.c (adjust_field_rtx_def): Handle 'r' fields. Deal with REG_ATTRS after the field loop. * emit-rtl.c (gen_raw_REG): Call rtx_alloc_stat directly. * expmed.c (init_expmed): Call gen_raw_REG instead of gen_rtx_raw_REG. * expr.c (init_expr_target): Likewise. * regcprop.c (maybe_mode_change): Likewise. * varasm.c (make_decl_rtl): Likewise. * final.c (leaf_renumber_regs_insn): Return early after handling REGs. * genemit.c (gen_exp): Handle 'r' fields. * genpeep.c (match_rtx): Likewise. * gensupport.c (subst_pattern_match): Likewise. (get_alternatives_number, collect_insn_data, alter_predicate_for_insn) (alter_constraints, subst_dup): Likewise. * read-rtl.c (read_rtx_code): Likewise. * print-rtl.c (print_rtx): Likewise. * genrecog.c (find_operand, find_matching_operand): Likewise. (validate_pattern, match_pattern_2): Likewise. (parameter::UINT, rtx_test::REGNO_FIELD): New enum values. (rtx_test::regno_field): New function. (operator ==, safe_to_hoist_p, transition_parameter_type) (parameter_type_string, print_parameter_value) (print_nonbool_test, print_test): Handle new enum values. * cselib.c (rtx_equal_for_cselib_1): Handle REG specially. * lra-constraints.c (operands_match_p): Likewise. Index: gcc/rtl.def =================================================================== --- gcc/rtl.def 2015-05-18 07:53:15.014808321 +0100 +++ gcc/rtl.def 2015-05-18 07:53:15.010808427 +0100 @@ -381,7 +381,7 @@ DEF_RTL_EXPR(PC, "pc", "", RTX_OBJ) points to a reg_attrs structure. This rtx needs to have as many (or more) fields as a MEM, since we can change REG rtx's into MEMs during reload. */ -DEF_RTL_EXPR(REG, "reg", "i0", RTX_OBJ) +DEF_RTL_EXPR(REG, "reg", "r", RTX_OBJ) /* A scratch register. This represents a register used only within a single insn. It will be replaced by a REG during register allocation Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2015-05-18 07:53:15.014808321 +0100 +++ gcc/rtl.h 2015-05-18 07:53:15.014808321 +0100 @@ -201,11 +201,21 @@ struct GTY((for_user)) reg_attrs { tree rt_tree; basic_block rt_bb; mem_attrs *rt_mem; - reg_attrs *rt_reg; struct constant_descriptor_rtx *rt_constant; struct dw_cfi_node *rt_cfi; }; +/* Describes the properties of a REG. */ +struct GTY(()) reg_info { + /* The value of REGNO. */ + unsigned int regno; + + unsigned int unused : 32; + + /* The value of REG_ATTRS. */ + reg_attrs *attrs; +}; + /* This structure remembers the position of a SYMBOL_REF within an object_block structure. A SYMBOL_REF only provides this information if SYMBOL_REF_HAS_BLOCK_INFO_P is true. */ @@ -395,6 +405,7 @@ struct GTY((desc("0"), tag("0"), union u { rtunion fld[1]; HOST_WIDE_INT hwint[1]; + struct reg_info reg; struct block_symbol block_sym; struct real_value rv; struct fixed_value fv; @@ -1070,6 +1081,13 @@ #define XCNMPFV(RTX, C, M) __extension__ __LINE__, __FUNCTION__); \ &_rtx->u.fv; }) +#define REG_CHECK(RTX) __extension__ \ +({ __typeof (RTX) const _rtx = (RTX); \ + if (GET_CODE (_rtx) != REG) \ + rtl_check_failed_code1 (_rtx, REG, __FILE__, __LINE__, \ + __FUNCTION__); \ + &_rtx->u.reg; }) + #define BLOCK_SYMBOL_CHECK(RTX) __extension__ \ ({ __typeof (RTX) const _symbol = (RTX); \ const unsigned int flags = SYMBOL_REF_FLAGS (_symbol); \ @@ -1124,6 +1142,7 @@ #define XCMWINT(RTX, N, C, M) ((RTX) #define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) #define XCNMPRV(RTX, C, M) (&(RTX)->u.rv) #define XCNMPFV(RTX, C, M) (&(RTX)->u.fv) +#define REG_CHECK(RTX) (&(RTX)->u.reg) #define BLOCK_SYMBOL_CHECK(RTX) (&(RTX)->u.block_sym) #define HWIVEC_CHECK(RTX,C) (&(RTX)->u.hwiv) @@ -1248,7 +1267,6 @@ #define X0BBDEF(RTX, N) (RTL_CHECK1 ( #define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags) #define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib) #define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rt_mem) -#define X0REGATTR(RTX, N) (RTL_CHECKC1 (RTX, N, REG).rt_reg) #define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant) /* Access a '0' field with any type. */ @@ -1694,7 +1712,7 @@ #define LABEL_REF_LABEL(LABREF) XCEXP (L be used on RHS. Use SET_REGNO to change the value. */ #define REGNO(RTX) (rhs_regno(RTX)) #define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N)) -#define SET_REGNO_RAW(RTX, N) (XCUINT (RTX, 0, REG) = N) +#define SET_REGNO_RAW(RTX, N) (REG_CHECK (RTX)->regno = N) /* Return the number of consecutive registers in a REG. This is always 1 for pseudo registers and is determined by HARD_REGNO_NREGS for @@ -1714,7 +1732,7 @@ #define ORIGINAL_REGNO(RTX) \ static inline unsigned int rhs_regno (const_rtx x) { - return XCUINT (x, 0, REG); + return REG_CHECK (x)->regno; } @@ -2271,7 +2289,7 @@ #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1 /* The register attribute block. We provide access macros for each value in the block and provide defaults if none specified. */ -#define REG_ATTRS(RTX) X0REGATTR (RTX, 1) +#define REG_ATTRS(RTX) (REG_CHECK (RTX)->attrs) #ifndef GENERATOR_FILE /* For a MEM rtx, the alias set. If 0, this MEM is not in any alias Index: gcc/rtl.c =================================================================== --- gcc/rtl.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/rtl.c 2015-05-18 07:53:15.010808427 +0100 @@ -89,7 +89,8 @@ const char * const rtx_format[NUM_RTX_CO prints the uid of the insn. "b" is a pointer to a bitmap header. "B" is a basic block pointer. - "t" is a tree pointer. */ + "t" is a tree pointer. + "r" a register. */ #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , #include "rtl.def" /* rtl expressions are defined here */ @@ -112,6 +113,8 @@ #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, (((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \ || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT) \ ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ + : (ENUM) == REG \ + ? RTX_HDR_SIZE + sizeof (reg_info) \ : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)), #include "rtl.def" Index: gcc/gengenrtl.c =================================================================== --- gcc/gengenrtl.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/gengenrtl.c 2015-05-18 07:53:15.006808572 +0100 @@ -113,7 +113,8 @@ special_format (const char *fmt) return (strchr (fmt, '*') != 0 || strchr (fmt, 'V') != 0 || strchr (fmt, 'S') != 0 - || strchr (fmt, 'n') != 0); + || strchr (fmt, 'n') != 0 + || strchr (fmt, 'r') != 0); } /* Return true if CODE always has VOIDmode. */ Index: gcc/gengtype.c =================================================================== --- gcc/gengtype.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/gengtype.c 2015-05-18 07:53:15.010808427 +0100 @@ -1241,6 +1241,7 @@ adjust_field_rtx_def (type_p t, options_ case 'i': case 'n': case 'w': + case 'r': t = scalar_tp; subname = "rt_int"; break; @@ -1268,8 +1269,6 @@ adjust_field_rtx_def (type_p t, options_ t = scalar_tp, subname = "rt_int"; else if (i == DEBUG_EXPR && aindex == 0) t = tree_tp, subname = "rt_tree"; - else if (i == REG && aindex == 1) - t = reg_attrs_tp, subname = "rt_reg"; else if (i == SYMBOL_REF && aindex == 1) t = symbol_union_tp, subname = ""; else if (i == JUMP_TABLE_DATA && aindex >= 4) @@ -1344,6 +1343,9 @@ adjust_field_rtx_def (type_p t, options_ "CONSTANT_POOL_ADDRESS_P (&%0)"); } + if (i == REG) + subfields = create_field (subfields, reg_attrs_tp, "reg.attrs"); + if (i == SYMBOL_REF) { /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/emit-rtl.c 2015-05-18 07:53:15.006808572 +0100 @@ -437,7 +437,10 @@ gen_blockage (void) rtx gen_raw_REG (machine_mode mode, int regno) { - rtx x = gen_rtx_raw_REG (mode, regno); + rtx x = rtx_alloc_stat (REG PASS_MEM_STAT); + PUT_MODE (x, mode); + SET_REGNO_RAW (x, regno); + REG_ATTRS (x) = NULL; ORIGINAL_REGNO (x) = regno; return x; } Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/expmed.c 2015-05-18 07:53:15.006808572 +0100 @@ -260,7 +260,7 @@ init_expmed (void) } /* Avoid using hard regs in ways which may be unsupported. */ - all.reg = gen_rtx_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1); + all.reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1); all.plus = gen_rtx_PLUS (mode, all.reg, all.reg); all.neg = gen_rtx_NEG (mode, all.reg); all.mult = gen_rtx_MULT (mode, all.reg, all.reg); Index: gcc/expr.c =================================================================== --- gcc/expr.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/expr.c 2015-05-18 07:53:15.006808572 +0100 @@ -258,7 +258,7 @@ init_expr_target (void) } } - mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000)); + mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER)); for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/regcprop.c 2015-05-18 07:53:15.010808427 +0100 @@ -410,7 +410,7 @@ maybe_mode_change (machine_mode orig_mod return NULL_RTX; if (orig_mode == new_mode) - return gen_rtx_raw_REG (new_mode, regno); + return gen_raw_REG (new_mode, regno); else if (mode_change_ok (orig_mode, new_mode, regno)) { int copy_nregs = hard_regno_nregs[copy_regno][copy_mode]; @@ -426,7 +426,7 @@ maybe_mode_change (machine_mode orig_mod + (BYTES_BIG_ENDIAN ? byteoffset : 0)); regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); if (HARD_REGNO_MODE_OK (regno, new_mode)) - return gen_rtx_raw_REG (new_mode, regno); + return gen_raw_REG (new_mode, regno); } return NULL_RTX; } Index: gcc/varasm.c =================================================================== --- gcc/varasm.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/varasm.c 2015-05-18 07:53:15.014808321 +0100 @@ -1429,7 +1429,7 @@ make_decl_rtl (tree decl) confused with that register and be eliminated. This usage is somewhat suspect... */ - SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number)); + SET_DECL_RTL (decl, gen_raw_REG (mode, reg_number)); ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number; REG_USERVAR_P (DECL_RTL (decl)) = 1; Index: gcc/final.c =================================================================== --- gcc/final.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/final.c 2015-05-18 07:53:15.006808572 +0100 @@ -4438,6 +4438,7 @@ leaf_renumber_regs_insn (rtx in_rtx) df_set_regs_ever_live (newreg, true); SET_REGNO (in_rtx, newreg); in_rtx->used = 1; + return; } if (INSN_P (in_rtx)) Index: gcc/genemit.c =================================================================== --- gcc/genemit.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/genemit.c 2015-05-18 07:53:15.006808572 +0100 @@ -240,6 +240,10 @@ gen_exp (rtx x, enum rtx_code subroutine printf ("%u", XINT (x, i)); break; + case 'r': + printf ("%u", REGNO (x)); + break; + case 's': printf ("\"%s\"", XSTR (x, i)); break; Index: gcc/genpeep.c =================================================================== --- gcc/genpeep.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/genpeep.c 2015-05-18 07:53:15.010808427 +0100 @@ -276,6 +276,12 @@ match_rtx (rtx x, struct link *path, int printf (" if (XINT (x, %d) != %d) goto L%d;\n", i, XINT (x, i), fail_label); } + else if (fmt[i] == 'r') + { + gcc_assert (i == 0); + printf (" if (REGNO (x) != %d) goto L%d;\n", + REGNO (x), fail_label); + } else if (fmt[i] == 'w') { /* Make sure that at run time `x' is the RTX we want to test. */ Index: gcc/gensupport.c =================================================================== --- gcc/gensupport.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/gensupport.c 2015-05-18 07:53:15.010808427 +0100 @@ -880,7 +880,7 @@ subst_pattern_match (rtx x, rtx pt, int switch (fmt[i]) { - case 'i': case 'w': case 's': + case 'i': case 'r': case 'w': case 's': continue; case 'e': case 'u': @@ -1045,7 +1045,7 @@ get_alternatives_number (rtx pattern, in return 0; break; - case 'i': case 'w': case '0': case 's': case 'S': case 'T': + case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': break; default: @@ -1104,7 +1104,7 @@ collect_insn_data (rtx pattern, int *pal collect_insn_data (XVECEXP (pattern, i, j), palt, pmax); break; - case 'i': case 'w': case '0': case 's': case 'S': case 'T': + case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': break; default: @@ -1188,7 +1188,7 @@ alter_predicate_for_insn (rtx pattern, i } break; - case 'i': case 'w': case '0': case 's': + case 'i': case 'r': case 'w': case '0': case 's': break; default: @@ -1246,7 +1246,7 @@ alter_constraints (rtx pattern, int n_du } break; - case 'i': case 'w': case '0': case 's': + case 'i': case 'r': case 'w': case '0': case 's': break; default: @@ -2184,7 +2184,7 @@ subst_dup (rtx pattern, int n_alt, int n n_alt, n_subst_alt); break; - case 'i': case 'w': case '0': case 's': case 'S': case 'T': + case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': break; default: Index: gcc/read-rtl.c =================================================================== --- gcc/read-rtl.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/read-rtl.c 2015-05-18 07:53:15.010808427 +0100 @@ -1346,6 +1346,13 @@ read_rtx_code (const char *code_name) name.string); break; + case 'r': + read_name (&name); + validate_const_int (name.string); + SET_REGNO_RAW (return_rtx, atoi (name.string)); + REG_ATTRS (return_rtx) = NULL; + break; + default: gcc_unreachable (); } Index: gcc/print-rtl.c =================================================================== --- gcc/print-rtl.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/print-rtl.c 2015-05-18 07:53:15.010808427 +0100 @@ -462,55 +462,12 @@ print_rtx (const_rtx in_rtx) int value = XINT (in_rtx, i); const char *name; -#ifndef GENERATOR_FILE - if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER) - fprintf (outfile, " %d %s", value, reg_names[value]); - else if (REG_P (in_rtx) - && (unsigned) value <= LAST_VIRTUAL_REGISTER) - { - if (value == VIRTUAL_INCOMING_ARGS_REGNUM) - fprintf (outfile, " %d virtual-incoming-args", value); - else if (value == VIRTUAL_STACK_VARS_REGNUM) - fprintf (outfile, " %d virtual-stack-vars", value); - else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM) - fprintf (outfile, " %d virtual-stack-dynamic", value); - else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM) - fprintf (outfile, " %d virtual-outgoing-args", value); - else if (value == VIRTUAL_CFA_REGNUM) - fprintf (outfile, " %d virtual-cfa", value); - else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM) - fprintf (outfile, " %d virtual-preferred-stack-boundary", - value); - else - fprintf (outfile, " %d virtual-reg-%d", value, - value-FIRST_VIRTUAL_REGISTER); - } - else -#endif - if (flag_dump_unnumbered - && (is_insn || NOTE_P (in_rtx))) + if (flag_dump_unnumbered + && (is_insn || NOTE_P (in_rtx))) fputc ('#', outfile); else fprintf (outfile, " %d", value); -#ifndef GENERATOR_FILE - if (REG_P (in_rtx) && REG_ATTRS (in_rtx)) - { - fputs (" [", outfile); - if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx)) - fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx)); - if (REG_EXPR (in_rtx)) - print_mem_expr (outfile, REG_EXPR (in_rtx)); - - if (REG_OFFSET (in_rtx)) - fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, - REG_OFFSET (in_rtx)); - fputs (" ]", outfile); - } - if (REG_P (in_rtx) && REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx)) - fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx)); -#endif - if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i) && XINT (in_rtx, i) >= 0 && (name = get_insn_name (XINT (in_rtx, i))) != NULL) @@ -519,6 +476,58 @@ print_rtx (const_rtx in_rtx) } break; + case 'r': + { + unsigned int regno = REGNO (in_rtx); +#ifndef GENERATOR_FILE + if (regno < FIRST_PSEUDO_REGISTER) + fprintf (outfile, " %d %s", regno, reg_names[regno]); + else if (regno <= LAST_VIRTUAL_REGISTER) + { + if (regno == VIRTUAL_INCOMING_ARGS_REGNUM) + fprintf (outfile, " %d virtual-incoming-args", regno); + else if (regno == VIRTUAL_STACK_VARS_REGNUM) + fprintf (outfile, " %d virtual-stack-vars", regno); + else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM) + fprintf (outfile, " %d virtual-stack-dynamic", regno); + else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM) + fprintf (outfile, " %d virtual-outgoing-args", regno); + else if (regno == VIRTUAL_CFA_REGNUM) + fprintf (outfile, " %d virtual-cfa", regno); + else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM) + fprintf (outfile, " %d virtual-preferred-stack-boundary", + regno); + else + fprintf (outfile, " %d virtual-reg-%d", regno, + regno-FIRST_VIRTUAL_REGISTER); + } + else +#endif + if (flag_dump_unnumbered && is_insn) + fputc ('#', outfile); + else + fprintf (outfile, " %d", regno); + +#ifndef GENERATOR_FILE + if (REG_ATTRS (in_rtx)) + { + fputs (" [", outfile); + if (regno != ORIGINAL_REGNO (in_rtx)) + fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx)); + if (REG_EXPR (in_rtx)) + print_mem_expr (outfile, REG_EXPR (in_rtx)); + + if (REG_OFFSET (in_rtx)) + fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, + REG_OFFSET (in_rtx)); + fputs (" ]", outfile); + } + if (regno != ORIGINAL_REGNO (in_rtx)) + fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx)); +#endif + break; + } + /* Print NOTE_INSN names rather than integer codes. */ case 'n': Index: gcc/genrecog.c =================================================================== --- gcc/genrecog.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/genrecog.c 2015-05-18 07:53:15.010808427 +0100 @@ -396,7 +396,7 @@ find_operand (rtx pattern, int n, rtx st return r; break; - case 'i': case 'w': case '0': case 's': + case 'i': case 'r': case 'w': case '0': case 's': break; default: @@ -447,7 +447,7 @@ find_matching_operand (rtx pattern, int return r; break; - case 'i': case 'w': case '0': case 's': + case 'i': case 'r': case 'w': case '0': case 's': break; default: @@ -747,7 +747,7 @@ validate_pattern (rtx pattern, rtx insn, validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0); break; - case 'i': case 'w': case '0': case 's': + case 'i': case 'r': case 'w': case '0': case 's': break; default: @@ -967,6 +967,9 @@ struct parameter /* An int parameter. */ INT, + /* An unsigned int parameter. */ + UINT, + /* A HOST_WIDE_INT parameter. */ WIDE_INT }; @@ -1063,6 +1066,9 @@ struct rtx_test /* Check GET_MODE (X) == LABEL. */ MODE, + /* Check REGNO (X) == LABEL. */ + REGNO_FIELD, + /* Check XINT (X, u.opno) == LABEL. */ INT_FIELD, @@ -1142,6 +1148,7 @@ struct rtx_test static rtx_test code (position *); static rtx_test mode (position *); + static rtx_test regno_field (position *); static rtx_test int_field (position *, int); static rtx_test wide_int_field (position *, int); static rtx_test veclen (position *); @@ -1180,6 +1187,13 @@ rtx_test::mode (position *pos) } rtx_test +rtx_test::regno_field (position *pos) +{ + rtx_test res (pos, rtx_test::REGNO_FIELD); + return res; +} + +rtx_test rtx_test::int_field (position *pos, int opno) { rtx_test res (pos, rtx_test::INT_FIELD); @@ -1299,6 +1313,7 @@ operator == (const rtx_test &a, const rt { case rtx_test::CODE: case rtx_test::MODE: + case rtx_test::REGNO_FIELD: case rtx_test::VECLEN: case rtx_test::HAVE_NUM_CLOBBERS: return true; @@ -1753,6 +1768,7 @@ safe_to_hoist_p (decision *d, const rtx_ } gcc_unreachable (); + case rtx_test::REGNO_FIELD: case rtx_test::INT_FIELD: case rtx_test::WIDE_INT_FIELD: case rtx_test::VECLEN: @@ -1959,6 +1975,9 @@ transition_parameter_type (rtx_test::kin case rtx_test::MODE: return parameter::MODE; + case rtx_test::REGNO_FIELD: + return parameter::UINT; + case rtx_test::INT_FIELD: case rtx_test::VECLEN: case rtx_test::PATTERN: @@ -3970,6 +3989,13 @@ match_pattern_2 (state *s, rtx top_patte XINT (pattern, i), false); break; + case 'r': + /* Make sure that REGNO (X) has the right value. */ + gcc_assert (i == 0); + s = add_decision (s, rtx_test::regno_field (pos), + REGNO (pattern), false); + break; + case 'w': /* Make sure that XWINT (X, I) has the right value. */ s = add_decision (s, rtx_test::wide_int_field (pos, i), @@ -4232,6 +4258,9 @@ parameter_type_string (parameter::type_e case parameter::INT: return "int"; + case parameter::UINT: + return "unsigned int"; + case parameter::WIDE_INT: return "HOST_WIDE_INT"; } @@ -4451,6 +4480,10 @@ print_parameter_value (const parameter & printf ("%d", (int) param.value); break; + case parameter::UINT: + printf ("%u", (unsigned int) param.value); + break; + case parameter::WIDE_INT: print_host_wide_int (param.value); break; @@ -4499,6 +4532,12 @@ print_nonbool_test (output_state *os, co printf (", %d)", test.u.opno); break; + case rtx_test::REGNO_FIELD: + printf ("REGNO ("); + print_test_rtx (os, test); + printf (")"); + break; + case rtx_test::WIDE_INT_FIELD: printf ("XWINT ("); print_test_rtx (os, test); @@ -4572,6 +4611,7 @@ print_test (output_state *os, const rtx_ case rtx_test::CODE: case rtx_test::MODE: case rtx_test::VECLEN: + case rtx_test::REGNO_FIELD: case rtx_test::INT_FIELD: case rtx_test::WIDE_INT_FIELD: case rtx_test::PATTERN: Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/cselib.c 2015-05-18 07:53:15.002808721 +0100 @@ -976,6 +976,9 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, ma case LABEL_REF: return LABEL_REF_LABEL (x) == LABEL_REF_LABEL (y); + case REG: + return REGNO (x) == REGNO (y); + case MEM: /* We have to compare any autoinc operations in the addresses using this MEM's mode. */ Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2015-05-18 07:53:15.014808321 +0100 +++ gcc/lra-constraints.c 2015-05-18 07:53:15.010808427 +0100 @@ -749,6 +749,9 @@ operands_match_p (rtx x, rtx y, int y_ha slow: + if (code == REG && REG_P (y)) + return REGNO (x) == REGNO (y); + if (code == REG && GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)) && x == SUBREG_REG (y)) return true;