Extend special_memory_constraint.
authorliuhongt <hongtao.liu@intel.com>
Sat, 26 Sep 2020 07:08:32 +0000 (15:08 +0800)
committerliuhongt <hongtao.liu@intel.com>
Thu, 22 Oct 2020 02:28:56 +0000 (10:28 +0800)
For operand with special_memory_constraint, there could be a wrapper
for memory_operand. Extract mem for operand for conditional judgement
like MEM_P, also for record_address_regs.

gcc/ChangeLog:

PR target/87767
* ira-costs.c (record_operand_costs): Extract memory operand
from recog_data.operand[i] for record_address_regs.
(record_reg_classes): Extract memory operand from OP for
conditional judgement MEM_P.
* ira.c (ira_setup_alts): Ditto.
* lra-constraints.c (extract_mem_from_operand): New function.
(satisfies_memory_constraint_p): Extract memory operand from
OP for decompose_mem_address, return false when there's no
memory operand inside OP.
(process_alt_operands): Remove MEM_P (op) since it would be
judged in satisfies_memory_constraint_p.
* recog.c (asm_operand_ok): Extract memory operand from OP for
judgement of memory_operand (OP, VOIDmode).
(constrain_operands): Don't unwrapper unary operator when
there's memory operand inside.
* rtl.h (extract_mem_from_operand): New decl.

gcc/ira-costs.c
gcc/ira.c
gcc/lra-constraints.c
gcc/recog.c
gcc/rtl.h

index 6891156b5aaa6cdc7d43e536a74e077e216eef0c..aeda6588bcd8ee0959c22e7fecb10ee30a8b25ec 100644 (file)
@@ -781,7 +781,8 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
 
                    case CT_SPECIAL_MEMORY:
                      insn_allows_mem[i] = allows_mem[i] = 1;
-                     if (MEM_P (op) && constraint_satisfied_p (op, cn))
+                     if (MEM_P (extract_mem_from_operand (op))
+                         && constraint_satisfied_p (op, cn))
                        win = 1;
                      break;
 
@@ -1397,15 +1398,16 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
      commutative.  */
   for (i = 0; i < recog_data.n_operands; i++)
     {
+      rtx op_mem = extract_mem_from_operand (recog_data.operand[i]);
       memcpy (op_costs[i], init_cost, struct_costs_size);
 
       if (GET_CODE (recog_data.operand[i]) == SUBREG)
        recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
 
-      if (MEM_P (recog_data.operand[i]))
-       record_address_regs (GET_MODE (recog_data.operand[i]),
-                            MEM_ADDR_SPACE (recog_data.operand[i]),
-                            XEXP (recog_data.operand[i], 0),
+      if (MEM_P (op_mem))
+       record_address_regs (GET_MODE (op_mem),
+                            MEM_ADDR_SPACE (op_mem),
+                            XEXP (op_mem, 0),
                             0, MEM, SCRATCH, frequency * 2);
       else if (constraints[i][0] == 'p'
               || (insn_extra_address_constraint
index 27d1b3c857d5d399062bffedffd56c6e7b2df3b4..a61138c6e94d4dc3858dd8d978fc0dff04d8f862 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1868,7 +1868,7 @@ ira_setup_alts (rtx_insn *insn)
 
                        case CT_MEMORY:
                        case CT_SPECIAL_MEMORY:
-                         if (MEM_P (op))
+                         if (MEM_P (extract_mem_from_operand (op)))
                            goto op_success;
                          win_p = true;
                          break;
index f761d7dfe3c2350cf551ed3767fa7b31d432310d..b5c010d503013ad4f693de0a0f32c4fff1744fca 100644 (file)
@@ -416,14 +416,34 @@ valid_address_p (rtx op, struct address_info *ad,
   return valid_address_p (ad->mode, *ad->outer, ad->as);
 }
 
+/* For special_memory_operand, it could be false for MEM_P (op),
+   i.e. bcst_mem_operand in i386 backend.
+   Extract and return real memory operand or op.  */
+rtx
+extract_mem_from_operand (rtx op)
+{
+  for (rtx x = op;; x = XEXP (x, 0))
+    {
+      if (MEM_P (x))
+       return x;
+      if (GET_RTX_LENGTH (GET_CODE (x)) != 1
+         || GET_RTX_FORMAT (GET_CODE (x))[0] != 'e')
+       break;
+    }
+  return op;
+}
+
 /* Return true if the eliminated form of memory reference OP satisfies
    extra (special) memory constraint CONSTRAINT.  */
 static bool
 satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
 {
   struct address_info ad;
+  rtx mem = extract_mem_from_operand (op);
+  if (!MEM_P (mem))
+    return false;
 
-  decompose_mem_address (&ad, op);
+  decompose_mem_address (&ad, mem);
   address_eliminator eliminator (&ad);
   return constraint_satisfied_p (op, constraint);
 }
@@ -2406,8 +2426,7 @@ process_alt_operands (int only_alternative)
                      break;
 
                    case CT_MEMORY:
-                     if (MEM_P (op)
-                         && satisfies_memory_constraint_p (op, cn))
+                     if (satisfies_memory_constraint_p (op, cn))
                        win = true;
                      else if (spilled_pseudo_p (op))
                        win = true;
@@ -2448,8 +2467,7 @@ process_alt_operands (int only_alternative)
                      break;
 
                    case CT_SPECIAL_MEMORY:
-                     if (MEM_P (op)
-                         && satisfies_memory_constraint_p (op, cn))
+                     if (satisfies_memory_constraint_p (op, cn))
                        win = true;
                      else if (spilled_pseudo_p (op))
                        win = true;
index ce83b7f52183c503a015c06dcfb9d189cf22871c..d3552ec63eb26c38817931468d8fbf7df4084470 100644 (file)
@@ -1798,7 +1798,8 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
            case CT_MEMORY:
            case CT_SPECIAL_MEMORY:
              /* Every memory operand can be reloaded to fit.  */
-             result = result || memory_operand (op, VOIDmode);
+             result = result || memory_operand (extract_mem_from_operand (op),
+                                                VOIDmode);
              break;
 
            case CT_ADDRESS:
@@ -2584,7 +2585,9 @@ constrain_operands (int strict, alternative_mask alternatives)
 
          /* A unary operator may be accepted by the predicate, but it
             is irrelevant for matching constraints.  */
-         if (UNARY_P (op))
+         /* For special_memory_operand, there could be a memory operand inside,
+            and it would cause a mismatch for constraint_satisfied_p.  */
+         if (UNARY_P (op) && op == extract_mem_from_operand (op))
            op = XEXP (op, 0);
 
          if (GET_CODE (op) == SUBREG)
index 0872cc408eb177f42083204764e69b2268cf0840..fcec9dc6387226a4edb364cdd1f808eafbbb3e57 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -4324,6 +4324,7 @@ extern rtx gen_hard_reg_clobber (machine_mode, unsigned int);
 extern rtx get_reg_known_value (unsigned int);
 extern bool get_reg_known_equiv_p (unsigned int);
 extern rtx get_reg_base_value (unsigned int);
+extern rtx extract_mem_from_operand (rtx);
 
 #ifdef STACK_REGS
 extern int stack_regs_mentioned (const_rtx insn);