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:
parent
fab27f5289
commit
abf96035ef
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_" } } */
|
||||
|
Loading…
Reference in New Issue