]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/69299 (-mavx performance degradation with r232088)
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 29 Jan 2016 18:47:17 +0000 (18:47 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 29 Jan 2016 18:47:17 +0000 (18:47 +0000)
2016-01-29  Vladimir Makarov  <vmakarov@redhat.com>

PR target/69299
* config/i386/constraints.md (Bm): Describe as special memory
constraint.
* doc/md.texi (DEFINE_SPECIAL_MEMORY_CONSTRAINT): Describe it.
* genoutput.c (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
* genpreds.c (struct constraint_data): Add is_special_memory.
(have_special_memory_constraints, special_memory_start): New
static vars.
(special_memory_end): Ditto.
(add_constraint): Add new arg is_special_memory.  Add code to
process its true value.  Update have_special_memory_constraints.
(process_define_constraint): Pass the new arg.
(process_define_register_constraint): Ditto.
(choose_enum_order): Process special memory.
(write_tm_preds_h): Generate enum const CT_SPECIAL_MEMORY and
function insn_extra_special_memory_constraint.
(main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
* gensupport.c (process_rtx): Process
DEFINE_SPECIAL_MEMORY_CONSTRAINT.
* ira-costs.c (record_reg_classes): Process CT_SPECIAL_MEMORY.
* ira-lives.c (single_reg_class): Use
insn_extra_special_memory_constraint.
* ira.c (ira_setup_alts): Process CT_SPECIAL_MEMORY.
* lra-constraints.c (process_alt_operands): Ditto.
(curr_insn_transform): Use insn_extra_special_memory_constraint.
* recog.c (asm_operand_ok, preprocess_constraints): Process
CT_SPECIAL_MEMORY.
* reload.c (find_reloads): Ditto.
* rtl.def (DEFINE_SPECIFAL_MEMORY_CONSTRAINT): New.
* stmt.c (parse_input_constraint): Use
insn_extra_special_memory_constraint.

From-SVN: r232993

14 files changed:
gcc/ChangeLog
gcc/config/i386/constraints.md
gcc/doc/md.texi
gcc/genoutput.c
gcc/genpreds.c
gcc/gensupport.c
gcc/ira-costs.c
gcc/ira-lives.c
gcc/ira.c
gcc/lra-constraints.c
gcc/recog.c
gcc/reload.c
gcc/rtl.def
gcc/stmt.c

index 48fdab630fa4bb0eaf6a86578075c974cf229601..2919b8134ef677eba87a4d295cd09f8313302d43 100644 (file)
@@ -1,3 +1,37 @@
+2016-01-29  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/69299
+       * config/i386/constraints.md (Bm): Describe as special memory
+       constraint.
+       * doc/md.texi (DEFINE_SPECIAL_MEMORY_CONSTRAINT): Describe it.
+       * genoutput.c (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
+       * genpreds.c (struct constraint_data): Add is_special_memory.
+       (have_special_memory_constraints, special_memory_start): New
+       static vars.
+       (special_memory_end): Ditto.
+       (add_constraint): Add new arg is_special_memory.  Add code to
+       process its true value.  Update have_special_memory_constraints.
+       (process_define_constraint): Pass the new arg.
+       (process_define_register_constraint): Ditto.
+       (choose_enum_order): Process special memory.
+       (write_tm_preds_h): Generate enum const CT_SPECIAL_MEMORY and
+       function insn_extra_special_memory_constraint.
+       (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
+       * gensupport.c (process_rtx): Process
+       DEFINE_SPECIAL_MEMORY_CONSTRAINT.
+       * ira-costs.c (record_reg_classes): Process CT_SPECIAL_MEMORY.
+       * ira-lives.c (single_reg_class): Use
+       insn_extra_special_memory_constraint.
+       * ira.c (ira_setup_alts): Process CT_SPECIAL_MEMORY.
+       * lra-constraints.c (process_alt_operands): Ditto.
+       (curr_insn_transform): Use insn_extra_special_memory_constraint.
+       * recog.c (asm_operand_ok, preprocess_constraints): Process
+       CT_SPECIAL_MEMORY.
+       * reload.c (find_reloads): Ditto.
+       * rtl.def (DEFINE_SPECIFAL_MEMORY_CONSTRAINT): New.
+       * stmt.c (parse_input_constraint): Use
+       insn_extra_special_memory_constraint.
+
 2016-01-29  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/69530
index 3b0b7c79dc11010219288fb48dcb3fbc938bb0ab..afdc546c065a4a6a03ad537a79c337e13231ebf8 100644 (file)
   "@internal GOT memory operand."
   (match_operand 0 "GOT_memory_operand"))
 
-(define_constraint "Bm"
+(define_special_memory_constraint "Bm"
   "@internal Vector memory operand."
   (match_operand 0 "vector_memory_operand"))
 
index 3c11d1944b8e212fb049381b8f11f42334fb80f9..864824f2f0dbb0440317a81848d9aff0414bc6f2 100644 (file)
@@ -4424,6 +4424,20 @@ The syntax and semantics are otherwise identical to
 @code{define_constraint}.
 @end deffn
 
+@deffn {MD Expression} define_special_memory_constraint name docstring exp
+Use this expression for constraints that match a subset of all memory
+operands: that is, @code{reload} can not make them match by reloading
+the address as it is described for @code{define_memory_constraint} or
+such address reload is undesirable with the performance point of view.
+
+For example, @code{define_special_memory_constraint} can be useful if
+specifically aligned memory is necessary or desirable for some insn
+operand.
+
+The syntax and semantics are otherwise identical to
+@code{define_constraint}.
+@end deffn
+
 @deffn {MD Expression} define_address_constraint name docstring exp
 Use this expression for constraints that match a subset of all address
 operands: that is, @code{reload} can make the constraint match by
index 1c620c3f8d5fc390c40425e57b638ed72ca5f864..6ca1bb89cf7209f7decd155fc1890680419cd9b8 100644 (file)
@@ -1019,6 +1019,7 @@ main (int argc, char **argv)
       case DEFINE_REGISTER_CONSTRAINT:
       case DEFINE_ADDRESS_CONSTRAINT:
       case DEFINE_MEMORY_CONSTRAINT:
+      case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
        note_constraint (&info);
        break;
 
index 84c41a16034c6fb8b595286999d035dce4e7ad24..c0d7ce4146cb49acd1c06fe9aef08b0b11d09665 100644 (file)
@@ -659,11 +659,11 @@ write_one_predicate_function (struct pred_data *p)
 \f
 /* Constraints fall into two categories: register constraints
    (define_register_constraint), and others (define_constraint,
-   define_memory_constraint, define_address_constraint).  We
-   work out automatically which of the various old-style macros
-   they correspond to, and produce appropriate code.  They all
-   go in the same hash table so we can verify that there are no
-   duplicate names.  */
+   define_memory_constraint, define_special_memory_constraint,
+   define_address_constraint).  We work out automatically which of the
+   various old-style macros they correspond to, and produce
+   appropriate code.  They all go in the same hash table so we can
+   verify that there are no duplicate names.  */
 
 /* All data from one constraint definition.  */
 struct constraint_data
@@ -681,6 +681,7 @@ struct constraint_data
   unsigned int is_const_dbl    : 1;
   unsigned int is_extra                : 1;
   unsigned int is_memory       : 1;
+  unsigned int is_special_memory: 1;
   unsigned int is_address      : 1;
   unsigned int maybe_allows_reg : 1;
   unsigned int maybe_allows_mem : 1;
@@ -718,6 +719,7 @@ static const char const_dbl_constraints[] = "GH";
 static unsigned int constraint_max_namelen;
 static bool have_register_constraints;
 static bool have_memory_constraints;
+static bool have_special_memory_constraints;
 static bool have_address_constraints;
 static bool have_extra_constraints;
 static bool have_const_int_constraints;
@@ -728,6 +730,7 @@ static unsigned int register_start, register_end;
 static unsigned int satisfied_start;
 static unsigned int const_int_start, const_int_end;
 static unsigned int memory_start, memory_end;
+static unsigned int special_memory_start, special_memory_end;
 static unsigned int address_start, address_end;
 static unsigned int maybe_allows_none_start, maybe_allows_none_end;
 static unsigned int maybe_allows_reg_start, maybe_allows_reg_end;
@@ -754,20 +757,22 @@ mangle (const char *name)
 
 /* Add one constraint, of any sort, to the tables.  NAME is its name;
    REGCLASS is the register class, if any; EXP is the expression to
-   test, if any;  IS_MEMORY and IS_ADDRESS indicate memory and address
-   constraints, respectively; LOC is the .md file location.
+   test, if any; IS_MEMORY, IS_SPECIAL_MEMORY and IS_ADDRESS indicate
+   memory, special memory, and address constraints, respectively; LOC
+   is the .md file location.
 
-   Not all combinations of arguments are valid; most importantly, REGCLASS
-   is mutually exclusive with EXP, and IS_MEMORY/IS_ADDRESS are only
-   meaningful for constraints with EXP.
+   Not all combinations of arguments are valid; most importantly,
+   REGCLASS is mutually exclusive with EXP, and
+   IS_MEMORY/IS_SPECIAL_MEMORY/IS_ADDRESS are only meaningful for
+   constraints with EXP.
 
    This function enforces all syntactic and semantic rules about what
    constraints can be defined.  */
 
 static void
 add_constraint (const char *name, const char *regclass,
-               rtx exp, bool is_memory, bool is_address,
-               file_location loc)
+               rtx exp, bool is_memory, bool is_special_memory,
+               bool is_address, file_location loc)
 {
   struct constraint_data *c, **iter, **slot;
   const char *p;
@@ -878,6 +883,17 @@ add_constraint (const char *name, const char *regclass,
                      name, name[0]);
          return;
        }
+      else if (is_special_memory)
+       {
+         if (name[1] == '\0')
+           error_at (loc, "constraint letter '%c' cannot be a "
+                     "special memory constraint", name[0]);
+         else
+           error_at (loc, "constraint name '%s' begins with '%c', "
+                     "and therefore cannot be a special memory constraint",
+                     name, name[0]);
+         return;
+       }
       else if (is_address)
        {
          if (name[1] == '\0')
@@ -904,6 +920,7 @@ add_constraint (const char *name, const char *regclass,
   c->is_const_dbl = is_const_dbl;
   c->is_extra = !(regclass || is_const_int || is_const_dbl);
   c->is_memory = is_memory;
+  c->is_special_memory = is_special_memory;
   c->is_address = is_address;
   c->maybe_allows_reg = true;
   c->maybe_allows_mem = true;
@@ -930,17 +947,20 @@ add_constraint (const char *name, const char *regclass,
   have_const_int_constraints |= c->is_const_int;
   have_extra_constraints |= c->is_extra;
   have_memory_constraints |= c->is_memory;
+  have_special_memory_constraints |= c->is_special_memory;
   have_address_constraints |= c->is_address;
   num_constraints += 1;
 }
 
-/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
-   DEFINE_ADDRESS_CONSTRAINT expression, C.  */
+/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT,
+   DEFINE_SPECIAL_MEMORY_CONSTRAINT, or DEFINE_ADDRESS_CONSTRAINT
+   expression, C.  */
 static void
 process_define_constraint (md_rtx_info *info)
 {
   add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
                  GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
+                 GET_CODE (info->def) == DEFINE_SPECIAL_MEMORY_CONSTRAINT,
                  GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
                  info->loc);
 }
@@ -950,7 +970,7 @@ static void
 process_define_register_constraint (md_rtx_info *info)
 {
   add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
-                 0, false, false, info->loc);
+                 0, false, false, false, info->loc);
 }
 
 /* Put the constraints into enum order.  We want to keep constraints
@@ -984,6 +1004,12 @@ choose_enum_order (void)
       enum_order[next++] = c;
   memory_end = next;
 
+  special_memory_start = next;
+  FOR_ALL_CONSTRAINTS (c)
+    if (c->is_special_memory)
+      enum_order[next++] = c;
+  special_memory_end = next;
+
   address_start = next;
   FOR_ALL_CONSTRAINTS (c)
     if (c->is_address)
@@ -992,27 +1018,31 @@ choose_enum_order (void)
 
   maybe_allows_none_start = next;
   FOR_ALL_CONSTRAINTS (c)
-    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
+    if (!c->is_register && !c->is_const_int && !c->is_memory
+       && !c->is_special_memory && !c->is_address
        && !c->maybe_allows_reg && !c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_none_end = next;
 
   maybe_allows_reg_start = next;
   FOR_ALL_CONSTRAINTS (c)
-    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
+    if (!c->is_register && !c->is_const_int && !c->is_memory
+       && !c->is_special_memory && !c->is_address
        && c->maybe_allows_reg && !c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_reg_end = next;
 
   maybe_allows_mem_start = next;
   FOR_ALL_CONSTRAINTS (c)
-    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
+    if (!c->is_register && !c->is_const_int && !c->is_memory
+       && !c->is_special_memory && !c->is_address
        && !c->maybe_allows_reg && c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_mem_end = next;
 
   FOR_ALL_CONSTRAINTS (c)
-    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
+    if (!c->is_register && !c->is_const_int && !c->is_memory
+       && !c->is_special_memory && !c->is_address
        && c->maybe_allows_reg && c->maybe_allows_mem)
       enum_order[next++] = c;
   gcc_assert (next == num_constraints);
@@ -1431,6 +1461,8 @@ write_tm_preds_h (void)
                            register_start, register_end);
       write_range_function ("insn_extra_memory_constraint",
                            memory_start, memory_end);
+      write_range_function ("insn_extra_special_memory_constraint",
+                           special_memory_start, special_memory_end);
       write_range_function ("insn_extra_address_constraint",
                            address_start, address_end);
       write_allows_reg_mem_function ();
@@ -1479,6 +1511,7 @@ write_tm_preds_h (void)
            "  CT_REGISTER,\n"
            "  CT_CONST_INT,\n"
            "  CT_MEMORY,\n"
+           "  CT_SPECIAL_MEMORY,\n"
            "  CT_ADDRESS,\n"
            "  CT_FIXED_FORM\n"
            "};\n"
@@ -1491,6 +1524,8 @@ write_tm_preds_h (void)
        values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT"));
       if (memory_start != memory_end)
        values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
+      if (special_memory_start != special_memory_end)
+       values.safe_push (std::make_pair (special_memory_start, "CT_SPECIAL_MEMORY"));
       if (address_start != address_end)
        values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
       if (address_end != num_constraints)
@@ -1602,6 +1637,7 @@ main (int argc, char **argv)
 
       case DEFINE_CONSTRAINT:
       case DEFINE_MEMORY_CONSTRAINT:
+      case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
       case DEFINE_ADDRESS_CONSTRAINT:
        process_define_constraint (&info);
        break;
index 596b88564c7dbeab151005e75c4439044a729377..8c5a1ab86029f44bc00a5b858983c05032013250 100644 (file)
@@ -521,6 +521,7 @@ process_rtx (rtx desc, file_location loc)
     case DEFINE_CONSTRAINT:
     case DEFINE_REGISTER_CONSTRAINT:
     case DEFINE_MEMORY_CONSTRAINT:
+    case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
     case DEFINE_ADDRESS_CONSTRAINT:
       queue_pattern (desc, &define_pred_tail, loc);
       break;
index ea5e8b1a0c339b9f64304c10ba5a709a5e8aee39..2b736c1ffd3c1aa829e7940908441eb6e0113fac 100644 (file)
@@ -783,6 +783,12 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                        win = 1;
                      break;
 
+                   case CT_SPECIAL_MEMORY:
+                     insn_allows_mem[i] = allows_mem[i] = 1;
+                     if (MEM_P (op) && constraint_satisfied_p (op, cn))
+                       win = 1;
+                     break;
+
                    case CT_ADDRESS:
                      /* Every address can be reloaded to fit.  */
                      allows_addr = 1;
index 30ef982381f97d22832e7307c6ee5282801da400..6950ffb17b31cd5e52dfd948a00645ae163f9ac9 100644 (file)
@@ -774,6 +774,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
          /* ??? Is this the best way to handle memory constraints?  */
          cn = lookup_constraint (constraints);
          if (insn_extra_memory_constraint (cn)
+             || insn_extra_special_memory_constraint (cn)
              || insn_extra_address_constraint (cn))
            return NO_REGS;
          if (constraint_satisfied_p (op, cn)
index 52596175c069555bffa216f5ed06c109c9451f94..249e2fffae7213570ba529263c3b65d9bffb6ef5 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1868,6 +1868,7 @@ ira_setup_alts (rtx_insn *insn, HARD_REG_SET &alts)
 
                        case CT_ADDRESS:
                        case CT_MEMORY:
+                       case CT_SPECIAL_MEMORY:
                          goto op_success;
 
                        case CT_FIXED_FORM:
index fb194165d497aab317f084b7db21d0d233f9fc8d..9a7121fb6afc9b3367ab005fa1e583b3bdfbd43a 100644 (file)
@@ -400,7 +400,7 @@ valid_address_p (struct address_info *ad)
 }
 
 /* Return true if the eliminated form of memory reference OP satisfies
-   extra memory constraint CONSTRAINT.  */
+   extra (special) memory constraint CONSTRAINT.  */
 static bool
 satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
 {
@@ -2038,6 +2038,14 @@ process_alt_operands (int only_alternative)
                      if (constraint_satisfied_p (op, cn))
                        win = true;
                      break;
+
+                   case CT_SPECIAL_MEMORY:
+                     if (MEM_P (op)
+                         && satisfies_memory_constraint_p (op, cn))
+                       win = true;
+                     else if (spilled_pseudo_p (op))
+                       win = true;
+                     break;
                    }
                  break;
 
@@ -3701,7 +3709,8 @@ curr_insn_transform (bool check_only_p)
                 constraint += CONSTRAINT_LEN (c, constraint))
              {
                enum constraint_num cn = lookup_constraint (constraint);
-               if (insn_extra_memory_constraint (cn)
+               if ((insn_extra_memory_constraint (cn)
+                    || insn_extra_special_memory_constraint (cn))
                    && satisfies_memory_constraint_p (tem, cn))
                  break;
              }
index 3dddbbdf4cf68b00be5b6ee0ecab727a9be9c925..92b2aa31a777b60bfd2f725d2c5d51006b971fbe 100644 (file)
@@ -1791,6 +1791,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
              break;
 
            case CT_MEMORY:
+           case CT_SPECIAL_MEMORY:
              /* Every memory operand can be reloaded to fit.  */
              result = result || memory_operand (op, VOIDmode);
              break;
@@ -2403,6 +2404,7 @@ preprocess_constraints (int n_operands, int n_alternatives,
                      break;
 
                    case CT_MEMORY:
+                   case CT_SPECIAL_MEMORY:
                      op_alt[i].memory_ok = 1;
                      break;
 
index 4646545fa6c083102cc438f6f67a6c528ebe46e9..6196e63a16c6df367921d17d4d0b6202ecd6b3a8 100644 (file)
@@ -3471,6 +3471,23 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
                        offmemok = 1;
                        break;
 
+                     case CT_SPECIAL_MEMORY:
+                       if (force_reload)
+                         break;
+                       if (constraint_satisfied_p (operand, cn))
+                         win = 1;
+                       /* Likewise if the address will be reloaded because
+                          reg_equiv_address is nonzero.  For reg_equiv_mem
+                          we have to check.  */
+                       else if (REG_P (operand)
+                                && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+                                && reg_renumber[REGNO (operand)] < 0
+                                && reg_equiv_mem (REGNO (operand)) != 0
+                                && (constraint_satisfied_p
+                                    (reg_equiv_mem (REGNO (operand)), cn)))
+                         win = 1;
+                       break;
+
                      case CT_ADDRESS:
                        if (constraint_satisfied_p (operand, cn))
                          win = 1;
index aef5036d2f7ebb37bd173ac4979e701c8349b15a..0b7f894e0d7920f6bef6932ffda66b84b1b986d5 100644 (file)
@@ -1035,6 +1035,7 @@ DEF_RTL_EXPR(DEFINE_REGISTER_CONSTRAINT, "define_register_constraint", "sss", RT
       RTL object.  */
 DEF_RTL_EXPR(DEFINE_CONSTRAINT, "define_constraint", "sse", RTX_EXTRA)
 DEF_RTL_EXPR(DEFINE_MEMORY_CONSTRAINT, "define_memory_constraint", "sse", RTX_EXTRA)
+DEF_RTL_EXPR(DEFINE_SPECIAL_MEMORY_CONSTRAINT, "define_special_memory_constraint", "sse", RTX_EXTRA)
 DEF_RTL_EXPR(DEFINE_ADDRESS_CONSTRAINT, "define_address_constraint", "sse", RTX_EXTRA)
 
 
index f9a694eafda4ba7d11cf49cd61e66afc43763b01..2e9072f4637913dc1a9aff7a2622941b692e951c 100644 (file)
@@ -434,7 +434,8 @@ parse_input_constraint (const char **constraint_p, int input_num,
        if (reg_class_for_constraint (cn) != NO_REGS
            || insn_extra_address_constraint (cn))
          *allows_reg = true;
-       else if (insn_extra_memory_constraint (cn))
+       else if (insn_extra_memory_constraint (cn)
+                || insn_extra_special_memory_constraint (cn))
          *allows_mem = true;
        else
          insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);