mirror of git://gcc.gnu.org/git/gcc.git
re PR target/39423 ([SH] performance regression: lost mov @(disp,Rn))
PR target/39423 * config/sh/predicates.md (mem_index_disp_operand): New predicate. * config/sh/sh.md (*movsi_index_disp): Rewrite insns to use the new mem_index_disp_operand predicate. PR target/39423 * gcc.target/sh/pr39423-1.c: New. From-SVN: r190259
This commit is contained in:
parent
78ff60c1ad
commit
b67b3838e9
|
|
@ -1,3 +1,10 @@
|
||||||
|
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR target/39423
|
||||||
|
* config/sh/predicates.md (mem_index_disp_operand): New predicate.
|
||||||
|
* config/sh/sh.md (*movsi_index_disp): Rewrite insns to use the new
|
||||||
|
mem_index_disp_operand predicate.
|
||||||
|
|
||||||
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
PR target/51244
|
PR target/51244
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,31 @@
|
||||||
return 0;
|
return 0;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
;; Returns 1 if OP is a MEM that can be used in "index_disp" combiner
|
||||||
|
;; patterns.
|
||||||
|
(define_predicate "mem_index_disp_operand"
|
||||||
|
(match_code "mem")
|
||||||
|
{
|
||||||
|
rtx plus0_rtx, plus1_rtx, mult_rtx;
|
||||||
|
|
||||||
|
plus0_rtx = XEXP (op, 0);
|
||||||
|
if (GET_CODE (plus0_rtx) != PLUS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
plus1_rtx = XEXP (plus0_rtx, 0);
|
||||||
|
if (GET_CODE (plus1_rtx) != PLUS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mult_rtx = XEXP (plus1_rtx, 0);
|
||||||
|
if (GET_CODE (mult_rtx) != MULT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return REG_P (XEXP (mult_rtx, 0)) && CONST_INT_P (XEXP (mult_rtx, 1))
|
||||||
|
&& exact_log2 (INTVAL (XEXP (mult_rtx, 1))) > 0
|
||||||
|
&& REG_P (XEXP (plus1_rtx, 1))
|
||||||
|
&& sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
|
||||||
|
})
|
||||||
|
|
||||||
;; TODO: Add a comment here.
|
;; TODO: Add a comment here.
|
||||||
|
|
||||||
(define_predicate "greater_comparison_operator"
|
(define_predicate "greater_comparison_operator"
|
||||||
|
|
|
||||||
|
|
@ -5119,114 +5119,116 @@ label:
|
||||||
;; FIXME: Combine never tries this kind of patterns for DImode.
|
;; FIXME: Combine never tries this kind of patterns for DImode.
|
||||||
(define_insn_and_split "*movsi_index_disp"
|
(define_insn_and_split "*movsi_index_disp"
|
||||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
||||||
(mem:SI
|
(match_operand:SI 1 "mem_index_disp_operand" "m"))]
|
||||||
(plus:SI
|
"TARGET_SH1"
|
||||||
(plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
|
|
||||||
(match_operand:SI 2 "const_int_operand"))
|
|
||||||
(match_operand:SI 3 "arith_reg_operand" "r"))
|
|
||||||
(match_operand:SI 4 "const_int_operand"))))]
|
|
||||||
"TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
|
|
||||||
&& exact_log2 (INTVAL (operands[2])) > 0"
|
|
||||||
"#"
|
"#"
|
||||||
"&& can_create_pseudo_p ()"
|
"&& can_create_pseudo_p ()"
|
||||||
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
||||||
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
||||||
(set (match_dup 0) (mem:SI (plus:SI (match_dup 6) (match_dup 4))))]
|
(set (match_dup 0) (match_dup 7))]
|
||||||
{
|
{
|
||||||
|
rtx mem = operands[1];
|
||||||
|
rtx plus0_rtx = XEXP (mem, 0);
|
||||||
|
rtx plus1_rtx = XEXP (plus0_rtx, 0);
|
||||||
|
rtx mult_rtx = XEXP (plus1_rtx, 0);
|
||||||
|
|
||||||
|
operands[1] = XEXP (mult_rtx, 0);
|
||||||
|
operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
|
||||||
|
operands[3] = XEXP (plus1_rtx, 1);
|
||||||
|
operands[4] = XEXP (plus0_rtx, 1);
|
||||||
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
||||||
operands[6] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
||||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
|
operands[7] =
|
||||||
|
replace_equiv_address (mem,
|
||||||
|
gen_rtx_PLUS (SImode, operands[6], operands[4]));
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movhi_index_disp"
|
(define_insn_and_split "*movhi_index_disp"
|
||||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
||||||
(sign_extend:SI
|
(sign_extend:SI (match_operand:HI 1 "mem_index_disp_operand" "m")))]
|
||||||
(mem:HI
|
"TARGET_SH1"
|
||||||
(plus:SI
|
|
||||||
(plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
|
|
||||||
(match_operand:SI 2 "const_int_operand"))
|
|
||||||
(match_operand:SI 3 "arith_reg_operand" "r"))
|
|
||||||
(match_operand:SI 4 "const_int_operand")))))]
|
|
||||||
"TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
|
|
||||||
&& exact_log2 (INTVAL (operands[2])) > 0"
|
|
||||||
"#"
|
"#"
|
||||||
"&& can_create_pseudo_p ()"
|
"&& can_create_pseudo_p ()"
|
||||||
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
||||||
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
||||||
(set (match_dup 0)
|
(set (match_dup 0) (sign_extend:SI (match_dup 7)))]
|
||||||
(sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))]
|
|
||||||
{
|
{
|
||||||
|
rtx mem = operands[1];
|
||||||
|
rtx plus0_rtx = XEXP (mem, 0);
|
||||||
|
rtx plus1_rtx = XEXP (plus0_rtx, 0);
|
||||||
|
rtx mult_rtx = XEXP (plus1_rtx, 0);
|
||||||
|
|
||||||
|
operands[1] = XEXP (mult_rtx, 0);
|
||||||
|
operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
|
||||||
|
operands[3] = XEXP (plus1_rtx, 1);
|
||||||
|
operands[4] = XEXP (plus0_rtx, 1);
|
||||||
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
||||||
operands[6] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
||||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
|
operands[7] =
|
||||||
|
replace_equiv_address (mem,
|
||||||
|
gen_rtx_PLUS (SImode, operands[6], operands[4]));
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movhi_index_disp"
|
(define_split
|
||||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
[(set (match_operand:SI 0 "arith_reg_dest")
|
||||||
(zero_extend:SI
|
(zero_extend:SI (match_operand:HI 1 "mem_index_disp_operand")))]
|
||||||
(mem:HI
|
"TARGET_SH1"
|
||||||
(plus:SI
|
[(set (match_dup 0) (sign_extend:SI (match_dup 1)))
|
||||||
(plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
|
(set (match_dup 0) (zero_extend:SI (match_dup 2)))]
|
||||||
(match_operand:SI 2 "const_int_operand"))
|
|
||||||
(match_operand:SI 3 "arith_reg_operand" "r"))
|
|
||||||
(match_operand:SI 4 "const_int_operand")))))]
|
|
||||||
"TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
|
|
||||||
&& exact_log2 (INTVAL (operands[2])) > 0"
|
|
||||||
"#"
|
|
||||||
"&& can_create_pseudo_p ()"
|
|
||||||
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
|
||||||
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
|
||||||
(set (match_dup 7)
|
|
||||||
(sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))
|
|
||||||
(set (match_dup 0) (zero_extend:SI (match_dup 8)))]
|
|
||||||
{
|
{
|
||||||
operands[5] = gen_reg_rtx (SImode);
|
operands[2] = gen_lowpart (HImode, operands[0]);
|
||||||
operands[6] = gen_reg_rtx (SImode);
|
|
||||||
operands[7] = gen_reg_rtx (SImode);
|
|
||||||
operands[8] = gen_lowpart (HImode, operands[7]);
|
|
||||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
|
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movsi_index_disp"
|
(define_insn_and_split "*movsi_index_disp"
|
||||||
[(set (mem:SI
|
[(set (match_operand:SI 0 "mem_index_disp_operand" "=m")
|
||||||
(plus:SI
|
(match_operand:SI 1 "arith_reg_operand" "r"))]
|
||||||
(plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
|
"TARGET_SH1"
|
||||||
(match_operand:SI 2 "const_int_operand"))
|
|
||||||
(match_operand:SI 3 "arith_reg_operand" "r"))
|
|
||||||
(match_operand:SI 4 "const_int_operand")))
|
|
||||||
(match_operand:SI 0 "arith_reg_operand" "r"))]
|
|
||||||
"TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
|
|
||||||
&& exact_log2 (INTVAL (operands[2])) > 0"
|
|
||||||
"#"
|
"#"
|
||||||
"&& can_create_pseudo_p ()"
|
"&& can_create_pseudo_p ()"
|
||||||
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 5) (ashift:SI (match_dup 0) (match_dup 2)))
|
||||||
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
||||||
(set (mem:SI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
|
(set (match_dup 7) (match_dup 1))]
|
||||||
{
|
{
|
||||||
|
rtx mem = operands[0];
|
||||||
|
rtx plus0_rtx = XEXP (mem, 0);
|
||||||
|
rtx plus1_rtx = XEXP (plus0_rtx, 0);
|
||||||
|
rtx mult_rtx = XEXP (plus1_rtx, 0);
|
||||||
|
|
||||||
|
operands[0] = XEXP (mult_rtx, 0);
|
||||||
|
operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
|
||||||
|
operands[3] = XEXP (plus1_rtx, 1);
|
||||||
|
operands[4] = XEXP (plus0_rtx, 1);
|
||||||
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
||||||
operands[6] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
||||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
|
operands[7] =
|
||||||
|
replace_equiv_address (mem,
|
||||||
|
gen_rtx_PLUS (SImode, operands[6], operands[4]));
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movhi_index_disp"
|
(define_insn_and_split "*movsi_index_disp"
|
||||||
[(set (mem:HI
|
[(set (match_operand:HI 0 "mem_index_disp_operand" "=m")
|
||||||
(plus:SI
|
(match_operand:HI 1 "arith_reg_operand" "r"))]
|
||||||
(plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
|
"TARGET_SH1"
|
||||||
(match_operand:SI 2 "const_int_operand"))
|
|
||||||
(match_operand:SI 3 "arith_reg_operand" "r"))
|
|
||||||
(match_operand:SI 4 "const_int_operand")))
|
|
||||||
(match_operand:HI 0 "arith_reg_operand" "r"))]
|
|
||||||
"TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
|
|
||||||
&& exact_log2 (INTVAL (operands[2])) > 0"
|
|
||||||
"#"
|
"#"
|
||||||
"&& can_create_pseudo_p ()"
|
"&& can_create_pseudo_p ()"
|
||||||
[(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 5) (ashift:SI (match_dup 0) (match_dup 2)))
|
||||||
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
|
||||||
(set (mem:HI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
|
(set (match_dup 7) (match_dup 1))]
|
||||||
{
|
{
|
||||||
|
rtx mem = operands[0];
|
||||||
|
rtx plus0_rtx = XEXP (mem, 0);
|
||||||
|
rtx plus1_rtx = XEXP (plus0_rtx, 0);
|
||||||
|
rtx mult_rtx = XEXP (plus1_rtx, 0);
|
||||||
|
|
||||||
|
operands[0] = XEXP (mult_rtx, 0);
|
||||||
|
operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
|
||||||
|
operands[3] = XEXP (plus1_rtx, 1);
|
||||||
|
operands[4] = XEXP (plus0_rtx, 1);
|
||||||
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
||||||
operands[6] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
||||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
|
operands[7] =
|
||||||
|
replace_equiv_address (mem,
|
||||||
|
gen_rtx_PLUS (SImode, operands[6], operands[4]));
|
||||||
})
|
})
|
||||||
|
|
||||||
;; Define additional pop for SH1 and SH2 so it does not get
|
;; Define additional pop for SH1 and SH2 so it does not get
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR target/39423
|
||||||
|
* gcc.target/sh/pr39423-1.c: New.
|
||||||
|
|
||||||
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
2012-08-09 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
PR target/51244
|
PR target/51244
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* Check that displacement addressing is used for indexed addresses with a
|
||||||
|
small offset, instead of re-calculating the index. */
|
||||||
|
/* { dg-do compile { target "sh*-*-*" } } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "add\t#1" } } */
|
||||||
|
|
||||||
|
int
|
||||||
|
test_00 (int tab[], int index)
|
||||||
|
{
|
||||||
|
return tab[index + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test_01 (short tab[], int index)
|
||||||
|
{
|
||||||
|
return tab[index + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test_02 (unsigned short tab[], int index)
|
||||||
|
{
|
||||||
|
return tab[index + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test_03 (long long tab[], int index)
|
||||||
|
{
|
||||||
|
return (int)tab[index + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_04 (int tab[], int index, int val)
|
||||||
|
{
|
||||||
|
tab[index + 1] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_05 (short tab[], int index, int val)
|
||||||
|
{
|
||||||
|
tab[index + 1] = (short)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_06 (unsigned short tab[], int index, int val)
|
||||||
|
{
|
||||||
|
tab[index + 1] = (unsigned short)val;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue