From patchwork Sat May 31 09:17:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 354400 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 C97FB1400A8 for ; Sat, 31 May 2014 19:17:20 +1000 (EST) 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; q=dns; s=default; b=P4j/xvT2rjBv9tfK EQJcnSJ0KL/6uX53t4wCt91AlA9568acb3RWE37VmheMemSXQkejtO7T00Wy6ksS kGy0GStcI3F3BOKoNDyV4LoocXDLtCyTAThr1+x7SKrrID3Uw0C4xIETk58w+W3h tmpWnOEx6U6zviCjv6WUgP5vDXI= 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; s=default; bh=HTfGc5f8WPZ4v9wIMD4Gwu EmuwM=; b=coocyr1DKKI0jkW6rcVRLQcYXuogHzU8B87lgmZ1FUrMk/ChsjSjWH HaFIMOwigIoNNwBIp5YZr5t9RfDCSVAwSysS2QjhRavzlhw5MLZpmnABXCtk4i4B BZlHdfJgCrk6V5w8l/WdL9e7NzjMHIvm9R5e4vZwgQAG/I0Q0jvt8= Received: (qmail 15177 invoked by alias); 31 May 2014 09:17:13 -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 15161 invoked by uid 89); 31 May 2014 09:17:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wg0-f41.google.com Received: from mail-wg0-f41.google.com (HELO mail-wg0-f41.google.com) (74.125.82.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 31 May 2014 09:17:09 +0000 Received: by mail-wg0-f41.google.com with SMTP id z12so3024397wgg.12 for ; Sat, 31 May 2014 02:17:06 -0700 (PDT) X-Received: by 10.180.160.205 with SMTP id xm13mr4498272wib.13.1401527826375; Sat, 31 May 2014 02:17:06 -0700 (PDT) Received: from localhost ([2.26.169.52]) by mx.google.com with ESMTPSA id ba9sm13155702wib.24.2014.05.31.02.17.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 31 May 2014 02:17:05 -0700 (PDT) From: Richard Sandiford To: Jeff Law Mail-Followup-To: Jeff Law , gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 4/5] Cache recog_op_alt by insn code: main patch References: <87egzokglh.fsf@talisman.default> <537B9911.7070604@redhat.com> <87mwdyfhhg.fsf_-_@talisman.default> Date: Sat, 31 May 2014 10:17:04 +0100 In-Reply-To: <87mwdyfhhg.fsf_-_@talisman.default> (Richard Sandiford's message of "Sat, 31 May 2014 10:02:51 +0100") Message-ID: <8761kmfgtr.fsf_-_@talisman.default> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 This is the refreshed main patch. I've rearranged the preprocess_constraints code into three functions so that LRA can use it in patch 5. Thanks, Richard gcc/ * recog.h (operand_alternative): Convert reg_class, reject, matched and matches into bitfields. (preprocess_constraints): New overload. (preprocess_insn_constraints): New function. (preprocess_constraints): Take the insn as parameter. (recog_op_alt): Change into a pointer. (target_recog): Add x_op_alt. * recog.c (asm_op_alt): New variable. (recog_op_alt): Change into a pointer. (preprocess_constraints): New overload, replacing the old function definition with one that doesn't use global state. (preprocess_insn_constraints): New function. (preprocess_constraints): Use them. Take the insn as parameter. Use asm_op_alt for asms. (recog_init): Free existing x_op_alt entries. * ira-lives.c (check_and_make_def_conflict): Make operand_alternative pointer const. (make_early_clobber_and_input_conflicts): Likewise. (process_bb_node_lives): Pass the insn to process_constraints. * reg-stack.c (check_asm_stack_operands): Likewise. (subst_asm_stack_regs): Likewise. * regcprop.c (copyprop_hardreg_forward_1): Likewise. * regrename.c (build_def_use): Likewise. * sched-deps.c (sched_analyze_insn): Likewise. * sel-sched.c (get_reg_class, implicit_clobber_conflict_p): Likewise. * config/arm/arm.c (xscale_sched_adjust_cost): Likewise. (note_invalid_constants): Likewise. * config/i386/i386.c (ix86_legitimate_combined_insn): Likewise. (ix86_legitimate_combined_insn): Make operand_alternative pointer const. Index: gcc/recog.h =================================================================== --- gcc/recog.h 2014-05-31 09:02:35.956369716 +0100 +++ gcc/recog.h 2014-05-31 09:10:16.596150618 +0100 @@ -46,18 +46,18 @@ struct operand_alternative const char *constraint; /* The register class valid for this alternative (possibly NO_REGS). */ - enum reg_class cl; + ENUM_BITFIELD (reg_class) cl : 16; /* "Badness" of this alternative, computed from number of '?' and '!' characters in the constraint string. */ - unsigned int reject; + unsigned int reject : 16; /* -1 if no matching constraint was found, or an operand number. */ - int matches; + int matches : 8; /* The same information, but reversed: -1 if this operand is not matched by any other, or the operand number of the operand that matches this one. */ - int matched; + int matched : 8; /* Nonzero if '&' was found in the constraint string. */ unsigned int earlyclobber:1; @@ -77,6 +77,8 @@ struct operand_alternative /* Nonzero if 'X' was found in the constraint string, or if the constraint string for this alternative was empty. */ unsigned int anything_ok:1; + + unsigned int unused : 8; }; /* Return the class for operand I of alternative ALT, taking matching @@ -142,7 +144,10 @@ extern void insn_extract (rtx); extern void extract_insn (rtx); extern void extract_constrain_insn_cached (rtx); extern void extract_insn_cached (rtx); -extern void preprocess_constraints (void); +extern void preprocess_constraints (int, int, const char **, + operand_alternative *); +extern const operand_alternative *preprocess_insn_constraints (int); +extern void preprocess_constraints (rtx); extern rtx peep2_next_insn (int); extern int peep2_regno_dead_p (int, int); extern int peep2_reg_dead_p (int, rtx); @@ -264,8 +269,7 @@ struct recog_data_d extern struct recog_data_d recog_data; -extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS - * MAX_RECOG_ALTERNATIVES]; +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). @@ -396,6 +400,7 @@ struct insn_data_d struct target_recog { bool x_initialized; alternative_mask x_enabled_alternatives[LAST_INSN_CODE]; + operand_alternative *x_op_alt[LAST_INSN_CODE]; }; extern struct target_recog default_target_recog; Index: gcc/recog.c =================================================================== --- gcc/recog.c 2014-05-31 09:07:21.669714878 +0100 +++ gcc/recog.c 2014-05-31 09:15:38.746800685 +0100 @@ -81,8 +81,11 @@ struct recog_data_d recog_data; /* Contains a vector of operand_alternative structures, such that operand OP of alternative A is at index A * n_operands + OP. Set up by preprocess_constraints. */ -struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS - * MAX_RECOG_ALTERNATIVES]; +const operand_alternative *recog_op_alt; + +/* Used to provide recog_op_alt for asms. */ +static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS + * MAX_RECOG_ALTERNATIVES]; /* On return from `constrain_operands', indicate which alternative was satisfied. */ @@ -2324,26 +2327,23 @@ extract_insn (rtx insn) which_alternative = -1; } -/* After calling extract_insn, you can use this function to extract some - information from the constraint strings into a more usable form. - The collected data is stored in recog_op_alt. */ +/* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands, + N_ALTERNATIVES alternatives and constraint strings CONSTRAINTS. + OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries and CONSTRAINTS + has N_OPERANDS entries. */ + void -preprocess_constraints (void) +preprocess_constraints (int n_operands, int n_alternatives, + const char **constraints, + operand_alternative *op_alt_base) { - int i; - - int n_operands = recog_data.n_operands; - int n_alternatives = recog_data.n_alternatives; - int n_entries = n_operands * n_alternatives; - memset (recog_op_alt, 0, n_entries * sizeof (struct operand_alternative)); - - for (i = 0; i < n_operands; i++) + for (int i = 0; i < n_operands; i++) { int j; struct operand_alternative *op_alt; - const char *p = recog_data.constraints[i]; + const char *p = constraints[i]; - op_alt = recog_op_alt; + op_alt = op_alt_base; for (j = 0; j < n_alternatives; j++, op_alt += n_operands) { @@ -2462,6 +2462,59 @@ preprocess_constraints (void) } } +/* Return an array of operand_alternative instructions for + instruction ICODE. */ + +const operand_alternative * +preprocess_insn_constraints (int icode) +{ + gcc_checking_assert (IN_RANGE (icode, 0, LAST_INSN_CODE)); + if (this_target_recog->x_op_alt[icode]) + return this_target_recog->x_op_alt[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 () + 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. */ + int n_alternatives = MAX (insn_data[icode].n_alternatives, 1); + int n_entries = n_operands * n_alternatives; + + operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries); + const char **constraints = XALLOCAVEC (const char *, n_operands); + + for (int i = 0; i < n_operands; ++i) + constraints[i] = insn_data[icode].operand[i].constraint; + preprocess_constraints (n_operands, n_alternatives, constraints, op_alt); + + this_target_recog->x_op_alt[icode] = op_alt; + return op_alt; +} + +/* After calling extract_insn, you can use this function to extract some + information from the constraint strings into a more usable form. + The collected data is stored in recog_op_alt. */ + +void +preprocess_constraints (rtx insn) +{ + int icode = INSN_CODE (insn); + if (icode >= 0) + recog_op_alt = preprocess_insn_constraints (icode); + else + { + int n_operands = recog_data.n_operands; + int n_alternatives = recog_data.n_alternatives; + int n_entries = n_operands * n_alternatives; + memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative)); + preprocess_constraints (n_operands, n_alternatives, + recog_data.constraints, asm_op_alt); + recog_op_alt = asm_op_alt; + } +} + /* Check the operands of an insn against the insn's operand constraints and return 1 if they are valid. The information about the insn's operands, constraints, operand modes @@ -4211,4 +4264,10 @@ recog_init () } memset (this_target_recog->x_enabled_alternatives, 0, sizeof (this_target_recog->x_enabled_alternatives)); + for (int i = 0; i < LAST_INSN_CODE; ++i) + if (this_target_recog->x_op_alt[i]) + { + free (this_target_recog->x_op_alt[i]); + this_target_recog->x_op_alt[i] = 0; + } } Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c 2014-05-31 09:07:21.670714886 +0100 +++ gcc/ira-lives.c 2014-05-31 09:10:16.598150634 +0100 @@ -625,7 +625,7 @@ check_and_make_def_conflict (int alt, in advance_p = true; int n_operands = recog_data.n_operands; - operand_alternative *op_alt = &recog_op_alt[alt * n_operands]; + const operand_alternative *op_alt = &recog_op_alt[alt * n_operands]; for (use = 0; use < n_operands; use++) { int alt1; @@ -646,7 +646,8 @@ check_and_make_def_conflict (int alt, in { if (!TEST_BIT (enabled, alt1)) continue; - operand_alternative *op_alt1 = &recog_op_alt[alt1 * n_operands]; + const operand_alternative *op_alt1 + = &recog_op_alt[alt1 * n_operands]; if (op_alt1[use].matches == def || (use < n_operands - 1 && recog_data.constraints[use][0] == '%' @@ -692,7 +693,7 @@ 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; - operand_alternative *op_alt = recog_op_alt; + const operand_alternative *op_alt = recog_op_alt; for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands) if (TEST_BIT (enabled, alt)) for (def = 0; def < n_operands; def++) @@ -1251,7 +1252,7 @@ process_bb_node_lives (ira_loop_tree_nod } extract_insn (insn); - preprocess_constraints (); + preprocess_constraints (insn); process_single_reg_class_operands (false, freq); /* See which defined values die here. */ Index: gcc/reg-stack.c =================================================================== --- gcc/reg-stack.c 2014-05-31 09:02:35.968369814 +0100 +++ gcc/reg-stack.c 2014-05-31 09:10:16.601150659 +0100 @@ -471,7 +471,7 @@ check_asm_stack_operands (rtx insn) extract_insn (insn); constrain_operands (1); - preprocess_constraints (); + preprocess_constraints (insn); get_asm_operands_in_out (body, &n_outputs, &n_inputs); @@ -2029,7 +2029,7 @@ subst_asm_stack_regs (rtx insn, stack_pt extract_insn (insn); constrain_operands (1); - preprocess_constraints (); + preprocess_constraints (insn); const operand_alternative *op_alt = which_op_alt (); get_asm_operands_in_out (body, &n_outputs, &n_inputs); Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2014-05-31 09:02:35.957369724 +0100 +++ gcc/regcprop.c 2014-05-31 09:10:16.601150659 +0100 @@ -774,7 +774,7 @@ copyprop_hardreg_forward_1 (basic_block extract_insn (insn); if (! constrain_operands (1)) fatal_insn_not_found (insn); - preprocess_constraints (); + preprocess_constraints (insn); const operand_alternative *op_alt = which_op_alt (); n_ops = recog_data.n_operands; is_asm = asm_noperands (PATTERN (insn)) >= 0; @@ -877,7 +877,7 @@ copyprop_hardreg_forward_1 (basic_block extract_insn (insn); if (! constrain_operands (1)) fatal_insn_not_found (insn); - preprocess_constraints (); + preprocess_constraints (insn); } /* Otherwise, try all valid registers and see if its valid. */ @@ -905,7 +905,7 @@ copyprop_hardreg_forward_1 (basic_block extract_insn (insn); if (! constrain_operands (1)) fatal_insn_not_found (insn); - preprocess_constraints (); + preprocess_constraints (insn); } } } Index: gcc/regrename.c =================================================================== --- gcc/regrename.c 2014-05-31 09:02:35.958369732 +0100 +++ gcc/regrename.c 2014-05-31 09:10:16.602150667 +0100 @@ -1570,7 +1570,7 @@ build_def_use (basic_block bb) extract_insn (insn); if (! constrain_operands (1)) fatal_insn_not_found (insn); - preprocess_constraints (); + preprocess_constraints (insn); const operand_alternative *op_alt = which_op_alt (); n_ops = recog_data.n_operands; untracked_operands = 0; Index: gcc/sched-deps.c =================================================================== --- gcc/sched-deps.c 2014-05-31 08:54:09.086208879 +0100 +++ gcc/sched-deps.c 2014-05-31 09:10:16.615150774 +0100 @@ -2865,7 +2865,7 @@ sched_analyze_insn (struct deps_desc *de HARD_REG_SET temp; extract_insn (insn); - preprocess_constraints (); + preprocess_constraints (insn); ira_implicitly_set_insn_hard_regs (&temp); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp); Index: gcc/sel-sched.c =================================================================== --- gcc/sel-sched.c 2014-05-31 09:02:35.970369830 +0100 +++ gcc/sel-sched.c 2014-05-31 09:10:16.617150790 +0100 @@ -1019,7 +1019,7 @@ get_reg_class (rtx insn) extract_insn (insn); if (! constrain_operands (1)) fatal_insn_not_found (insn); - preprocess_constraints (); + preprocess_constraints (insn); n_ops = recog_data.n_operands; const operand_alternative *op_alt = which_op_alt (); @@ -2134,7 +2134,7 @@ implicit_clobber_conflict_p (insn_t thro /* Calculate implicit clobbers. */ extract_insn (insn); - preprocess_constraints (); + preprocess_constraints (insn); ira_implicitly_set_insn_hard_regs (&temp); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2014-05-31 09:02:35.966369798 +0100 +++ gcc/config/arm/arm.c 2014-05-31 09:10:16.626150864 +0100 @@ -11335,7 +11335,7 @@ xscale_sched_adjust_cost (rtx insn, rtx that overlaps with SHIFTED_OPERAND, then we have increase the cost of this dependency. */ extract_insn (dep); - preprocess_constraints (); + preprocess_constraints (dep); for (opno = 0; opno < recog_data.n_operands; opno++) { /* We can ignore strict inputs. */ @@ -16870,7 +16870,7 @@ note_invalid_constants (rtx insn, HOST_W /* Fill in recog_op_alt with information about the constraints of this insn. */ - preprocess_constraints (); + preprocess_constraints (insn); const operand_alternative *op_alt = which_op_alt (); for (opno = 0; opno < recog_data.n_operands; opno++) Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2014-05-31 09:07:21.682714985 +0100 +++ gcc/config/i386/i386.c 2014-05-31 09:10:16.638150962 +0100 @@ -5826,7 +5826,7 @@ ix86_legitimate_combined_insn (rtx insn) int i; extract_insn (insn); - preprocess_constraints (); + preprocess_constraints (insn); int n_operands = recog_data.n_operands; int n_alternatives = recog_data.n_alternatives; @@ -5834,7 +5834,7 @@ ix86_legitimate_combined_insn (rtx insn) { rtx op = recog_data.operand[i]; enum machine_mode mode = GET_MODE (op); - operand_alternative *op_alt; + const operand_alternative *op_alt; int offset = 0; bool win; int j;