mips.md (JOIN_MODE): New mode iterator.

gcc/
	* config/mips/mips.md (JOIN_MODE): New mode iterator.
	(join2_load_Store<JOIN_MODE:mode>): New pattern.
	(join2_loadhi): Likewise.
	(define_peehole2): Add peephole2 patterns to join 2 HI/SI/SF/DF-mode
	load-load and store-stores.
	* config/mips/mips.opt (mload-store-pairs): New option.
	(TARGET_LOAD_STORE_PAIRS): New macro.
	* config/mips/mips.h (ENABLE_LD_ST_PAIRS): Likewise.
	* config/mips/mips-protos.h (mips_load_store_bonding_p): New prototype.
	* config/mips/mips.c (mips_load_store_bonding_p): New function.

gcc/testsuite/
	* gcc.target/mips/p5600-bonding.c : New file.

From-SVN: r223334
This commit is contained in:
Prachi Godbole 2015-05-19 05:06:03 +00:00
parent fab27f5289
commit abf96035ef
8 changed files with 220 additions and 0 deletions

View File

@ -1,3 +1,16 @@
2015-05-19 Sameera Deshpande <Sameera.Deshpande@imgtec.com>
* config/mips/mips.md (JOIN_MODE): New mode iterator.
(join2_load_Store<JOIN_MODE:mode>): New pattern.
(join2_loadhi): Likewise.
(define_peehole2): Add peephole2 patterns to join 2 HI/SI/SF/DF-mode
load-load and store-stores.
* config/mips/mips.opt (mload-store-pairs): New option.
(TARGET_LOAD_STORE_PAIRS): New macro.
* config/mips/mips.h (ENABLE_LD_ST_PAIRS): Likewise.
* config/mips/mips-protos.h (mips_load_store_bonding_p): New prototype.
* config/mips/mips.c (mips_load_store_bonding_p): New function.
2015-05-19 Mikhail Maltsev <maltsevm@gmail.com>
* bb-reorder.c (fix_up_fall_thru_edges): Use std::swap instead of

View File

@ -360,6 +360,7 @@ extern bool mips_epilogue_uses (unsigned int);
extern void mips_final_prescan_insn (rtx_insn *, rtx *, int);
extern int mips_trampoline_code_size (void);
extern void mips_function_profiler (FILE *);
extern bool mips_load_store_bonding_p (rtx *, machine_mode, bool);
typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx);
#ifdef RTX_CODE

View File

@ -18231,6 +18231,66 @@ umips_load_store_pair_p_1 (bool load_p, bool swap_p,
return true;
}
bool
mips_load_store_bonding_p (rtx *operands, machine_mode mode, bool load_p)
{
rtx reg1, reg2, mem1, mem2, base1, base2;
enum reg_class rc1, rc2;
HOST_WIDE_INT offset1, offset2;
if (load_p)
{
reg1 = operands[0];
reg2 = operands[2];
mem1 = operands[1];
mem2 = operands[3];
}
else
{
reg1 = operands[1];
reg2 = operands[3];
mem1 = operands[0];
mem2 = operands[2];
}
if (mips_address_insns (XEXP (mem1, 0), mode, false) == 0
|| mips_address_insns (XEXP (mem2, 0), mode, false) == 0)
return false;
mips_split_plus (XEXP (mem1, 0), &base1, &offset1);
mips_split_plus (XEXP (mem2, 0), &base2, &offset2);
/* Base regs do not match. */
if (!REG_P (base1) || !rtx_equal_p (base1, base2))
return false;
/* Either of the loads is clobbering base register. It is legitimate to bond
loads if second load clobbers base register. However, hardware does not
support such bonding. */
if (load_p
&& (REGNO (reg1) == REGNO (base1)
|| (REGNO (reg2) == REGNO (base1))))
return false;
/* Loading in same registers. */
if (load_p
&& REGNO (reg1) == REGNO (reg2))
return false;
/* The loads/stores are not of same type. */
rc1 = REGNO_REG_CLASS (REGNO (reg1));
rc2 = REGNO_REG_CLASS (REGNO (reg2));
if (rc1 != rc2
&& !reg_class_subset_p (rc1, rc2)
&& !reg_class_subset_p (rc2, rc1))
return false;
if (abs (offset1 - offset2) != GET_MODE_SIZE (mode))
return false;
return true;
}
/* OPERANDS describes the operands to a pair of SETs, in the order
dest1, src1, dest2, src2. Return true if the operands can be used
in an LWP or SWP instruction; LOAD_P says which. */

View File

@ -3162,3 +3162,10 @@ extern GTY(()) struct target_globals *mips16_globals;
#define STANDARD_STARTFILE_PREFIX_1 "/lib64/"
#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib64/"
#endif
/* Load store bonding is not supported by micromips and fix_24k. The
performance can be degraded for those targets. Hence, do not bond for
micromips or fix_24k. */
#define ENABLE_LD_ST_PAIRS \
(TARGET_LOAD_STORE_PAIRS && TUNE_P5600 \
&& !TARGET_MICROMIPS && !TARGET_FIX_24K)

View File

@ -754,6 +754,11 @@
(define_mode_iterator MOVEP1 [SI SF])
(define_mode_iterator MOVEP2 [SI SF])
(define_mode_iterator JOIN_MODE [HI
SI
(SF "TARGET_HARD_FLOAT")
(DF "TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT")])
;; This mode iterator allows :HILO to be used as the mode of the
;; concatenated HI and LO registers.
@ -7404,6 +7409,112 @@
{ return MIPS_CALL ("jal", operands, 0, -1); }
[(set_attr "type" "call")
(set_attr "insn_count" "3")])
;; Match paired HI/SI/SF/DFmode load/stores.
(define_insn "*join2_load_store<JOIN_MODE:mode>"
[(set (match_operand:JOIN_MODE 0 "nonimmediate_operand" "=d,f,m,m")
(match_operand:JOIN_MODE 1 "nonimmediate_operand" "m,m,d,f"))
(set (match_operand:JOIN_MODE 2 "nonimmediate_operand" "=d,f,m,m")
(match_operand:JOIN_MODE 3 "nonimmediate_operand" "m,m,d,f"))]
"ENABLE_LD_ST_PAIRS && reload_completed"
{
bool load_p = (which_alternative == 0 || which_alternative == 1);
/* Reg-renaming pass reuses base register if it is dead after bonded loads.
Hardware does not bond those loads, even when they are consecutive.
However, order of the loads need to be checked for correctness. */
if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[1]))
{
output_asm_insn (mips_output_move (operands[0], operands[1]),
operands);
output_asm_insn (mips_output_move (operands[2], operands[3]),
&operands[2]);
}
else
{
output_asm_insn (mips_output_move (operands[2], operands[3]),
&operands[2]);
output_asm_insn (mips_output_move (operands[0], operands[1]),
operands);
}
return "";
}
[(set_attr "move_type" "load,fpload,store,fpstore")
(set_attr "insn_count" "2,2,2,2")])
;; 2 HI/SI/SF/DF loads are joined.
;; P5600 does not support bonding of two LBs, hence QI mode is not included.
;; The loads must be non-volatile as they might be reordered at the time of asm
;; generation.
(define_peephole2
[(set (match_operand:JOIN_MODE 0 "register_operand")
(match_operand:JOIN_MODE 1 "non_volatile_mem_operand"))
(set (match_operand:JOIN_MODE 2 "register_operand")
(match_operand:JOIN_MODE 3 "non_volatile_mem_operand"))]
"ENABLE_LD_ST_PAIRS
&& mips_load_store_bonding_p (operands, <JOIN_MODE:MODE>mode, true)"
[(parallel [(set (match_dup 0)
(match_dup 1))
(set (match_dup 2)
(match_dup 3))])]
"")
;; 2 HI/SI/SF/DF stores are joined.
;; P5600 does not support bonding of two SBs, hence QI mode is not included.
(define_peephole2
[(set (match_operand:JOIN_MODE 0 "memory_operand")
(match_operand:JOIN_MODE 1 "register_operand"))
(set (match_operand:JOIN_MODE 2 "memory_operand")
(match_operand:JOIN_MODE 3 "register_operand"))]
"ENABLE_LD_ST_PAIRS
&& mips_load_store_bonding_p (operands, <JOIN_MODE:MODE>mode, false)"
[(parallel [(set (match_dup 0)
(match_dup 1))
(set (match_dup 2)
(match_dup 3))])]
"")
;; Match paired HImode loads.
(define_insn "*join2_loadhi"
[(set (match_operand:SI 0 "register_operand" "=r")
(any_extend:SI (match_operand:HI 1 "non_volatile_mem_operand" "m")))
(set (match_operand:SI 2 "register_operand" "=r")
(any_extend:SI (match_operand:HI 3 "non_volatile_mem_operand" "m")))]
"ENABLE_LD_ST_PAIRS && reload_completed"
{
/* Reg-renaming pass reuses base register if it is dead after bonded loads.
Hardware does not bond those loads, even when they are consecutive.
However, order of the loads need to be checked for correctness. */
if (!reg_overlap_mentioned_p (operands[0], operands[1]))
{
output_asm_insn ("lh<u>\t%0,%1", operands);
output_asm_insn ("lh<u>\t%2,%3", operands);
}
else
{
output_asm_insn ("lh<u>\t%2,%3", operands);
output_asm_insn ("lh<u>\t%0,%1", operands);
}
return "";
}
[(set_attr "move_type" "load")
(set_attr "insn_count" "2")])
;; 2 HI loads are joined.
(define_peephole2
[(set (match_operand:SI 0 "register_operand")
(any_extend:SI (match_operand:HI 1 "non_volatile_mem_operand")))
(set (match_operand:SI 2 "register_operand")
(any_extend:SI (match_operand:HI 3 "non_volatile_mem_operand")))]
"ENABLE_LD_ST_PAIRS
&& mips_load_store_bonding_p (operands, HImode, true)"
[(parallel [(set (match_dup 0)
(any_extend:SI (match_dup 1)))
(set (match_dup 2)
(any_extend:SI (match_dup 3)))])]
"")
;; Synchronization instructions.

View File

@ -418,3 +418,7 @@ Enable use of odd-numbered single-precision registers
noasmopt
Driver
mload-store-pairs
Target Report Var(TARGET_LOAD_STORE_PAIRS) Init(1)
Enable load/store bonding.

View File

@ -1,3 +1,7 @@
2015-05-19 Sameera Deshpande <sameera.deshpande@imgtec.com>
* gcc.target/mips/p5600-bonding.c : New file.
2015-05-18 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/66106

View File

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-dp -mtune=p5600 -mno-micromips -mno-mips16" } */
/* { dg-skip-if "Bonding needs peephole optimization." { *-*-* } { "-O0" "-O1" } { "" } } */
typedef int VINT32 __attribute__ ((vector_size((16))));
void
memory_operation (void * __restrict src, void * __restrict dest, int num)
{
VINT32 *vsrc = (VINT32 *) src;
VINT32 *vdest = (VINT32 *) dest;
int i;
for (i = 0; i < num - 1; i += 2)
{
vdest[i] = vdest[i] + vsrc[i];
vdest[i + 1] = vdest[i + 1] + vsrc[i + 1];
}
}
/* { dg-final { scan-assembler "join2_" } } */