aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2007-06-08 09:58:41 +0200
committerChristian Bruel <chrbr@gcc.gnu.org>2007-06-08 09:58:41 +0200
commit4aa97413d3845089735af2d5a5fe7b01eeae6008 (patch)
tree703c2b7fb2c08be557096002e275a7a02efaf2ad
parent1fc3998daa162619e2826523d2b9efad2a3c7725 (diff)
downloadgcc-4aa97413d3845089735af2d5a5fe7b01eeae6008.zip
gcc-4aa97413d3845089735af2d5a5fe7b01eeae6008.tar.gz
gcc-4aa97413d3845089735af2d5a5fe7b01eeae6008.tar.bz2
re PR target/29953 ([SH-4] Perfomance regression in loops. cmp/eq used instead of dt)
PR target/29953 * config/sh/sh.md (doloop_end): New pattern and splitter. * loop-iv.c (simple_rhs_p): Check for hardware registers. From-SVN: r125564
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh.md46
-rw-r--r--gcc/loop-iv.c6
3 files changed, 55 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14ac46a..583ba38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2007-06-08 Christian Bruel <christian.bruel@st.com>
+
+ PR target/29953
+ * config/sh/sh.md (doloop_end): New pattern and splitter.
+ * loop-iv.c (simple_rhs_p): Check for hardware registers.
+
2007-06-08 Zdenek Dvorak <dvorakz@suse.cz>
PR middle-end/32209
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index c4f6257..20653b1 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -7323,6 +7323,52 @@ label:
? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
: gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
}")
+
+; operand 0 is the loop count pseudo register
+; operand 1 is the number of loop iterations or 0 if it is unknown
+; operand 2 is the maximum number of loop iterations
+; operand 3 is the number of levels of enclosed loops
+; operand 4 is the label to jump to at the top of the loop
+
+(define_expand "doloop_end"
+ [(parallel [(set (pc) (if_then_else
+ (ne:SI (match_operand:SI 0 "" "")
+ (const_int 1))
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0) (const_int -1)))
+ (clobber (reg:SI T_REG))])]
+ "TARGET_SH2"
+ "
+{
+ if (GET_MODE (operands[0]) != SImode)
+ FAIL;
+}
+")
+
+(define_insn_and_split "doloop_end_split"
+ [(set (pc)
+ (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
+ (const_int 1))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))
+ (set (match_dup 0)
+ (plus (match_dup 0) (const_int -1)))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH2"
+ "#"
+ ""
+ [(parallel [(set (reg:SI T_REG)
+ (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
+ (const_int 1)))
+ (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
+ (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+""
+ [(set_attr "type" "cbranch")])
+
;; ------------------------------------------------------------------------
;; Jump and linkage insns
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index bdf1508..0b6d46d 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -1293,7 +1293,7 @@ simple_rhs_p (rtx rhs)
rtx op0, op1;
if (CONSTANT_P (rhs)
- || REG_P (rhs))
+ || (REG_P (rhs) && !HARD_REGISTER_P (rhs)))
return true;
switch (GET_CODE (rhs))
@@ -1303,9 +1303,9 @@ simple_rhs_p (rtx rhs)
op0 = XEXP (rhs, 0);
op1 = XEXP (rhs, 1);
/* Allow reg + const sets only. */
- if (REG_P (op0) && CONSTANT_P (op1))
+ if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
return true;
- if (REG_P (op1) && CONSTANT_P (op0))
+ if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
return true;
return false;