From patchwork Wed Nov 25 12:26:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 548514 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 5DC861401DE for ; Wed, 25 Nov 2015 23:26:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=l47M2MK5; 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=k2C gYTfYHGp5El0CeaY1SMpsTRSsG+dapAFAmxUgA0Yhh4xwAlDTWaG7k2eZn8R89fE rBZtudAfyBWlJxKPpZ9NYhVEcSGeAZ4WqbbtwBTKzQp1O/UMxuZfdF+prWZutYgb rd8ZFhBj5XvwongRXdbbAOsMnOtDYT5BGFKGZ5vc= 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=PPdP1EgMZ k4+kct1thX6v1IIPwU=; b=l47M2MK5c3Ud3t/D56CrrmxydCF7ZBtb0HGBsulIt D7fqjRKR0K7nPTNZ6P+64OVYFxHGtfb3EOzlCAV3KYxnh5EFF6YmCTv/RlHL7LCk JY2LXMBzADCYOtwYLmJ/9hX1f0HG5Ja/nUPV844GosJ5V6Icw4mnTetdUqGHpVdb es= Received: (qmail 113932 invoked by alias); 25 Nov 2015 12:26:22 -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 113910 invoked by uid 89); 25 Nov 2015 12:26:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL, BAYES_50, SPF_PASS autolearn=ham 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; Wed, 25 Nov 2015 12:26:16 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-21-uAby-SdLQySz0kRBD4ASiw-1; Wed, 25 Nov 2015 12:26:09 +0000 Received: from localhost ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 25 Nov 2015 12:26:08 +0000 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PR68432 04/22] Remove global which_alternative References: <874mgajmo9.fsf@e105548-lin.cambridge.arm.com> Date: Wed, 25 Nov 2015 12:26:08 +0000 In-Reply-To: <874mgajmo9.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Wed, 25 Nov 2015 12:20:06 +0000") Message-ID: <87k2p6i7tr.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: uAby-SdLQySz0kRBD4ASiw-1 Later patches in the series add a new form of attribute that takes the attribute number as an argument, rather than it being stored in the global which_alternative variable. Having both a local alternative number and a global alternative number is likely to cause confusion. This patch therefore gets rid of the global variable. The main change is to get functions like constrain_operands to return the number of the matching alternative, or -1 if none. The cached versions still use static state, but at least that state is now local to recog.c and has a different name. Tested as described in the covering note. gcc/ * recog.h (extract_constrain_insn): Return an int. (extract_constrain_insn_cached): Likewise. (which_alternative): Delete. (which_op_alt): Delete in favor of... (get_opt_alt): ...this new function. (insn_output_fn): Add an alternative number as argument. * recog.c (which_alternative): Delete in favor of... (cached_which_alternative): ...this. (get_bool_attr_mask_uncached): Update accordingly. (extract_insn): Likewise. (check_asm_operands): Check the return value of constrain_operands directly. (insn_invalid_p): Update check for whether constrain_operands was successful. (extract_constrain_insn): Return the matching alternative. (extract_constrain_insn_cached): Likewise. (constrain_operands_cached): Return the alternative number, or -1 on failure. Use cached_which_alternative as the cache. (preprocess_insn_constraints): Update comment. (constrain_operands): Return the alternative number on success and -1 on failure. Don't assign to which_alternative. * genattrtab.c (write_attr_case): Make which_alternative a local variable, set from the result of extract_constrain_insn_cached. * genoutput.c (process_template): Make the output functions take which_alternative as argument. * output.h (get_insn_template): Pass the alternative number too. Put the instruction argument first. * final.c (get_insn_template): Likewise. Pass the alternative number down to the output function. (final_scan_insn): Update call accordingly. (output_asm_name): Use constrain_operands_cached instead of which_alternative. * postreload.c (reload_cse_simplify_operands): Use the return value of extract_constrain_insn instead of which_alternative. * config/s390/predicates.md (execute_operation): Likewise. * config/m68k/m68k.md (*movdf_internal, *addsi3_5200): Likewise. * regrename.c (hide_operands): Take the alternative number as argument. Replace use of which_op_alt with get_op_alt. (record_out_operands): Likewise. (build_def_use): Update accordingly. Also replace which_op_alt with get_op_alt here. * caller-save.c (reg_save_code): Update check for whether constrain_operands was successful. * ira.c (setup_prohibited_mode_move_regs): Likewise. * postreload-gcse.c (eliminate_partially_redundant_load): Likewise. * ree.c (combine_reaching_defs): Likewise. * reload.c (can_reload_into): Likewise. * reload1.c (reload): Likewise. (reload_as_needed): Likewise. (gen_reload_chain_without_interm_reg_p): Likewise. (emit_input_reload_insns): Likewise. (emit_insn_if_valid_for_reload): Likewise. (inc_for_reload): Likewise. * reorg.c (fill_slots_from_thread): Likewise. * config/pa/pa.c (pa_can_combine_p): Likewise. * config/rl78/rl78.c (insn_ok_now): Likewise. * config/alpha/alpha.c (alpha_end_function): Update call to get_insn_template. * config/rs6000/rs6000.c (rs6000_final_prescan_insn): Likewise. * reg-stack.c (check_asm_stack_operands): Replace use of which_op_alt with get_op_alt. (subst_asm_stack_regs): Likewise. * regcprop.c (copyprop_hardreg_forward_1): Likewise. * sel-sched.c (get_reg_class): Likewise. * config/arm/arm.c (note_invalid_constants): Likewise. * config/i386/i386.c (ix86_attr_length_address_default): Remove use of global which_alternative. (ix86_mitigate_rop): Replace use of which_op_alt with get_op_alt. * config/sparc/sparc-protos.h (output_v8plus_shift) (output_v8plus_mult): Add which_alternative argument. * config/sparc/sparc.c (output_v8plus_shift, output_v8plus_mult): Likewise. * config/sparc/sparc.md (muldi3_v8plus, umulxhi_v8plus, xmulx_v8plus) (xmulxhi_v8plus, ashldi3_v8plus, ashrdi3_v8plus, lshrdi3_v8plus): Update accordingly. * config/vax/vax-protos.h (vax_output_int_add): Add an alternative number as argument. (vax_output_int_subtract): Likewise. * config/vax/vax.c (vax_output_int_add): Update accordingly. (vax_output_int_subtract): Likewise. Update calls to get_insn_template. * config/vax/vax.md (add3, adcdi3, adddi3_old, sbcdi3) (subdi3_old): Update accordingly. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 084d079..5a648c1 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -142,9 +142,9 @@ reg_save_code (int reg, machine_mode mode) if (ok) { extract_insn (saveinsn); - ok = constrain_operands (1, get_enabled_alternatives (saveinsn)); + ok = constrain_operands (1, get_enabled_alternatives (saveinsn)) >= 0; extract_insn (restinsn); - ok &= constrain_operands (1, get_enabled_alternatives (restinsn)); + ok &= constrain_operands (1, get_enabled_alternatives (restinsn)) >= 0; } if (! ok) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 4cfae82..a85c836 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -8335,7 +8335,7 @@ alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED) if (!INSN_P (insn)) insn = prev_active_insn (insn); if (insn && CALL_P (insn)) - output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL); + output_asm_insn (get_insn_template (NULL, CODE_FOR_nop, 0), NULL); #if TARGET_ABI_OPEN_VMS /* Write the linkage entries. */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e0cdc20..ae3bfee 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -17105,7 +17105,7 @@ note_invalid_constants (rtx_insn *insn, HOST_WIDE_INT address, int do_pushes) { int opno; - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); if (recog_data.n_alternatives == 0) return; @@ -17114,7 +17114,7 @@ note_invalid_constants (rtx_insn *insn, HOST_WIDE_INT address, int do_pushes) this insn. */ preprocess_constraints (insn); - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); for (opno = 0; opno < recog_data.n_operands; opno++) { /* Things we need to fix can only occur in inputs. */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cc42544..e81a368 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -27630,11 +27630,10 @@ ix86_attr_length_address_default (rtx_insn *insn) rtx op = recog_data.operand[i]; if (MEM_P (op)) { - constrain_operands_cached (insn, reload_completed); - if (which_alternative != -1) + int alt = constrain_operands_cached (insn, reload_completed); + if (alt != -1) { const char *constraints = recog_data.constraints[i]; - int alt = which_alternative; while (*constraints == '=' || *constraints == '+') constraints++; @@ -45354,7 +45353,7 @@ ix86_mitigate_rop (void) continue; extract_insn (insn); - constrain_operands_cached (insn, reload_completed); + int alt = constrain_operands_cached (insn, reload_completed); int opno0, opno1; int modrm = ix86_get_modrm_for_rop (insn, recog_data.operand, recog_data.n_operands, &opno0, @@ -45366,12 +45365,12 @@ ix86_mitigate_rop (void) rtx oldreg = recog_data.operand[opno1]; preprocess_constraints (insn); - const operand_alternative *alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); int i; for (i = 0; i < recog_data.n_operands; i++) if (i != opno1 - && alt[i].earlyclobber + && op_alt[i].earlyclobber && reg_overlap_mentioned_p (recog_data.operand[i], oldreg)) break; @@ -45383,7 +45382,7 @@ ix86_mitigate_rop (void) fprintf (dump_file, "attempting to fix modrm byte in insn %d:" " reg %d class %s", INSN_UID (insn), REGNO (oldreg), - reg_class_names[alt[opno1].cl]); + reg_class_names[op_alt[opno1].cl]); HARD_REG_SET unavailable; REG_SET_TO_HARD_REG_SET (unavailable, &live); @@ -45392,7 +45391,7 @@ ix86_mitigate_rop (void) IOR_HARD_REG_SET (unavailable, fixed_reg_set); IOR_HARD_REG_SET (unavailable, output_risky); IOR_COMPL_HARD_REG_SET (unavailable, - reg_class_contents[alt[opno1].cl]); + reg_class_contents[op_alt[opno1].cl]); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (!TEST_HARD_REG_BIT (unavailable, i)) diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 1eaf58f..1c7309b 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -283,7 +283,7 @@ "@ fmove%.d %f1,%0 #" - "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 1)" + "&& reload_completed && extract_constrain_insn_cached (insn) == 1" [(const_int 0)] { m68k_emit_move_double (operands); @@ -2514,7 +2514,9 @@ return ""; } } - "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])" + "&& reload_completed + && extract_constrain_insn_cached (insn) == 5 + && !operands_match_p (operands[0], operands[1])" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index b8caab5..4b5d275 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -9133,7 +9133,8 @@ pa_can_combine_p (rtx_insn *new_rtx, rtx_insn *anchor, rtx_insn *floater, basic_block bb = BLOCK_FOR_INSN (anchor); if (insn_code_number < 0 || (extract_insn (new_rtx), - !constrain_operands (1, get_preferred_alternatives (new_rtx, bb)))) + (constrain_operands + (1, get_preferred_alternatives (new_rtx, bb)) < 0))) return 0; if (reversed) diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 9d136a4..f44dc3b 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -2494,7 +2494,7 @@ insn_ok_now (rtx_insn * insn) if (recog (pattern, insn, 0) > -1) { extract_insn (insn); - if (constrain_operands (1, get_preferred_alternatives (insn))) + if (constrain_operands (1, get_preferred_alternatives (insn)) >= 0) { #if DEBUG_ALLOC fprintf (stderr, "\033[32m"); @@ -2523,7 +2523,7 @@ insn_ok_now (rtx_insn * insn) if (recog (pattern, insn, 0) > -1) { extract_insn (insn); - if (constrain_operands (0, get_preferred_alternatives (insn))) + if (constrain_operands (0, get_preferred_alternatives (insn)) >= 0) { cfun->machine->virt_insns_ok = 0; return false; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 457e9442..44f2075 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -34021,7 +34021,8 @@ rs6000_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED, if (insn_code_number < 0) return; - temp = get_insn_template (insn_code_number, insn); + int alt = extract_constrain_insn_cached (insn); + temp = get_insn_template (insn, insn_code_number, alt); if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS) warning_at (location, OPT_mwarn_cell_microcode, diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index 893092b..0718028 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -414,9 +414,7 @@ if (icode < 0) return false; - extract_constrain_insn (insn); - - return which_alternative >= 0; + return extract_constrain_insn (insn) >= 0; }) ;; Return true if OP is a store multiple operation. It is known to be a diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 1431437..39c2909 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -73,8 +73,8 @@ extern const char *output_ubranch (rtx, rtx_insn *); extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *); extern const char *output_return (rtx_insn *); extern const char *output_sibcall (rtx_insn *, rtx); -extern const char *output_v8plus_shift (rtx_insn *, rtx *, const char *); -extern const char *output_v8plus_mult (rtx_insn *, rtx *, const char *); +extern const char *output_v8plus_shift (rtx_insn *, rtx *, const char *, int); +extern const char *output_v8plus_mult (rtx_insn *, rtx *, const char *, int); extern const char *output_v9branch (rtx, rtx, int, int, int, int, rtx_insn *); extern const char *output_probe_stack_range (rtx, rtx); extern const char *output_cbcond (rtx, rtx, rtx_insn *); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 9328723..c0bb126 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -9781,7 +9781,8 @@ sparc_check_64 (rtx x, rtx_insn *insn) OPERANDS are its operands and OPCODE is the mnemonic to be used. */ const char * -output_v8plus_shift (rtx_insn *insn, rtx *operands, const char *opcode) +output_v8plus_shift (rtx_insn *insn, rtx *operands, const char *opcode, + int which_alternative) { static char asm_code[60]; @@ -12011,7 +12012,8 @@ sparc_preferred_reload_class (rtx x, reg_class_t rclass) OPERANDS are its operands and OPCODE is the mnemonic to be used. */ const char * -output_v8plus_mult (rtx_insn *insn, rtx *operands, const char *opcode) +output_v8plus_mult (rtx_insn *insn, rtx *operands, const char *opcode, + int which_alternative) { char mulstr[32]; diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 9cc74f1..5c32689 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -4044,7 +4044,7 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_V8PLUS" - "* return output_v8plus_mult (insn, operands, \"mulx\");" + "* return output_v8plus_mult (insn, operands, \"mulx\", which_alternative);" [(set_attr "type" "multi") (set_attr "length" "9,8")]) @@ -4484,7 +4484,7 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_VIS3 && ! TARGET_ARCH64" - "* return output_v8plus_mult (insn, operands, \"umulxhi\");" + "* return output_v8plus_mult (insn, operands, \"umulxhi\", which_alternative);" [(set_attr "type" "imul") (set_attr "length" "9,8")]) @@ -4528,7 +4528,7 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_VIS3 && ! TARGET_ARCH64" - "* return output_v8plus_mult (insn, operands, \"xmulx\");" + "* return output_v8plus_mult (insn, operands, \"xmulx\", which_alternative);" [(set_attr "type" "imul") (set_attr "length" "9,8")]) @@ -4578,7 +4578,7 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_VIS3 && !TARGET_ARCH64" - "* return output_v8plus_mult (insn, operands, \"xmulxhi\");" + "* return output_v8plus_mult (insn, operands, \"xmulxhi\", which_alternative);" [(set_attr "type" "imul") (set_attr "length" "9,8")]) @@ -5952,7 +5952,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (insn ,operands, \"sllx\");" + "* return output_v8plus_shift (insn ,operands, \"sllx\", which_alternative);" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) @@ -6061,7 +6061,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (insn, operands, \"srax\");" + "* return output_v8plus_shift (insn, operands, \"srax\", which_alternative);" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) @@ -6150,7 +6150,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (insn, operands, \"srlx\");" + "* return output_v8plus_shift (insn, operands, \"srlx\", which_alternative);" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index b9d0e5d..bf5347d 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -29,8 +29,8 @@ extern void print_operand (FILE *, rtx, int); extern void vax_notice_update_cc (rtx, rtx); extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code); extern const char * vax_output_int_move (rtx, rtx *, machine_mode); -extern const char * vax_output_int_add (rtx, rtx *, machine_mode); -extern const char * vax_output_int_subtract (rtx, rtx *, machine_mode); +extern const char * vax_output_int_add (rtx, int, rtx *, machine_mode); +extern const char * vax_output_int_subtract (rtx, int, rtx *, machine_mode); extern const char * vax_output_movmemsi (rtx, rtx *); #endif /* RTX_CODE */ diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index c059751..f323bf9 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1340,7 +1340,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, which are not modified very often. */ const char * -vax_output_int_add (rtx insn, rtx *operands, machine_mode mode) +vax_output_int_add (rtx insn, int alt, rtx *operands, machine_mode mode) { switch (mode) { @@ -1367,7 +1367,7 @@ vax_output_int_add (rtx insn, rtx *operands, machine_mode mode) /* No reason to add a 0 to the low part and thus no carry, so just emit the appropriate add/sub instruction. */ if (low[2] == const0_rtx) - return vax_output_int_add (NULL, operands, SImode); + return vax_output_int_add (NULL, alt, operands, SImode); /* Are we doing addition or subtraction? */ sub = CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0; @@ -1421,7 +1421,7 @@ vax_output_int_add (rtx insn, rtx *operands, machine_mode mode) output_asm_insn (pattern, low); if (!carry) /* If CARRY is 0, we don't have any carry value to worry about. */ - return get_insn_template (CODE_FOR_addsi3, insn); + return get_insn_template (insn, CODE_FOR_addsi3, alt); /* %0 = C + %1 + %2 */ if (!rtx_equal_p (operands[0], operands[1])) output_asm_insn ((operands[1] == const0_rtx @@ -1550,7 +1550,7 @@ vax_output_int_add (rtx insn, rtx *operands, machine_mode mode) } const char * -vax_output_int_subtract (rtx insn, rtx *operands, machine_mode mode) +vax_output_int_subtract (rtx insn, int alt, rtx *operands, machine_mode mode) { switch (mode) { @@ -1603,7 +1603,10 @@ vax_output_int_subtract (rtx insn, rtx *operands, machine_mode mode) if (low[2] == constm1_rtx) pattern = "decl %0"; else if (low[2] == const0_rtx) - pattern = get_insn_template (CODE_FOR_movsi, insn), carry = 0; + { + pattern = get_insn_template (insn, CODE_FOR_movsi, alt); + carry = 0; + } else pattern = "subl3 %2,%1,%0"; } @@ -1616,7 +1619,7 @@ vax_output_int_subtract (rtx insn, rtx *operands, machine_mode mode) return "sbwc %2,%0"; /* %0 = %2 - %1 - C */ } - return get_insn_template (CODE_FOR_subsi3, insn); + return get_insn_template (insn, CODE_FOR_subsi3, alt); } default: diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index d5caa15..8ac4663 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -371,7 +371,8 @@ (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") (match_operand:VAXint 2 "general_operand" "nrmT")))] "" - "* return vax_output_int_add (insn, operands, mode);") + "* return vax_output_int_add (insn, which_alternative, operands, + mode);") (define_expand "adddi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") @@ -385,7 +386,7 @@ (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") (match_operand:DI 2 "general_addsub_di_operand" "nRr")))] "TARGET_QMATH" - "* return vax_output_int_add (insn, operands, DImode);") + "* return vax_output_int_add (insn, which_alternative, operands, DImode);") ;; The add-with-carry (adwc) instruction only accepts two operands. (define_insn "adddi3_old" @@ -393,7 +394,7 @@ (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") (match_operand:DI 2 "general_operand" "Fsro,Fs")))] "!TARGET_QMATH" - "* return vax_output_int_add (insn, operands, DImode);") + "* return vax_output_int_add (insn, which_alternative, operands, DImode);") ;;- All kinds of subtract instructions. @@ -427,7 +428,8 @@ (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))] "TARGET_QMATH" - "* return vax_output_int_subtract (insn, operands, DImode);") + "* return vax_output_int_subtract (insn, which_alternative, + operands, DImode);") ;; The subtract-with-carry (sbwc) instruction only takes two operands. (define_insn "subdi3_old" @@ -435,7 +437,8 @@ (minus:DI (match_operand:DI 1 "general_operand" "0,or>") (match_operand:DI 2 "general_operand" "Fsor,Fs")))] "!TARGET_QMATH" - "* return vax_output_int_subtract (insn, operands, DImode);") + "* return vax_output_int_subtract (insn, which_alternative, + operands, DImode);") ;;- Multiply instructions. diff --git a/gcc/final.c b/gcc/final.c index 2f57b1b..1a081e8 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -2061,19 +2061,27 @@ final (rtx_insn *first, FILE *file, int optimize_p) } } +/* Return the output code for alternative ALT of insn_code CODE. + If CODE uses an output function, INSN is the specific instruction + we want to generate, otherwise it is unused and can be null. + + Note that an output function might write text directly to the + asm output file and simply return "". */ + const char * -get_insn_template (int code, rtx insn) +get_insn_template (rtx insn, int code, int alt) { switch (insn_data[code].output_format) { case INSN_OUTPUT_FORMAT_SINGLE: return insn_data[code].output.single; case INSN_OUTPUT_FORMAT_MULTI: - return insn_data[code].output.multi[which_alternative]; + return insn_data[code].output.multi[alt]; case INSN_OUTPUT_FORMAT_FUNCTION: gcc_assert (insn); return (*insn_data[code].output.function) (recog_data.operand, - as_a (insn)); + as_a (insn), + alt); default: gcc_unreachable (); @@ -2916,7 +2924,8 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, print_rtx_head = ""; } - if (! constrain_operands_cached (insn, 1)) + int alt = constrain_operands_cached (insn, 1); + if (alt < 0) fatal_insn_not_found (insn); /* Some target machines need to prescan each insn before @@ -2944,7 +2953,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, current_output_insn = debug_insn = insn; /* Find the proper template for this insn. */ - templ = get_insn_template (insn_code_number, insn); + templ = get_insn_template (insn, insn_code_number, alt); /* If the C code returns 0, it means that it is a jump insn which follows a deleted test insn, and that test insn @@ -3422,7 +3431,8 @@ output_asm_name (void) ASM_COMMENT_START, INSN_UID (debug_insn), insn_data[num].name); if (insn_data[num].n_alternatives > 1) - fprintf (asm_out_file, "/%d", which_alternative + 1); + fprintf (asm_out_file, "/%d", + constrain_operands_cached (debug_insn, 1) + 1); if (HAVE_ATTR_length) fprintf (asm_out_file, "\t[length = %d]", diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2caf8f6..36fdf8b 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -4278,31 +4278,41 @@ write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av, must_extract = must_constrain = address_used = 0; walk_attr_value (av->value); + int code_indent = indent + 2; if (must_constrain) { + code_indent += 2; write_indent (outf, indent + 2); - fprintf (outf, "extract_constrain_insn_cached (insn);\n"); + fprintf (outf, "{\n"); + write_indent (outf, code_indent); + fprintf (outf, "int which_alternative ATTRIBUTE_UNUSED = " + "extract_constrain_insn_cached (insn);\n"); } else if (must_extract) { - write_indent (outf, indent + 2); + write_indent (outf, code_indent); fprintf (outf, "extract_insn_cached (insn);\n"); } attrs_to_cache = 0; if (av->num_insns == 1) - write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix, + write_attr_set (outf, attr, code_indent, av->value, prefix, suffix, known_true, av->first_insn->def->insn_code, av->first_insn->def->insn_index, 0); else - write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix, + write_attr_set (outf, attr, code_indent, av->value, prefix, suffix, known_true, -2, 0, 0); if (strncmp (prefix, "return", 6)) { - write_indent (outf, indent + 2); + write_indent (outf, code_indent); fprintf (outf, "break;\n"); } + if (code_indent != indent + 2) + { + write_indent (outf, indent + 2); + fprintf (outf, "}\n"); + } fprintf (outf, "\n"); } diff --git a/gcc/genoutput.c b/gcc/genoutput.c index ed9540d..d2e7dbc 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -627,7 +627,9 @@ process_template (struct data *d, const char *template_code) d->output_format = INSN_OUTPUT_FORMAT_FUNCTION; puts ("\nstatic const char *"); - printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n", + printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED," + " rtx_insn *insn ATTRIBUTE_UNUSED," + " int which_alternative ATTRIBUTE_UNUSED)\n", d->code_number); puts ("{"); print_md_ptr_loc (template_code); @@ -656,7 +658,9 @@ process_template (struct data *d, const char *template_code) d->output_format = INSN_OUTPUT_FORMAT_FUNCTION; puts ("\nstatic const char *"); printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, " - "rtx_insn *insn ATTRIBUTE_UNUSED)\n", d->code_number); + "rtx_insn *insn ATTRIBUTE_UNUSED, " + "int which_alternative ATTRIBUTE_UNUSED)\n", + d->code_number); puts ("{"); puts (" switch (which_alternative)\n {"); } diff --git a/gcc/ira.c b/gcc/ira.c index 97edf8c..eae63a4 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1755,7 +1755,7 @@ setup_prohibited_mode_move_regs (void) extract_insn (move_insn); /* We don't know whether the move will be in code that is optimized for size or speed, so consider all enabled alternatives. */ - if (! constrain_operands (1, get_enabled_alternatives (move_insn))) + if (constrain_operands (1, get_enabled_alternatives (move_insn)) < 0) continue; CLEAR_HARD_REG_BIT (ira_prohibited_mode_move_regs[i], j); } diff --git a/gcc/output.h b/gcc/output.h index d485cd6..27c8df9 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -149,7 +149,7 @@ extern int only_leaf_regs_used (void); extern void leaf_renumber_regs_insn (rtx); /* Locate the proper template for the given insn-code. */ -extern const char *get_insn_template (int, rtx); +extern const char *get_insn_template (rtx, int, int); /* Functions in varasm.c. */ diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index f8a770e..d63e7969 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1087,8 +1087,8 @@ eliminate_partially_redundant_load (basic_block bb, rtx_insn *insn, rtx_insn *move = gen_move_insn (copy_rtx (dest), copy_rtx (avail_reg)); extract_insn (move); - if (! constrain_operands (1, get_preferred_alternatives (insn, - pred_bb)) + if (constrain_operands (1, get_preferred_alternatives (insn, + pred_bb)) < 0 || reg_killed_on_edge (avail_reg, pred) || reg_used_on_edge (dest, pred)) { diff --git a/gcc/postreload.c b/gcc/postreload.c index 1186bc0..f8df2d7 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -391,7 +391,7 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) /* Array of alternatives, sorted in order of decreasing desirability. */ int *alternative_order; - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0) return 0; @@ -583,7 +583,7 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) /* Record all alternatives which are better or equal to the currently matching one in the alternative_order array. */ for (i = j = 0; i < recog_data.n_alternatives; i++) - if (alternative_reject[i] <= alternative_reject[which_alternative]) + if (alternative_reject[i] <= alternative_reject[alt]) alternative_order[j++] = i; recog_data.n_alternatives = j; diff --git a/gcc/recog.c b/gcc/recog.c index 028190a..04228f8 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -78,10 +78,10 @@ const operand_alternative *recog_op_alt; static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS * MAX_RECOG_ALTERNATIVES]; -/* On return from `constrain_operands', indicate which alternative - was satisfied. */ +/* Used by constrain_operands_cached to record the matching alternative. + Only valid if nonnegative. */ -int which_alternative; +static int cached_which_alternative; /* Nonzero after end of reload pass. Set to 1 or 0 by toplev.c. @@ -148,8 +148,7 @@ check_asm_operands (rtx x) /* ??? Doh! We've not got the wrapping insn. Cook one up. */ rtx_insn *insn = make_insn_raw (x); extract_insn (insn); - constrain_operands (1, get_enabled_alternatives (insn)); - return which_alternative >= 0; + return constrain_operands (1, get_enabled_alternatives (insn)) >= 0; } noperands = asm_noperands (x); @@ -352,7 +351,7 @@ insn_invalid_p (rtx_insn *insn, bool in_group) { extract_insn (insn); - if (! constrain_operands (1, get_preferred_alternatives (insn))) + if (constrain_operands (1, get_preferred_alternatives (insn)) < 0) return 1; } @@ -2070,20 +2069,20 @@ get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr) mustn't depend on the values of operands, so we don't provide their real values here. */ rtx_insn *old_insn = recog_data.insn; - int old_alternative = which_alternative; + int old_alternative = cached_which_alternative; recog_data.insn = insn; 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; + cached_which_alternative = i; if (!get_bool_attr (insn, attr)) mask &= ~ALTERNATIVE_BIT (i); } recog_data.insn = old_insn; - which_alternative = old_alternative; + cached_which_alternative = old_alternative; return mask; } @@ -2179,36 +2178,43 @@ extract_insn_cached (rtx_insn *insn) } /* Do uncached extract_insn, constrain_operands and complain about failures. + Return the number of the matching alternative. + This should be used when extracting a pre-existing constrained instruction if the caller wants to know which alternative was chosen. */ -void +int extract_constrain_insn (rtx_insn *insn) { extract_insn (insn); - if (!constrain_operands (reload_completed, get_enabled_alternatives (insn))) + int alt = constrain_operands (reload_completed, + get_enabled_alternatives (insn)); + if (alt < 0) fatal_insn_not_found (insn); + return alt; } /* Do cached extract_insn, constrain_operands and complain about failures. + Return the number of the matching alternative. + Used by insn_attrtab. */ -void +int extract_constrain_insn_cached (rtx_insn *insn) { extract_insn_cached (insn); - if (which_alternative == -1 - && !constrain_operands (reload_completed, - get_enabled_alternatives (insn))) + int alt = constrain_operands_cached (insn, reload_completed); + if (alt < 0) fatal_insn_not_found (insn); + return alt; } -/* Do cached constrain_operands on INSN and complain about failures. */ +/* Do cached constrain_operands on INSN. Return -1 on failure. */ int constrain_operands_cached (rtx_insn *insn, int strict) { - if (which_alternative == -1) - return constrain_operands (strict, get_enabled_alternatives (insn)); - else - return 1; + if (cached_which_alternative == -1) + cached_which_alternative + = constrain_operands (strict, get_enabled_alternatives (insn)); + return cached_which_alternative; } /* Analyze INSN and fill in recog_data. */ @@ -2310,7 +2316,7 @@ extract_insn (rtx_insn *insn) gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES); recog_data.insn = NULL; - which_alternative = -1; + cached_which_alternative = -1; } /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands, @@ -2439,7 +2445,7 @@ preprocess_insn_constraints (unsigned int icode) int n_operands = insn_data[icode].n_operands; if (n_operands == 0) return 0; - /* Always provide at least one alternative so that which_op_alt () + /* Always provide at least one alternative so that get_op_alt () works correctly. If the instruction has 0 alternatives (i.e. all constraint strings are empty) then each operand in this alternative will have anything_ok set. */ @@ -2479,16 +2485,12 @@ preprocess_constraints (rtx_insn *insn) } } -/* Check the operands of an insn against the insn's operand constraints - and return 1 if they match any of the alternatives in ALTERNATIVES. +/* Check the operands of an insn against the insn's operand constraints. + Return the matching alternative number on success, otherwise return -1. The information about the insn's operands, constraints, operand modes etc. is obtained from the global variables set up by extract_insn. - WHICH_ALTERNATIVE is set to a number which indicates which - alternative of constraints was matched: 0 for the first alternative, - 1 for the next, etc. - In addition, when two operands are required to match and it happens that the output operand is (reg) while the input operand is --(reg) or ++(reg) (a pre-inc or pre-dec), @@ -2523,9 +2525,8 @@ constrain_operands (int strict, alternative_mask alternatives) struct funny_match funny_match[MAX_RECOG_OPERANDS]; int funny_match_index; - which_alternative = 0; if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0) - return 1; + return 0; for (c = 0; c < recog_data.n_operands; c++) { @@ -2533,6 +2534,7 @@ constrain_operands (int strict, alternative_mask alternatives) matching_operands[c] = -1; } + int which_alternative = 0; do { int seen_earlyclobber_at = -1; @@ -2806,14 +2808,14 @@ constrain_operands (int strict, alternative_mask alternatives) if (strchr (recog_data.constraints[opno], '<') == NULL && strchr (recog_data.constraints[opno], '>') == NULL) - return 0; + return -1; break; default: break; } } - return 1; + return which_alternative; } } @@ -2821,13 +2823,12 @@ constrain_operands (int strict, alternative_mask alternatives) } while (which_alternative < recog_data.n_alternatives); - which_alternative = -1; /* If we are about to reject this, but we are not to test strictly, try a very loose test. Only return failure if it fails also. */ if (strict == 0) return constrain_operands (-1, alternatives); else - return 0; + return -1; } /* Return true iff OPERAND (assumed to be a REG rtx) diff --git a/gcc/recog.h b/gcc/recog.h index 327d6c0..b15140b 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -132,8 +132,8 @@ extern void add_clobbers (rtx, int); extern int added_clobbers_hard_reg_p (int); extern void insn_extract (rtx_insn *); extern void extract_insn (rtx_insn *); -extern void extract_constrain_insn (rtx_insn *insn); -extern void extract_constrain_insn_cached (rtx_insn *); +extern int extract_constrain_insn (rtx_insn *insn); +extern int extract_constrain_insn_cached (rtx_insn *); extern void extract_insn_cached (rtx_insn *); extern void preprocess_constraints (int, int, const char **, operand_alternative *); @@ -186,10 +186,6 @@ skip_alternative (const char *p) /* Nonzero means volatile operands are recognized. */ extern int volatile_ok; -/* Set by constrain_operands to the number of the alternative that - matched. */ -extern int which_alternative; - /* The following vectors hold the results from insn_extract. */ struct recog_data_d @@ -257,22 +253,21 @@ extern struct recog_data_d recog_data; extern const operand_alternative *recog_op_alt; /* Return a pointer to an array in which index OP describes the constraints - on operand OP of the current instruction alternative (which_alternative). + on operand OP for alternative ALT of the current instruction. Only valid after calling preprocess_constraints and constrain_operands. */ inline static const operand_alternative * -which_op_alt () +get_op_alt (int alt) { - gcc_checking_assert (IN_RANGE (which_alternative, 0, - recog_data.n_alternatives - 1)); - return &recog_op_alt[which_alternative * recog_data.n_operands]; + gcc_checking_assert (IN_RANGE (alt, 0, recog_data.n_alternatives - 1)); + return &recog_op_alt[alt * recog_data.n_operands]; } /* A table defined in insn-output.c that give information about each insn-code value. */ typedef int (*insn_operand_predicate_fn) (rtx, machine_mode); -typedef const char * (*insn_output_fn) (rtx *, rtx_insn *); +typedef const char * (*insn_output_fn) (rtx *, rtx_insn *, int); struct insn_gen_fn { diff --git a/gcc/ree.c b/gcc/ree.c index f3b79e0..c641ba7 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -840,7 +840,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state) if (recog_memoized (insn) == -1) return false; extract_insn (insn); - if (!constrain_operands (1, get_preferred_alternatives (insn, bb))) + if (constrain_operands (1, get_preferred_alternatives (insn, bb)) < 0) return false; } diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 8cc0fa4..be9e1b2 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -467,20 +467,20 @@ check_asm_stack_operands (rtx_insn *insn) /* Find out what the constraints require. If no constraint alternative matches, this asm is malformed. */ - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); preprocess_constraints (insn); get_asm_operands_in_out (body, &n_outputs, &n_inputs); - if (which_alternative < 0) + if (alt < 0) { malformed_asm = 1; /* Avoid further trouble with this insn. */ PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); return 0; } - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); /* Strip SUBREGs here to make the following code simpler. */ for (i = 0; i < recog_data.n_operands; i++) @@ -2002,10 +2002,10 @@ subst_asm_stack_regs (rtx_insn *insn, stack_ptr regstack) /* Find out what the constraints required. If no constraint alternative matches, that is a compiler bug: we should have caught such an insn in check_asm_stack_operands. */ - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); preprocess_constraints (insn); - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); get_asm_operands_in_out (body, &n_outputs, &n_inputs); diff --git a/gcc/regcprop.c b/gcc/regcprop.c index f0723a1..833fe6c 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -769,9 +769,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) } set = single_set (insn); - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); preprocess_constraints (insn); - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); n_ops = recog_data.n_operands; is_asm = asm_noperands (PATTERN (insn)) >= 0; @@ -870,8 +870,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) } /* We need to re-extract as validate_change clobbers recog_data. */ - extract_constrain_insn (insn); + alt = extract_constrain_insn (insn); preprocess_constraints (insn); + op_alt = get_op_alt (alt); } /* Otherwise, try all valid registers and see if its valid. */ @@ -896,8 +897,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) } /* We need to re-extract as validate_change clobbers recog_data. */ - extract_constrain_insn (insn); + alt = extract_constrain_insn (insn); preprocess_constraints (insn); + op_alt = get_op_alt (alt); } } } diff --git a/gcc/regrename.c b/gcc/regrename.c index e2a1e83..4f223ab 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -1480,18 +1480,18 @@ scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action, } /* Hide operands of the current insn (of which there are N_OPS) by - substituting cc0 for them. - Previous values are stored in the OLD_OPERANDS and OLD_DUPS. - For every bit set in DO_NOT_HIDE, we leave the operand alone. - If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands - and earlyclobbers. */ + substituting cc0 for them. ALT is the number of the matching + alternative. Previous values are stored in the OLD_OPERANDS and + OLD_DUPS. For every bit set in DO_NOT_HIDE, we leave the operand + alone. If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT + type operands and earlyclobbers. */ static void -hide_operands (int n_ops, rtx *old_operands, rtx *old_dups, +hide_operands (int alt, int n_ops, rtx *old_operands, rtx *old_dups, unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only) { int i; - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); for (i = 0; i < n_ops; i++) { old_operands[i] = recog_data.operand[i]; @@ -1536,13 +1536,15 @@ restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups) /* For each output operand of INSN, call scan_rtx to create a new open chain. Do this only for normal or earlyclobber outputs, depending on EARLYCLOBBER. If INSN_INFO is nonnull, use it to - record information about the operands in the insn. */ + record information about the operands in the insn. ALT is the + number of the matching alternative. */ static void -record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info) +record_out_operands (rtx_insn *insn, int alt, bool earlyclobber, + insn_rr_info *insn_info) { int n_ops = recog_data.n_operands; - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); int i; @@ -1634,9 +1636,9 @@ build_def_use (basic_block bb) to be marked unrenamable or even cause us to abort the entire basic block. */ - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); preprocess_constraints (insn); - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); n_ops = recog_data.n_operands; untracked_operands = 0; @@ -1692,22 +1694,22 @@ build_def_use (basic_block bb) /* Step 1a: Mark hard registers that are clobbered in this insn, outside an operand, as live. */ - hide_operands (n_ops, old_operands, old_dups, untracked_operands, - false); + hide_operands (alt, n_ops, old_operands, old_dups, + untracked_operands, false); note_stores (PATTERN (insn), note_sets_clobbers, &clobber_code); restore_operands (insn, n_ops, old_operands, old_dups); /* Step 1b: Begin new chains for earlyclobbered writes inside operands. */ - record_out_operands (insn, true, insn_info); + record_out_operands (insn, alt, true, insn_info); /* Step 2: Mark chains for which we have reads outside operands as unrenamable. We do this by munging all operands into CC0, and closing everything remaining. */ - hide_operands (n_ops, old_operands, old_dups, untracked_operands, - false); + hide_operands (alt, n_ops, old_operands, old_dups, + untracked_operands, false); scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN); restore_operands (insn, n_ops, old_operands, old_dups); @@ -1801,20 +1803,20 @@ build_def_use (basic_block bb) the previous insn at the latest, as such operands cannot possibly overlap with any input operands. */ - hide_operands (n_ops, old_operands, old_dups, untracked_operands, - true); + hide_operands (alt, n_ops, old_operands, old_dups, + untracked_operands, true); scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN); restore_operands (insn, n_ops, old_operands, old_dups); /* Step 6a: Mark hard registers that are set in this insn, outside an operand, as live. */ - hide_operands (n_ops, old_operands, old_dups, untracked_operands, - false); + hide_operands (alt, n_ops, old_operands, old_dups, + untracked_operands, false); note_stores (PATTERN (insn), note_sets_clobbers, &set_code); restore_operands (insn, n_ops, old_operands, old_dups); /* Step 6b: Begin new chains for writes inside operands. */ - record_out_operands (insn, false, insn_info); + record_out_operands (insn, alt, false, insn_info); /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR notes for update. */ diff --git a/gcc/reload.c b/gcc/reload.c index 1e96dfc..c41a7b1 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -910,7 +910,7 @@ can_reload_into (rtx in, int regno, machine_mode mode) if (recog_memoized (test_insn) >= 0) { extract_insn (test_insn); - r = constrain_operands (1, get_enabled_alternatives (test_insn)); + r = constrain_operands (1, get_enabled_alternatives (test_insn)) >= 0; } recog_data = save_recog_data; return r; diff --git a/gcc/reload1.c b/gcc/reload1.c index 4f1910b..92a0050 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1248,7 +1248,7 @@ reload (rtx_insn *first, int global) if (asm_noperands (PATTERN (insn)) >= 0) { extract_insn (insn); - if (!constrain_operands (1, get_enabled_alternatives (insn))) + if (constrain_operands (1, get_enabled_alternatives (insn)) < 0) { error_for_asm (insn, "% operand has impossible constraints"); @@ -4712,8 +4712,8 @@ reload_as_needed (int live_known) && GET_CODE (PATTERN (p)) != USE && (recog_memoized (p) < 0 || (extract_insn (p), - !(constrain_operands (1, - get_enabled_alternatives (p)))))) + (constrain_operands + (1, get_enabled_alternatives (p)) < 0)))) { error_for_asm (insn, "% operand requires " @@ -4796,8 +4796,8 @@ reload_as_needed (int live_known) if (n) { extract_insn (p); - n = constrain_operands (1, - get_enabled_alternatives (p)); + n = constrain_operands + (1, get_enabled_alternatives (p)) >= 0; } /* If the constraints were not met, then @@ -5717,7 +5717,8 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2) /* We want constrain operands to treat this insn strictly in its validity determination, i.e., the way it would after reload has completed. */ - result = constrain_operands (1, get_enabled_alternatives (insn)); + result = + constrain_operands (1, get_enabled_alternatives (insn)) >= 0; } delete_insns_since (last); @@ -7387,7 +7388,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl, autoincrement addressing mode, then the resulting insn is ill-formed and we must reject this optimization. */ extract_insn (temp); - if (constrain_operands (1, get_enabled_alternatives (temp)) + if (constrain_operands (1, get_enabled_alternatives (temp)) >= 0 && (!AUTO_INC_DEC || ! find_reg_note (temp, REG_INC, reloadreg))) { /* If the previous insn is an output reload, the source is @@ -8571,7 +8572,7 @@ emit_insn_if_valid_for_reload (rtx pat) /* We want constrain operands to treat this insn strictly in its validity determination, i.e., the way it would after reload has completed. */ - if (constrain_operands (1, get_enabled_alternatives (insn))) + if (constrain_operands (1, get_enabled_alternatives (insn)) >= 0) return insn; } @@ -9204,7 +9205,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount) if (code >= 0) { extract_insn (add_insn); - if (constrain_operands (1, get_enabled_alternatives (add_insn))) + if (constrain_operands (1, get_enabled_alternatives (add_insn)) >= 0) { /* If this is a pre-increment and we have incremented the value where it lives, copy the incremented value to RELOADREG to diff --git a/gcc/reorg.c b/gcc/reorg.c index cc68d6b..96a6a97 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -2708,7 +2708,8 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, if (recog_memoized (ninsn) < 0 || (extract_insn (ninsn), - !constrain_operands (1, get_preferred_alternatives (ninsn)))) + (constrain_operands + (1, get_preferred_alternatives (ninsn)) < 0))) { delete_related_insns (ninsn); return; diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index aebc2d9..f4966ee 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -985,11 +985,11 @@ get_reg_class (rtx_insn *insn) { int i, n_ops; - extract_constrain_insn (insn); + int alt = extract_constrain_insn (insn); preprocess_constraints (insn); n_ops = recog_data.n_operands; - const operand_alternative *op_alt = which_op_alt (); + const operand_alternative *op_alt = get_op_alt (alt); if (asm_noperands (PATTERN (insn)) > 0) { for (i = 0; i < n_ops; i++)