]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
recog.h (operand_alternative): Convert reg_class, reject, matched and matches into...
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 4 Jun 2014 17:34:40 +0000 (17:34 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 4 Jun 2014 17:34:40 +0000 (17:34 +0000)
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.

From-SVN: r211240

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/i386/i386.c
gcc/ira-lives.c
gcc/recog.c
gcc/recog.h
gcc/reg-stack.c
gcc/regcprop.c
gcc/regrename.c
gcc/sched-deps.c
gcc/sel-sched.c

index 0cc10d25b6aabc9aaa87d31206eb6cf86a29b84b..049ab7d3ba1b7072366410d832d95354cde63cc5 100644 (file)
@@ -1,3 +1,36 @@
+2014-06-04  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * 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.
+
 2014-06-04  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * recog.c (preprocess_constraints): Don't skip disabled alternatives.
index d5d958ebec51d4930abe2e03f15f33d7f1320bb1..c68d888028fe2a3f3c5b212e2c4ee8c6bcc6b3e2 100644 (file)
@@ -11341,7 +11341,7 @@ xscale_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
             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.  */
@@ -16876,7 +16876,7 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
 
   /* 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 e0e55d51cfd7ad92b8c8d6a8e8e3633d4973dac8..9105132cf1a2be155d7b6cd5cc5d216615dece64 100644 (file)
@@ -5827,7 +5827,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;
@@ -5835,7 +5835,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;
index 62e3768aea60a7e42d11fb7cda451d33fca3c257..65133202432826a5abc8671c2f142775502f0bf2 100644 (file)
@@ -625,7 +625,7 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
   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, int def, enum reg_class def_cl)
        {
          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 (void)
   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_node_t loop_tree_node)
              }
 
          extract_insn (insn);
-         preprocess_constraints ();
+         preprocess_constraints (insn);
          process_single_reg_class_operands (false, freq);
 
          /* See which defined values die here.  */
index 15e07527ba84c6e044981c31cbe19e9d69f9e31f..0a5d82e1a80b46f1c2c4c0c71351c4ad13ddf980 100644 (file)
@@ -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
@@ -4212,4 +4265,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 3dae18ba26a4cc8be192bb73c5e7edcce56767c1..2017c85a49873e7056b415fb31ab6d8005d3f5d1 100644 (file)
@@ -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 @@ extern int peep2_current_count;
 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 443a65a504bcc029c8b1ff470fcb670dc8fc7208..05ca881e4542bbb7b7f0fadfef08a2ec7019b339 100644 (file)
@@ -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_ptr regstack)
   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 56efc948a7c795d1cf18b109dadf22a2ef41f4bd..fe370ee70ba587b1037f71b0a1e69704c391e72a 100644 (file)
@@ -774,7 +774,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
       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 bb, struct value_data *vd)
              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 bb, struct value_data *vd)
                  extract_insn (insn);
                  if (! constrain_operands (1))
                    fatal_insn_not_found (insn);
-                 preprocess_constraints ();
+                 preprocess_constraints (insn);
                }
            }
        }
index fa6ed49d1dfddce44645ed5ddd360269c6438acc..20f0baa62d768550168126b0bc7f36731949e00d 100644 (file)
@@ -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 efc4223089ac988444481fcb74e19f6f163c7fcb..019ec2f9532d983de6250735c58a1cfe9e538e50 100644 (file)
@@ -2865,7 +2865,7 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
       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 fb93f92a2bc9e85089e4dd27e922395cc55df19a..416e91725e84846504c3f8223124bf92e62c5cdb 100644 (file)
@@ -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 through_insn, expr_t expr)
 
   /* 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);