Vladimir Makarov <vmaka...@redhat.com> writes:
> On 12-10-16 5:21 PM, Richard Sandiford wrote:
>> I realise you probably have patches pending as well, so I'm happy to
>> wait until those have gone in and update.
>>
> You can commit it into the branch.  You have to do some work for 
> conflict resolution (I added new helper function in 
> curr_insn_transformation for swapping operands) as the code was changed 
> a lot today.

Thanks.  For the record, here's what I committed after retesting.

Richard


gcc/
        * lra-int.h (lra_operand_data): Add is_address field.
        * lra.c (debug_operand_data): Initialize is_address field.
        (get_static_insn_data): Likewise.
        (setup_operand_alternative): Record is_address in operand data.
        (lra_set_insn_recog_data): Initialize is_address field.
        * lra-constraints.c (curr_operand_mode): New array.
        (init_curr_operand_mode): New function.
        (find_mode, get_op_mode): Delete.
        (match_reload): Use curr_operand_mode rather than get_op_mode.
        (process_alt_operands): Likewise.  Remove VOIDmode check from
        CONST_OK_POOL_P check.
        (swap_operands): Swap the operand modes too.
        (curr_insn_transform): Use curr_operand_mode rather than get_op_mode.
        Remove VOIDmode check from CONST_OK_POOL_P check.  Use swap_operands
        for the final swap too.
        (lra_constraints): Call init_curr_operand_mode.

Index: gcc/lra-int.h
===================================================================
--- gcc/lra-int.h       2012-10-17 09:04:35.000000000 +0100
+++ gcc/lra-int.h       2012-10-17 09:05:12.284782971 +0100
@@ -157,6 +157,8 @@ struct lra_operand_data
      This field is set up every time when corresponding
      operand_alternative in lra_static_insn_data is set up.  */
   unsigned int early_clobber : 1;
+  /* True if the operand is an address.  */
+  unsigned int is_address : 1;
 };
 
 /* Info about register in an insn.  */
Index: gcc/lra.c
===================================================================
--- gcc/lra.c   2012-10-17 09:04:35.000000000 +0100
+++ gcc/lra.c   2012-10-17 09:05:12.286782972 +0100
@@ -517,7 +517,7 @@ static struct lra_operand_data debug_ope
     NULL, /* alternative  */
     VOIDmode, /* We are not interesting in the operand mode.  */
     OP_IN,
-    0, 0, 0 
+    0, 0, 0, 0
   };
 
 /* The following data are used as static insn data for all debug
@@ -618,6 +618,7 @@ get_static_insn_data (int icode, int nop
            = (data->operand[i].constraint[0] == '=' ? OP_OUT
               : data->operand[i].constraint[0] == '+' ? OP_INOUT
               : OP_IN);
+         data->operand[i].is_address = false;
        }
       for (i = 0; i < ndup; i++)
        data->dup_num[i] = recog_data.dup_num[i];
@@ -823,6 +824,7 @@ setup_operand_alternative (lra_insn_reco
                  break;
 
                case 'p':
+                 static_data->operand[i].is_address = true;
                  op_alt->is_address = 1;
                  op_alt->cl = (reg_class_subunion[(int) op_alt->cl]
                                [(int) base_reg_class (VOIDmode,
@@ -844,6 +846,7 @@ setup_operand_alternative (lra_insn_reco
                    }
                  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
                    {
+                     static_data->operand[i].is_address = true;
                      op_alt->is_address = 1;
                      op_alt->cl
                        = (reg_class_subunion
@@ -1062,6 +1065,7 @@ lra_set_insn_recog_data (rtx insn)
              insn_static_data->operand[i].constraint = constraints[i];
              insn_static_data->operand[i].strict_low = false;
              insn_static_data->operand[i].is_operator = false;
+             insn_static_data->operand[i].is_address = false;
            }
        }
       for (i = 0; i < insn_static_data->n_operands; i++)
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c       2012-10-17 09:04:35.000000000 +0100
+++ gcc/lra-constraints.c       2012-10-17 09:14:03.164753401 +0100
@@ -138,11 +138,13 @@
 static int bb_reload_num;
 
 /* The current insn being processed and corresponding its data (basic
-   block, the insn data, and the insn static data.  */
+   block, the insn data, the insn static data, and the mode of each
+   operand).  */
 static rtx curr_insn;
 static basic_block curr_bb;
 static lra_insn_recog_data_t curr_id;
 static struct lra_static_insn_data *curr_static_id;
+static enum machine_mode curr_operand_mode[MAX_RECOG_OPERANDS];
 
 
 
@@ -298,6 +300,27 @@ get_equiv_substitution (rtx x)
   gcc_unreachable ();
 }
 
+/* Set up curr_operand_mode.  */
+static void
+init_curr_operand_mode (void)
+{
+  int nop = curr_static_id->n_operands;
+  for (int i = 0; i < nop; i++)
+    {
+      enum machine_mode mode = GET_MODE (*curr_id->operand_loc[i]);
+      if (mode == VOIDmode)
+       {
+         /* The .md mode for address operands is the mode of the
+            addressed value rather than the mode of the address itself.  */
+         if (curr_id->icode >= 0 && curr_static_id->operand[i].is_address)
+           mode = Pmode;
+         else
+           mode = curr_static_id->operand[i].mode;
+       }
+      curr_operand_mode[i] = mode;
+    }
+}
+
 
 
 /* The page contains code to reuse input reloads.  */
@@ -870,65 +893,6 @@ #define SMALL_REGISTER_CLASS_P(C)                          
        \
   (reg_class_size [(C)] == 1                                           \
    || (reg_class_size [(C)] >= 1 && targetm.class_likely_spilled_p (C)))
 
-/* Return mode of WHAT inside of WHERE whose mode of the context is
-   OUTER_MODE. If WHERE does not contain WHAT, return VOIDmode.  */
-static enum machine_mode
-find_mode (rtx *where, enum machine_mode outer_mode, rtx *what)
-{
-  int i, j;
-  enum machine_mode mode;
-  rtx x;
-  const char *fmt;
-  enum rtx_code code;
-
-  if (where == what)
-    return outer_mode;
-  if (*where == NULL_RTX)
-    return VOIDmode;
-  x = *where;
-  code = GET_CODE (x);
-  outer_mode = GET_MODE (x);
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-       {
-         if ((mode = find_mode (&XEXP (x, i), outer_mode, what)) != VOIDmode)
-           return mode;
-       }
-      else if (fmt[i] == 'E')
-       {
-         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-         if ((mode = find_mode (&XVECEXP (x, i, j), outer_mode, what))
-             != VOIDmode)
-           return mode;
-       }
-    }
-  return VOIDmode;
-}
-
-/* Return mode for operand NOP of the current insn.  */
-static inline enum machine_mode
-get_op_mode (int nop)
-{
-  rtx *loc;
-  enum machine_mode mode;
-  bool md_first_p = asm_noperands (PATTERN (curr_insn)) < 0;
-
-  /* Take mode from the machine description first.  */
-  if (md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode)
-    return mode;
-  loc = curr_id->operand_loc[nop];
-  /* Take mode from the operand second.         */
-  mode = GET_MODE (*loc);
-  if (mode != VOIDmode)
-    return mode;
-  if (! md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode)
-    return mode;
-  /* Here is a very rare case. Take mode from the context.  */
-  return find_mode (&PATTERN (curr_insn), VOIDmode, loc);
-}
-
 /* If REG is a reload pseudo, try to make its class satisfying CL.  */
 static void
 narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
@@ -963,8 +927,8 @@ match_reload (signed char out, signed ch
   rtx in_rtx = *curr_id->operand_loc[ins[0]];
   rtx out_rtx = *curr_id->operand_loc[out];
 
-  outmode = get_op_mode (out);
-  inmode = get_op_mode (ins[0]);
+  outmode = curr_operand_mode[out];
+  inmode = curr_operand_mode[ins[0]];
   if (inmode != outmode)
     {
       if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
@@ -1690,7 +1654,7 @@ process_alt_operands (int only_alternati
            }
       
          op = no_subreg_reg_operand[nop];
-         mode = get_op_mode (nop);
+         mode = curr_operand_mode[nop];
 
          win = did_match = winreg = offmemok = constmemok = false;
          badop = true;
@@ -2162,8 +2126,7 @@ process_alt_operands (int only_alternati
              if (CONST_POOL_OK_P (mode, op)
                  && ((targetm.preferred_reload_class
                       (op, this_alternative) == NO_REGS)
-                     || no_input_reloads_p)
-                 && get_op_mode (nop) != VOIDmode)
+                     || no_input_reloads_p))
                {
                  const_to_mem = 1;
                  if (! no_regs_p)
@@ -2824,6 +2787,9 @@ emit_inc (enum reg_class new_rclass, rtx
 static inline void
 swap_operands (int nop)
 {
+  enum machine_mode mode = curr_operand_mode[nop];
+  curr_operand_mode[nop] = curr_operand_mode[nop + 1];
+  curr_operand_mode[nop + 1] = mode;
   rtx x = *curr_id->operand_loc[nop];
   *curr_id->operand_loc[nop] = *curr_id->operand_loc[nop + 1];
   *curr_id->operand_loc[nop + 1] = x;
@@ -3012,20 +2978,12 @@ curr_insn_transform (void)
 
   if (goal_alt_swapped)
     {
-      rtx tem;
-
       if (lra_dump_file != NULL)
        fprintf (lra_dump_file, "  Commutative operand exchange in insn %u\n",
                 INSN_UID (curr_insn));
 
-      tem = *curr_id->operand_loc[commutative];
-      *curr_id->operand_loc[commutative]
-       = *curr_id->operand_loc[commutative + 1];
-      *curr_id->operand_loc[commutative + 1] = tem;
-
       /* Swap the duplicates too.  */
-      lra_update_dup (curr_id, commutative);
-      lra_update_dup (curr_id, commutative + 1);
+      swap_operands (commutative);
       change_p = true;
     }
 
@@ -3148,7 +3106,7 @@ curr_insn_transform (void)
        char c;
        rtx op = *curr_id->operand_loc[i];
        rtx subreg = NULL_RTX;
-       enum machine_mode mode = get_op_mode (i);
+       enum machine_mode mode = curr_operand_mode[i];
        
        if (GET_CODE (op) == SUBREG)
          {
@@ -3160,8 +3118,7 @@ curr_insn_transform (void)
        if (CONST_POOL_OK_P (mode, op)
            && ((targetm.preferred_reload_class
                 (op, (enum reg_class) goal_alt[i]) == NO_REGS)
-               || no_input_reloads_p)
-           && mode != VOIDmode)
+               || no_input_reloads_p))
          {
            rtx tem = force_const_mem (mode, op);
            
@@ -3255,7 +3212,7 @@ curr_insn_transform (void)
          enum op_type type = curr_static_id->operand[i].type;
 
          loc = curr_id->operand_loc[i];
-         mode = get_op_mode (i);
+         mode = curr_operand_mode[i];
          if (GET_CODE (*loc) == SUBREG)
            {
              reg = SUBREG_REG (*loc);
@@ -3702,6 +3659,7 @@ lra_constraints (bool first_p)
          curr_id = lra_get_insn_recog_data (curr_insn);
          curr_static_id = curr_id->insn_static_data;
          init_curr_insn_input_reloads ();
+         init_curr_operand_mode ();
          if (curr_insn_transform ())
            changed_p = true;
        }

Reply via email to