From patchwork Fri Oct 17 14:48:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 400544 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 6D0D31400B2 for ; Sat, 18 Oct 2014 01:49:05 +1100 (AEDT) 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:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type:content-transfer-encoding; q=dns; s= default; b=D3fiD8kv2PmTHy8+iXZHhCbUrwL9DEY1p4uHt0BRWN0897o3a3Q7r AuxtHN6eme1P7uCSRAeOxXx3o+90UDE93JBXc4FyojBrDEVEoF7X836yrn9Ro/oL HtPWFinFrOUB8e17JQ322wASaHuYKdeh/ZsQeGmzkZ3WZs9rpokpJM= 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:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type:content-transfer-encoding; s=default; bh=jvOOR/PB5j+fNcuL/VpabaiXn1w=; b=PKmZ/j9rMcDThrS0pixwD0c/TovB JuDnEGrLdnLFVwxCbXPfvs/jBNNdVNn9S604rHgfcm0mVYR/Au2Tq4iuV9xSwB8i O8uF17+eKsnC20ndFGXj3/dxTMs0bSpSMsTp2W7EFPybA4Xsv5yhAyH1HdM1Nexb 2S0+zNo2/pMzswo= Received: (qmail 20986 invoked by alias); 17 Oct 2014 14:48:57 -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 20972 invoked by uid 89); 17 Oct 2014 14:48:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Oct 2014 14:48:53 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 17 Oct 2014 15:48:50 +0100 Received: from localhost ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 17 Oct 2014 15:48:49 +0100 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, vmakarov@redhat.com, ubizjak@gmail.com, markus@trippelsdorf.de, Ganesh.Gopalasubramanian@amd.com, richard.sandiford@arm.com Cc: vmakarov@redhat.com, ubizjak@gmail.com, markus@trippelsdorf.de, Ganesh.Gopalasubramanian@amd.com Subject: [PATCH 2/5] Add preferred_for_{size,speed} attributes References: <87bnpabvvx.fsf@e105548-lin.cambridge.arm.com> Date: Fri, 17 Oct 2014 15:48:49 +0100 In-Reply-To: <87bnpabvvx.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Fri, 17 Oct 2014 15:42:26 +0100") Message-ID: <87zjcuah0u.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: 114101715485000301 This is the main patch, to add new preferred_for_size and preferred_for_speed attributes that can be used to selectively disable alternatives when optimising for size or speed. As explained in the docs, the new attributes are just optimisation hints and it is possible that "size-only" alternatives will sometimes end up in a block that's optimised for speed, or vice versa. The patch deals with code that directly accesses the enabled_attributes mask and that ought to take size/speed choices into account. The next patch deals with indirect uses. Note that I'm not making reload support these attributes for hopefully obvious reasons :-) Richard gcc/ * doc/md.texi: Document "preferred_for_size" and "preferred_for_speed" attributes. * genattr.c (main): Handle "preferred_for_size" and "preferred_for_speed" in the same way as "enabled". * recog.h (bool_attr): New enum. (target_recog): Replace x_enabled_alternatives with x_bool_attr_masks. (get_preferred_alternatives, check_bool_attrs): Declare. * recog.c (have_bool_attr, get_bool_attr, get_bool_attr_mask_uncached) (get_bool_attr_mask, get_preferred_alternatives, check_bool_attrs): New functions. (get_enabled_alternatives): Use get_bool_attr_mask. * ira-costs.c (record_reg_classes): Use get_preferred_alternatives instead of recog_data.enabled_alternatives. * ira.c (ira_setup_alts): Likewise. * postreload.c (reload_cse_simplify_operands): Likewise. * config/i386/i386.c (ix86_legitimate_combined_insn): Likewise. * ira-lives.c (preferred_alternatives): New variable. (process_bb_node_lives): Set it. (check_and_make_def_conflict, make_early_clobber_and_input_conflicts) (single_reg_class, ira_implicitly_set_insn_hard_regs): Use it instead of recog_data.enabled_alternatives. * lra-int.h (lra_insn_recog_data): Replace enabled_alternatives to preferred_alternatives. * lra-constraints.c (process_alt_operands): Update accordingly. * lra.c (lra_set_insn_recog_data): Likewise. (lra_update_insn_recog_data): Assert check_bool_attrs. Index: gcc/doc/md.texi =================================================================== --- gcc/doc/md.texi 2014-10-07 13:12:12.227445290 +0100 +++ gcc/doc/md.texi 2014-10-17 15:47:34.349453560 +0100 @@ -1080,7 +1080,7 @@ the addressing register. * Class Preferences:: Constraints guide which hard register to put things in. * Modifiers:: More precise control over effects of constraints. * Machine Constraints:: Existing constraints for some particular machines. -* Disable Insn Alternatives:: Disable insn alternatives using the @code{enabled} attribute. +* Disable Insn Alternatives:: Disable insn alternatives using attributes. * Define Constraints:: How to define machine-specific constraints. * C Constraint Interface:: How to test constraints from C code. @end menu @@ -4006,42 +4006,49 @@ Unsigned constant valid for BccUI instru @subsection Disable insn alternatives using the @code{enabled} attribute @cindex enabled -The @code{enabled} insn attribute may be used to disable insn -alternatives that are not available for the current subtarget. -This is useful when adding new instructions to an existing pattern -which are only available for certain cpu architecture levels as -specified with the @code{-march=} option. - -If an insn alternative is disabled, then it will never be used. The -compiler treats the constraints for the disabled alternative as -unsatisfiable. +There are three insn attributes that may be used to selectively disable +instruction alternatives: -In order to make use of the @code{enabled} attribute a back end has to add -in the machine description files: +@table @code +@item enabled +Says whether an alternative is available on the current subtarget. -@enumerate -@item -A definition of the @code{enabled} insn attribute. The attribute is -defined as usual using the @code{define_attr} command. This -definition should be based on other insn attributes and/or target flags. -The attribute must be a static property of the subtarget; that is, it -must not depend on the current operands or any other dynamic context -(for example, the location of the insn within the body of a loop). - -The @code{enabled} attribute is a numeric attribute and should evaluate to -@code{(const_int 1)} for an enabled alternative and to -@code{(const_int 0)} otherwise. -@item -A definition of another insn attribute used to describe for what -reason an insn alternative might be available or -not. E.g. @code{cpu_facility} as in the example below. -@item -An assignment for the second attribute to each insn definition -combining instructions which are not all available under the same -circumstances. (Note: It obviously only makes sense for definitions -with more than one alternative. Otherwise the insn pattern should be -disabled or enabled using the insn condition.) -@end enumerate +@item preferred_for_size +Says whether an enabled alternative should be used in code that is +optimized for size. + +@item preferred_for_speed +Says whether an enabled alternative should be used in code that is +optimized for speed. +@end table + +All these attributes should use @code{(const_int 1)} to allow an alternative +or @code{(const_int 0)} to disallow it. The attributes must be a static +property of the subtarget; they cannot for example depend on the +current operands, on the current optimization level, on the location +of the insn within the body of a loop, on whether register allocation +has finished, or on the current compiler pass. + +The @code{enabled} attribute is a correctness property. It tells GCC to act +as though the disabled alternatives were never defined in the first place. +This is useful when adding new instructions to an existing pattern in +cases where the new instructions are only available for certain cpu +architecture levels (typically mapped to the @code{-march=} command-line +option). + +In contrast, the @code{preferred_for_size} and @code{preferred_for_speed} +attributes are strong optimization hints rather than correctness properties. +@code{preferred_for_size} tells GCC which alternatives to consider when +adding or modifying an instruction that GCC wants to optimize for size. +@code{preferred_for_speed} does the same thing for speed. Note that things +like code motion can lead to cases where code optimized for size uses +alternatives that are not preferred for size, and similarly for speed. + +Although @code{define_insn}s can in principle specify the @code{enabled} +attribute directly, it is often clearer to have subsiduary attributes +for each architectural feature of interest. The @code{define_insn}s +can then use these subsiduary attributes to say which alternatives +require which features. The example below does this for @code{cpu_facility}. E.g. the following two patterns could easily be merged using the @code{enabled} attribute: Index: gcc/genattr.c =================================================================== --- gcc/genattr.c 2014-09-18 11:40:31.195691182 +0100 +++ gcc/genattr.c 2014-10-17 15:47:34.353453512 +0100 @@ -338,7 +338,9 @@ main (int argc, char **argv) } /* Special-purpose attributes should be tested with if, not #ifdef. */ - const char * const special_attrs[] = { "length", "enabled", 0 }; + const char * const special_attrs[] = { "length", "enabled", + "preferred_for_size", + "preferred_for_speed", 0 }; for (const char * const *p = special_attrs; *p; p++) { printf ("#ifndef HAVE_ATTR_%s\n" @@ -355,9 +357,15 @@ main (int argc, char **argv) "#define insn_current_length hook_int_rtx_insn_unreachable\n" "#include \"insn-addr.h\"\n" "#endif\n" - "#if !HAVE_ATTR_enabled\n" "extern int hook_int_rtx_1 (rtx);\n" + "#if !HAVE_ATTR_enabled\n" "#define get_attr_enabled hook_int_rtx_1\n" + "#endif\n" + "#if !HAVE_ATTR_preferred_for_size\n" + "#define get_attr_preferred_for_size hook_int_rtx_1\n" + "#endif\n" + "#if !HAVE_ATTR_preferred_for_speed\n" + "#define get_attr_preferred_for_speed hook_int_rtx_1\n" "#endif\n"); /* Output flag masks for use by reorg. Index: gcc/recog.h =================================================================== --- gcc/recog.h 2014-10-17 15:44:50.219398486 +0100 +++ gcc/recog.h 2014-10-17 15:47:34.357453465 +0100 @@ -389,10 +389,19 @@ struct insn_data_d #ifndef GENERATOR_FILE #include "insn-codes.h" +/* An enum of boolean attributes that may only depend on the current + subtarget, not on things like operands or compiler phase. */ +enum bool_attr { + BA_ENABLED, + BA_PREFERRED_FOR_SPEED, + BA_PREFERRED_FOR_SIZE, + BA_LAST = BA_PREFERRED_FOR_SIZE +}; + /* Target-dependent globals. */ struct target_recog { bool x_initialized; - alternative_mask x_enabled_alternatives[LAST_INSN_CODE]; + alternative_mask x_bool_attr_masks[LAST_INSN_CODE][BA_LAST + 1]; operand_alternative *x_op_alt[LAST_INSN_CODE]; }; @@ -404,6 +413,8 @@ #define this_target_recog (&default_targ #endif alternative_mask get_enabled_alternatives (rtx_insn *); +alternative_mask get_preferred_alternatives (rtx_insn *); +bool check_bool_attrs (rtx_insn *); void recog_init (); #endif Index: gcc/recog.c =================================================================== --- gcc/recog.c 2014-10-17 15:44:50.219398486 +0100 +++ gcc/recog.c 2014-10-17 15:47:34.357453465 +0100 @@ -2055,25 +2055,46 @@ mode_dependent_address_p (rtx addr, addr return targetm.mode_dependent_address_p (addr, addrspace); } -/* Return the mask of operand alternatives that are allowed for INSN. - This mask depends only on INSN and on the current target; it does not - depend on things like the values of operands. */ +/* Return true if boolean attribute ATTR is supported. */ -alternative_mask -get_enabled_alternatives (rtx_insn *insn) +static bool +have_bool_attr (bool_attr attr) { - /* Quick exit for asms and for targets that don't use the "enabled" - attribute. */ - int code = INSN_CODE (insn); - if (code < 0 || !HAVE_ATTR_enabled) - return ALL_ALTERNATIVES; + switch (attr) + { + case BA_ENABLED: + return HAVE_ATTR_enabled; + case BA_PREFERRED_FOR_SIZE: + return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size; + case BA_PREFERRED_FOR_SPEED: + return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed; + } + gcc_unreachable (); +} - /* Calling get_attr_enabled can be expensive, so cache the mask - for speed. */ - if (this_target_recog->x_enabled_alternatives[code]) - return this_target_recog->x_enabled_alternatives[code]; +/* Return the value of ATTR for instruction INSN. */ - /* Temporarily install enough information for get_attr_enabled to assume +static bool +get_bool_attr (rtx_insn *insn, bool_attr attr) +{ + switch (attr) + { + case BA_ENABLED: + return get_attr_enabled (insn); + case BA_PREFERRED_FOR_SIZE: + return get_attr_enabled (insn) && get_attr_preferred_for_size (insn); + case BA_PREFERRED_FOR_SPEED: + return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn); + } + gcc_unreachable (); +} + +/* Like get_bool_attr_mask, but don't use the cache. */ + +static alternative_mask +get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr) +{ + /* Temporarily install enough information for get_attr_ to assume that the insn operands are already cached. As above, the attribute mustn't depend on the values of operands, so we don't provide their real values here. */ @@ -2081,20 +2102,81 @@ get_enabled_alternatives (rtx_insn *insn int old_alternative = which_alternative; recog_data.insn = insn; - alternative_mask enabled = ALL_ALTERNATIVES; - int n_alternatives = insn_data[code].n_alternatives; + alternative_mask mask = ALL_ALTERNATIVES; + int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives; for (int i = 0; i < n_alternatives; i++) { which_alternative = i; - if (!get_attr_enabled (insn)) - enabled &= ~ALTERNATIVE_BIT (i); + if (!get_bool_attr (insn, attr)) + mask &= ~ALTERNATIVE_BIT (i); } recog_data.insn = old_insn; which_alternative = old_alternative; + return mask; +} + +/* Return the mask of operand alternatives that are allowed for INSN + by boolean attribute ATTR. This mask depends only on INSN and on + the current target; it does not depend on things like the values of + operands. */ + +static alternative_mask +get_bool_attr_mask (rtx_insn *insn, bool_attr attr) +{ + /* Quick exit for asms and for targets that don't use these attributes. */ + int code = INSN_CODE (insn); + if (code < 0 || !have_bool_attr (attr)) + return ALL_ALTERNATIVES; - this_target_recog->x_enabled_alternatives[code] = enabled; - return enabled; + /* Calling get_attr_ can be expensive, so cache the mask + for speed. */ + if (!this_target_recog->x_bool_attr_masks[code][attr]) + this_target_recog->x_bool_attr_masks[code][attr] + = get_bool_attr_mask_uncached (insn, attr); + return this_target_recog->x_bool_attr_masks[code][attr]; +} + +/* Return the set of alternatives of INSN that are allowed by the current + target. */ + +alternative_mask +get_enabled_alternatives (rtx_insn *insn) +{ + return get_bool_attr_mask (insn, BA_ENABLED); +} + +/* Return the set of alternatives of INSN that are allowed by the current + target and are preferred for the current size/speed optimization + choice. */ + +alternative_mask +get_preferred_alternatives (rtx_insn *insn) +{ + if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))) + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED); + else + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); +} + +/* Assert that the cached boolean attributes for INSN are still accurate. + The backend is required to define these attributes in a way that only + depends on the current target (rather than operands, compiler phase, + etc.). */ + +bool +check_bool_attrs (rtx_insn *insn) +{ + int code = INSN_CODE (insn); + if (code >= 0) + for (int i = 0; i <= BA_LAST; ++i) + { + enum bool_attr attr = (enum bool_attr) i; + if (this_target_recog->x_bool_attr_masks[code][attr]) + gcc_assert (this_target_recog->x_bool_attr_masks[code][attr] + == get_bool_attr_mask_uncached (insn, attr)); + } + return true; } /* Like extract_insn, but save insn extracted and don't extract again, when @@ -4043,8 +4125,8 @@ recog_init () this_target_recog->x_initialized = true; return; } - memset (this_target_recog->x_enabled_alternatives, 0, - sizeof (this_target_recog->x_enabled_alternatives)); + memset (this_target_recog->x_bool_attr_masks, 0, + sizeof (this_target_recog->x_bool_attr_masks)); for (int i = 0; i < LAST_INSN_CODE; ++i) if (this_target_recog->x_op_alt[i]) { Index: gcc/ira-costs.c =================================================================== --- gcc/ira-costs.c 2014-10-03 11:09:08.000000000 +0100 +++ gcc/ira-costs.c 2014-10-17 15:47:34.353453512 +0100 @@ -416,6 +416,7 @@ record_reg_classes (int n_alts, int n_op /* Process each alternative, each time minimizing an operand's cost with the cost for each operand in that alternative. */ + alternative_mask preferred = get_preferred_alternatives (insn); for (alt = 0; alt < n_alts; alt++) { enum reg_class classes[MAX_RECOG_OPERANDS]; @@ -424,7 +425,7 @@ record_reg_classes (int n_alts, int n_op int alt_fail = 0; int alt_cost = 0, op_cost_add; - if (!TEST_BIT (recog_data.enabled_alternatives, alt)) + if (!TEST_BIT (preferred, alt)) { for (i = 0; i < recog_data.n_operands; i++) constraints[i] = skip_alternative (constraints[i]); Index: gcc/ira.c =================================================================== --- gcc/ira.c 2014-10-13 08:02:40.953138663 +0100 +++ gcc/ira.c 2014-10-17 15:47:34.353453512 +0100 @@ -1783,6 +1783,7 @@ ira_setup_alts (rtx_insn *insn, HARD_REG int commutative = -1; extract_insn (insn); + alternative_mask preferred = get_preferred_alternatives (insn); CLEAR_HARD_REG_SET (alts); insn_constraints.release (); insn_constraints.safe_grow_cleared (recog_data.n_operands @@ -1812,7 +1813,7 @@ ira_setup_alts (rtx_insn *insn, HARD_REG } for (nalt = 0; nalt < recog_data.n_alternatives; nalt++) { - if (!TEST_BIT (recog_data.enabled_alternatives, nalt) + if (!TEST_BIT (preferred, nalt) || TEST_HARD_REG_BIT (alts, nalt)) continue; Index: gcc/postreload.c =================================================================== --- gcc/postreload.c 2014-10-17 15:44:50.219398486 +0100 +++ gcc/postreload.c 2014-10-17 15:47:34.357453465 +0100 @@ -493,6 +493,7 @@ reload_cse_simplify_operands (rtx_insn * SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc)); } + alternative_mask preferred = get_preferred_alternatives (insn); for (i = 0; i < recog_data.n_operands; i++) { enum machine_mode mode; @@ -566,7 +567,7 @@ reload_cse_simplify_operands (rtx_insn * alternative yet and the operand being replaced is not a cheap CONST_INT. */ if (op_alt_regno[i][j] == -1 - && TEST_BIT (recog_data.enabled_alternatives, j) + && TEST_BIT (preferred, j) && reg_fits_class_p (testreg, rclass, 0, mode) && (!CONST_INT_P (recog_data.operand[i]) || (set_src_cost (recog_data.operand[i], Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2014-10-13 08:02:40.985138241 +0100 +++ gcc/config/i386/i386.c 2014-10-17 15:47:34.349453560 +0100 @@ -5901,10 +5901,10 @@ ix86_legitimate_combined_insn (rtx_insn /* Operand has no constraints, anything is OK. */ win = !n_alternatives; - alternative_mask enabled = recog_data.enabled_alternatives; + alternative_mask preferred = get_preferred_alternatives (insn); for (j = 0; j < n_alternatives; j++, op_alt += n_operands) { - if (!TEST_BIT (enabled, j)) + if (!TEST_BIT (preferred, j)) continue; if (op_alt[i].anything_ok || (op_alt[i].matches != -1 Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c 2014-09-22 08:36:24.217790119 +0100 +++ gcc/ira-lives.c 2014-10-17 15:47:34.353453512 +0100 @@ -85,6 +85,10 @@ Software Foundation; either version 3, o /* The number of last call at which given allocno was saved. */ static int *allocno_saved_at_call; +/* The value of get_preferred_alternatives for the current instruction, + supplemental to recog_data. */ +static alternative_mask preferred_alternatives; + /* Record the birth of hard register REGNO, updating hard_regs_live and hard reg conflict information for living allocnos. */ static void @@ -641,10 +645,9 @@ check_and_make_def_conflict (int alt, in /* If there's any alternative that allows USE to match DEF, do not record a conflict. If that causes us to create an invalid instruction due to the earlyclobber, reload must fix it up. */ - alternative_mask enabled = recog_data.enabled_alternatives; for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++) { - if (!TEST_BIT (enabled, alt1)) + if (!TEST_BIT (preferred_alternatives, alt1)) continue; const operand_alternative *op_alt1 = &recog_op_alt[alt1 * n_operands]; @@ -692,10 +695,9 @@ make_early_clobber_and_input_conflicts ( int n_alternatives = recog_data.n_alternatives; int n_operands = recog_data.n_operands; - alternative_mask enabled = recog_data.enabled_alternatives; const operand_alternative *op_alt = recog_op_alt; for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands) - if (TEST_BIT (enabled, alt)) + if (TEST_BIT (preferred_alternatives, alt)) for (def = 0; def < n_operands; def++) { def_cl = NO_REGS; @@ -762,13 +764,13 @@ single_reg_class (const char *constraint enum constraint_num cn; cl = NO_REGS; - alternative_mask enabled = recog_data.enabled_alternatives; + alternative_mask preferred = preferred_alternatives; for (; (c = *constraints); constraints += CONSTRAINT_LEN (c, constraints)) if (c == '#') - enabled &= ~ALTERNATIVE_BIT (0); + preferred &= ~ALTERNATIVE_BIT (0); else if (c == ',') - enabled >>= 1; - else if (enabled & 1) + preferred >>= 1; + else if (preferred & 1) switch (c) { case 'g': @@ -851,13 +853,13 @@ ira_implicitly_set_insn_hard_regs (HARD_ mode = (GET_CODE (op) == SCRATCH ? GET_MODE (op) : PSEUDO_REGNO_MODE (regno)); cl = NO_REGS; - alternative_mask enabled = recog_data.enabled_alternatives; + alternative_mask preferred = preferred_alternatives; for (; (c = *p); p += CONSTRAINT_LEN (c, p)) if (c == '#') - enabled &= ~ALTERNATIVE_BIT (0); + preferred &= ~ALTERNATIVE_BIT (0); else if (c == ',') - enabled >>= 1; - else if (enabled & 1) + preferred >>= 1; + else if (preferred & 1) { cl = reg_class_for_constraint (lookup_constraint (p)); if (cl != NO_REGS) @@ -1174,6 +1176,7 @@ process_bb_node_lives (ira_loop_tree_nod } extract_insn (insn); + preferred_alternatives = get_preferred_alternatives (insn); preprocess_constraints (insn); process_single_reg_class_operands (false, freq); Index: gcc/lra-int.h =================================================================== --- gcc/lra-int.h 2014-09-22 08:36:23.153803537 +0100 +++ gcc/lra-int.h 2014-10-17 15:47:34.357453465 +0100 @@ -233,8 +233,8 @@ struct lra_insn_recog_data value can be NULL or points to array of the hard register numbers ending with a negative value. */ int *arg_hard_regs; - /* Alternative enabled for the insn. NULL for debug insns. */ - alternative_mask enabled_alternatives; + /* Cached value of get_preferred_alternatives. */ + alternative_mask preferred_alternatives; /* The following member value is always NULL for a debug insn. */ struct lra_insn_reg *regs; }; Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2014-10-03 11:05:47.521106593 +0100 +++ gcc/lra-constraints.c 2014-10-17 15:47:34.357453465 +0100 @@ -1680,14 +1680,14 @@ process_alt_operands (int only_alternati together, the second alternatives go together, etc. First loop over alternatives. */ - alternative_mask enabled = curr_id->enabled_alternatives; + alternative_mask preferred = curr_id->preferred_alternatives; if (only_alternative >= 0) - enabled &= ALTERNATIVE_BIT (only_alternative); + preferred &= ALTERNATIVE_BIT (only_alternative); for (nalt = 0; nalt < n_alternatives; nalt++) { /* Loop over operands for one constraint alternative. */ - if (!TEST_BIT (enabled, nalt)) + if (!TEST_BIT (preferred, nalt)) continue; overall = losers = reject = reload_nregs = reload_sum = 0; Index: gcc/lra.c =================================================================== --- gcc/lra.c 2014-10-17 15:44:50.219398486 +0100 +++ gcc/lra.c 2014-10-17 15:47:34.357453465 +0100 @@ -917,7 +917,7 @@ lra_set_insn_recog_data (rtx_insn *insn) data->insn_static_data = &debug_insn_static_data; data->dup_loc = NULL; data->arg_hard_regs = NULL; - data->enabled_alternatives = ALL_ALTERNATIVES; + data->preferred_alternatives = ALL_ALTERNATIVES; data->operand_loc = XNEWVEC (rtx *, 1); data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn); return data; @@ -977,7 +977,7 @@ lra_set_insn_recog_data (rtx_insn *insn) = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT : OP_IN); - data->enabled_alternatives = ALL_ALTERNATIVES; + data->preferred_alternatives = ALL_ALTERNATIVES; if (nop > 0) { operand_alternative *op_alt = XCNEWVEC (operand_alternative, @@ -1011,7 +1011,7 @@ lra_set_insn_recog_data (rtx_insn *insn) memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *)); } data->dup_loc = locs; - data->enabled_alternatives = get_enabled_alternatives (insn); + data->preferred_alternatives = get_preferred_alternatives (insn); const operand_alternative *op_alt = preprocess_insn_constraints (icode); if (!insn_static_data->operand_alternative) setup_operand_alternative (data, op_alt); @@ -1202,27 +1202,7 @@ lra_update_insn_recog_data (rtx_insn *in n = insn_static_data->n_dups; if (n != 0) memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *)); -#if HAVE_ATTR_enabled -#ifdef ENABLE_CHECKING - { - int i; - alternative_mask enabled; - - n = insn_static_data->n_alternatives; - enabled = data->enabled_alternatives; - lra_assert (n >= 0); - /* Cache the insn to prevent extract_insn call from - get_attr_enabled. */ - recog_data.insn = insn; - for (i = 0; i < n; i++) - { - which_alternative = i; - lra_assert (TEST_BIT (enabled, i) - == (bool) get_attr_enabled (insn)); - } - } -#endif -#endif + lra_assert (check_bool_attrs (insn)); } return data; }