]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Enable LRA for MIPS
authorRobert Suchanek <robert.suchanek@imgtec.com>
Wed, 18 Jun 2014 20:40:34 +0000 (20:40 +0000)
committerMatthew Fortune <mpf@gcc.gnu.org>
Wed, 18 Jun 2014 20:40:34 +0000 (20:40 +0000)
gcc/

* config/mips/constraints.md ("d"): BASE_REG_CLASS replaced by
"TARGET_MIPS16 ? M16_REGS : GR_REGS".
* config/mips/mips.c (mips_regno_to_class): Update for M16_SP_REGS.
(mips_regno_mode_ok_for_base_p): Remove use of !strict_p for MIPS16.
(mips_register_priority): New function that implements the target
hook TARGET_REGISTER_PRIORITY.
(mips_spill_class): Likewise for TARGET_SPILL_CLASS.
(mips_lra_p): Likewise for TARGET_LRA_P.
(TARGET_REGISTER_PRIORITY): Define macro.
(TARGET_SPILL_CLASS): Likewise.
(TARGET_LRA_P): Likewise.
* config/mips/mips.h (reg_class): Add M16_SP_REGS and SPILL_REGS
classes.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(BASE_REG_CLASS): Use M16_SP_REGS.
* config/mips/mips.md (*mul_acc_si): Add alternative tuned for LRA.
New set attribute to enable alternatives depending on the register
allocator used.
(*mul_acc_si_r3900, *mul_sub_si): Likewise.
(*lea64): Disable pattern for MIPS16.
* config/mips/mips.opt (mlra): New option.

From-SVN: r211805

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/mips.opt

index cdc49917ae53f25c7438cf10cdffc2984548c482..9f790251cdcb20d04cf792d92033985e2efa925a 100644 (file)
@@ -1,7 +1,32 @@
 2014-06-18  Robert Suchanek  <robert.suchanek@imgtec.com>
 
-       * lra-constraints.c (base_to_reg): New function.
-       (process_address): Use new function.
+       * config/mips/constraints.md ("d"): BASE_REG_CLASS replaced by
+       "TARGET_MIPS16 ? M16_REGS : GR_REGS".
+       * config/mips/mips.c (mips_regno_to_class): Update for M16_SP_REGS.
+       (mips_regno_mode_ok_for_base_p): Remove use of !strict_p for MIPS16.
+       (mips_register_priority): New function that implements the target
+       hook TARGET_REGISTER_PRIORITY.
+       (mips_spill_class): Likewise for TARGET_SPILL_CLASS.
+       (mips_lra_p): Likewise for TARGET_LRA_P.
+       (TARGET_REGISTER_PRIORITY): Define macro.
+       (TARGET_SPILL_CLASS): Likewise.
+       (TARGET_LRA_P): Likewise.
+       * config/mips/mips.h (reg_class): Add M16_SP_REGS and SPILL_REGS
+       classes.
+       (REG_CLASS_NAMES): Likewise.
+       (REG_CLASS_CONTENTS): Likewise.
+       (BASE_REG_CLASS): Use M16_SP_REGS.
+       * config/mips/mips.md (*mul_acc_si): Add alternative tuned for LRA.
+       New set attribute to enable alternatives depending on the register
+       allocator used.
+       (*mul_acc_si_r3900, *mul_sub_si): Likewise.
+       (*lea64): Disable pattern for MIPS16.
+       * config/mips/mips.opt (mlra): New option.
+
+2014-06-18  Robert Suchanek  <robert.suchanek@imgtec.com>
+
+       * lra-constraints.c (base_to_reg): New function.       
+       (process_address): Use new function.                   
 
 2014-06-18  Tom de Vries  <tom@codesourcery.com>
 
index f6834fd1e9415a5855759f1edfdb63c8632a5365..fa33c305f8a869cd7f5884236517704763641a74 100644 (file)
@@ -19,7 +19,7 @@
 
 ;; Register constraints
 
-(define_register_constraint "d" "BASE_REG_CLASS"
+(define_register_constraint "d" "TARGET_MIPS16 ? M16_REGS : GR_REGS"
   "An address register.  This is equivalent to @code{r} unless
    generating MIPS16 code.")
 
index cff1d3817c7e80df0e7c5789a9c5812f7f5a6e11..1b1633ce046be51d049f743f90514a783a4bc583 100644 (file)
@@ -661,7 +661,7 @@ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   M16_REGS,        M16_STORE_REGS,  LEA_REGS,        LEA_REGS,
   LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
   T_REG,           PIC_FN_ADDR_REG, LEA_REGS,        LEA_REGS,
-  LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
+  LEA_REGS,        M16_SP_REGS,     LEA_REGS,        LEA_REGS,
 
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
@@ -2260,22 +2260,9 @@ mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode,
     return true;
 
   /* In MIPS16 mode, the stack pointer can only address word and doubleword
-     values, nothing smaller.  There are two problems here:
-
-       (a) Instantiating virtual registers can introduce new uses of the
-          stack pointer.  If these virtual registers are valid addresses,
-          the stack pointer should be too.
-
-       (b) Most uses of the stack pointer are not made explicit until
-          FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
-          We don't know until that stage whether we'll be eliminating to the
-          stack pointer (which needs the restriction) or the hard frame
-          pointer (which doesn't).
-
-     All in all, it seems more consistent to only enforce this restriction
-     during and after reload.  */
+     values, nothing smaller.  */
   if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
-    return !strict_p || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
+    return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
 
   return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
 }
@@ -12100,6 +12087,18 @@ mips_register_move_cost (enum machine_mode mode,
   return 0;
 }
 
+/* Implement TARGET_REGISTER_PRIORITY.  */
+
+static int
+mips_register_priority (int hard_regno)
+{
+  /* Treat MIPS16 registers with higher priority than other regs.  */
+  if (TARGET_MIPS16
+      && TEST_HARD_REG_BIT (reg_class_contents[M16_REGS], hard_regno))
+    return 1;
+  return 0;
+}
+
 /* Implement TARGET_MEMORY_MOVE_COST.  */
 
 static int
@@ -18898,6 +18897,25 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
                    atomic_feraiseexcept_call);
 }
+
+/* Implement TARGET_SPILL_CLASS.  */
+
+static reg_class_t
+mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED,
+                 enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  if (TARGET_MIPS16)
+    return SPILL_REGS;
+  return NO_REGS;
+}
+
+/* Implement TARGET_LRA_P.  */
+
+static bool
+mips_lra_p (void)
+{
+  return mips_lra_flag;
+}
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
@@ -18961,6 +18979,8 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
 #undef TARGET_REGISTER_MOVE_COST
 #define TARGET_REGISTER_MOVE_COST mips_register_move_cost
+#undef TARGET_REGISTER_PRIORITY
+#define TARGET_REGISTER_PRIORITY mips_register_priority
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost
 #undef TARGET_RTX_COSTS
@@ -19138,6 +19158,11 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
 
+#undef TARGET_SPILL_CLASS
+#define TARGET_SPILL_CLASS mips_spill_class
+#undef TARGET_LRA_P
+#define TARGET_LRA_P mips_lra_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 #include "gt-mips.h"
index 38eea44c407e62c419939cbcef6205d31ce6f5df..7029e046f9a248a3b18bf15e99a9ddfe3dcc263d 100644 (file)
@@ -1869,10 +1869,12 @@ enum reg_class
   NO_REGS,                     /* no registers in set */
   M16_STORE_REGS,              /* microMIPS store registers  */
   M16_REGS,                    /* mips16 directly accessible registers */
+  M16_SP_REGS,                 /* mips16 + $sp */
   T_REG,                       /* mips16 T register ($24) */
   M16_T_REGS,                  /* mips16 registers plus T register */
   PIC_FN_ADDR_REG,             /* SVR4 PIC function address register */
   V1_REG,                      /* Register $v1 ($3) used for TLS access.  */
+  SPILL_REGS,                  /* All but $sp and call preserved regs are in here */
   LEA_REGS,                    /* Every GPR except $25 */
   GR_REGS,                     /* integer registers */
   FP_REGS,                     /* floating point registers */
@@ -1907,10 +1909,12 @@ enum reg_class
   "NO_REGS",                                                           \
   "M16_STORE_REGS",                                                    \
   "M16_REGS",                                                          \
+  "M16_SP_REGS",                                                               \
   "T_REG",                                                             \
   "M16_T_REGS",                                                                \
   "PIC_FN_ADDR_REG",                                                   \
   "V1_REG",                                                            \
+  "SPILL_REGS",                                                                \
   "LEA_REGS",                                                          \
   "GR_REGS",                                                           \
   "FP_REGS",                                                           \
@@ -1948,10 +1952,12 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* NO_REGS */           \
   { 0x000200fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_STORE_REGS */    \
   { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_REGS */          \
+  { 0x200300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_SP_REGS */               \
   { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* T_REG */             \
   { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* M16_T_REGS */        \
   { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* PIC_FN_ADDR_REG */   \
   { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* V1_REG */            \
+  { 0x0303fffc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* SPILL_REGS */        \
   { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* LEA_REGS */          \
   { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* GR_REGS */           \
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* FP_REGS */           \
@@ -1984,7 +1990,7 @@ enum reg_class
    valid base register must belong.  A base register is one used in
    an address which is the register value plus a displacement.  */
 
-#define BASE_REG_CLASS  (TARGET_MIPS16 ? M16_REGS : GR_REGS)
+#define BASE_REG_CLASS  (TARGET_MIPS16 ? M16_SP_REGS : GR_REGS)
 
 /* A macro whose definition is the name of the class to which a
    valid index register must belong.  An index register is one used
index 9912ddcb63a30fcea2db2d4f1b85ca19134b6752..7e23bd210660dc3e23f0d1bf71dac23956f7ae8f 100644 (file)
 ;; copy instructions.  Reload therefore thinks that the second alternative
 ;; is two reloads more costly than the first.  We add "*?*?" to the first
 ;; alternative as a counterweight.
+;;
+;; LRA simulates reload but the cost of reloading scratches is lower
+;; than of the classic reload. For the time being, removing the counterweight
+;; for LRA is more profitable.
 (define_insn "*mul_acc_si"
-  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
-       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
-                         (match_operand:SI 2 "register_operand" "d,d"))
-                (match_operand:SI 3 "register_operand" "0,d")))
-   (clobber (match_scratch:SI 4 "=X,l"))
-   (clobber (match_scratch:SI 5 "=X,&d"))]
+  [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
+       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
+                         (match_operand:SI 2 "register_operand" "d,d,d"))
+                (match_operand:SI 3 "register_operand" "0,0,d")))
+   (clobber (match_scratch:SI 4 "=X,X,l"))
+   (clobber (match_scratch:SI 5 "=X,X,&d"))]
   "GENERATE_MADD_MSUB && !TARGET_MIPS16"
   "@
+    madd\t%1,%2
     madd\t%1,%2
     #"
   [(set_attr "type"    "imadd")
    (set_attr "accum_in"        "3")
    (set_attr "mode"    "SI")
-   (set_attr "insn_count" "1,2")])
+   (set_attr "insn_count" "1,1,2")
+   (set (attr "enabled")
+        (cond [(and (eq_attr "alternative" "0")
+                    (match_test "!mips_lra_flag"))
+                  (const_string "yes")
+               (and (eq_attr "alternative" "1")
+                    (match_test "mips_lra_flag"))
+                  (const_string "yes")
+               (eq_attr "alternative" "2")
+                  (const_string "yes")]
+              (const_string "no")))])
 
 ;; The same idea applies here.  The middle alternative needs one less
 ;; clobber than the final alternative, so we add "*?" as a counterweight.
 (define_insn "*mul_acc_si_r3900"
-  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?")
-       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
-                         (match_operand:SI 2 "register_operand" "d,d,d"))
-                (match_operand:SI 3 "register_operand" "0,l,d")))
-   (clobber (match_scratch:SI 4 "=X,3,l"))
-   (clobber (match_scratch:SI 5 "=X,X,&d"))]
+  [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d*?,d?")
+       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
+                         (match_operand:SI 2 "register_operand" "d,d,d,d"))
+                (match_operand:SI 3 "register_operand" "0,0,l,d")))
+   (clobber (match_scratch:SI 4 "=X,X,3,l"))
+   (clobber (match_scratch:SI 5 "=X,X,X,&d"))]
   "TARGET_MIPS3900 && !TARGET_MIPS16"
   "@
+    madd\t%1,%2
     madd\t%1,%2
     madd\t%0,%1,%2
     #"
   [(set_attr "type"    "imadd")
    (set_attr "accum_in"        "3")
    (set_attr "mode"    "SI")
-   (set_attr "insn_count" "1,1,2")])
+   (set_attr "insn_count" "1,1,1,2")
+   (set (attr "enabled")
+        (cond [(and (eq_attr "alternative" "0")
+                    (match_test "!mips_lra_flag"))
+                  (const_string "yes")
+               (and (eq_attr "alternative" "1")
+                    (match_test "mips_lra_flag"))
+                  (const_string "yes")
+               (eq_attr "alternative" "2,3")
+                  (const_string "yes")]
+              (const_string "no")))])
 
 ;; Split *mul_acc_si if both the source and destination accumulator
 ;; values are GPRs.
 
 ;; See the comment above *mul_add_si for details.
 (define_insn "*mul_sub_si"
-  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
-        (minus:SI (match_operand:SI 1 "register_operand" "0,d")
-                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
-                           (match_operand:SI 3 "register_operand" "d,d"))))
-   (clobber (match_scratch:SI 4 "=X,l"))
-   (clobber (match_scratch:SI 5 "=X,&d"))]
+  [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
+        (minus:SI (match_operand:SI 1 "register_operand" "0,0,d")
+                  (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
+                           (match_operand:SI 3 "register_operand" "d,d,d"))))
+   (clobber (match_scratch:SI 4 "=X,X,l"))
+   (clobber (match_scratch:SI 5 "=X,X,&d"))]
   "GENERATE_MADD_MSUB"
   "@
+   msub\t%2,%3
    msub\t%2,%3
    #"
   [(set_attr "type"     "imadd")
    (set_attr "accum_in"        "1")
    (set_attr "mode"     "SI")
-   (set_attr "insn_count" "1,2")])
+   (set_attr "insn_count" "1,1,2")
+   (set (attr "enabled")
+        (cond [(and (eq_attr "alternative" "0")
+                    (match_test "!mips_lra_flag"))
+                  (const_string "yes")
+               (and (eq_attr "alternative" "1")
+                    (match_test "mips_lra_flag"))
+                  (const_string "yes")
+               (eq_attr "alternative" "2")
+                  (const_string "yes")]
+              (const_string "no")))])
 
 ;; Split *mul_sub_si if both the source and destination accumulator
 ;; values are GPRs.
   [(set (match_operand:DI 0 "register_operand" "=d")
        (match_operand:DI 1 "absolute_symbolic_operand" ""))
    (clobber (match_scratch:DI 2 "=&d"))]
-  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
+  "!TARGET_MIPS16
+   && TARGET_EXPLICIT_RELOCS
+   && ABI_HAS_64BIT_SYMBOLS
+   && cse_not_expected"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (high:DI (match_dup 3)))
index c992ceeb71d64eb94810b2c1e56146791551cfe4..dca4f8089452a77bef39a5d6944b39dca4dd045b 100644 (file)
@@ -380,6 +380,10 @@ msynci
 Target Report Mask(SYNCI)
 Use synci instruction to invalidate i-cache
 
+mlra
+Target Report Var(mips_lra_flag) Init(1) Save
+Use LRA instead of reload
+
 mtune=
 Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value)
 -mtune=PROCESSOR       Optimize the output for PROCESSOR