Commit a78cc314 by Robert Suchanek Committed by Matthew Fortune

Enable LRA for MIPS

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
parent 30256bef
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>
......
......@@ -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.")
......
......@@ -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;
}
/* 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;
#include "gt-mips.h"
......@@ -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
......
......@@ -1624,40 +1624,66 @@
;; 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.
......@@ -1861,20 +1887,31 @@
;; 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.
......@@ -4141,7 +4178,10 @@
[(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)))
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment