This patch adds splits for if_then_else into cond_execs. This helps generating the minimum number of IT-blocks for two consequent if_then_elses, e.g. one ITETE insn instead of two ITE insns, if if_then_else were expanded directly into assembly code. There are three splitters for the cases when both IF and THEN branches are present, and when there's only one of them (the last two splitters are required to prevent generation of code like "(cc) r0 = r0").
On SPEC2K INT with -O2 this reduces code size by 76 bytes (no regressions).

2011-12-08  Sevak Sargsyan <sevak.sargs...@ispras.ru>

gcc/
    * config/arm/thumb2.md (new splitters for if_then_else): Turn them
    into cond_execs.

diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 05585da..662f995 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -299,6 +299,57 @@
    (set_attr "conds" "use")]
 )
 
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+       (if_then_else:SI
+         (match_operator 3 "arm_comparison_operator"
+          [(match_operand 4 "cc_register" "") (const_int 0)])
+         (match_operand:SI 1 "arm_not_operand" "")
+         (match_operand:SI 2 "arm_not_operand" "")))]
+  "TARGET_THUMB2 && reload_completed
+   && (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1]))
+   && (!REG_P (operands[2]) || REGNO (operands[0]) != REGNO (operands[2]))"
+[(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 1)))
+ (cond_exec (match_dup 6) (set (match_dup 0) (match_dup 2)))]
+{
+   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), VOIDmode,
+                                 operands[4], const0_rtx);
+   operands[6] = gen_rtx_fmt_ee (reversed_comparison_code (operands[3], NULL_RTX),
+                                 VOIDmode, operands[4], const0_rtx);
+})
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+       (if_then_else:SI
+         (match_operator 3 "arm_comparison_operator"
+          [(match_operand 4 "cc_register" "") (const_int 0)])
+         (match_operand:SI 1 "arm_not_operand" "")
+         (match_operand:SI 2 "arm_not_operand" "")))]
+  "TARGET_THUMB2 && reload_completed
+   && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])
+   && (!REG_P (operands[2]) || REGNO (operands[0]) != REGNO (operands[2]))"
+[(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 2)))]
+{
+   operands[5] = gen_rtx_fmt_ee (reversed_comparison_code (operands[3], NULL_RTX),
+                                 VOIDmode, operands[4], const0_rtx);
+})
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+       (if_then_else:SI
+         (match_operator 3 "arm_comparison_operator"
+          [(match_operand 4 "cc_register" "") (const_int 0)])
+         (match_operand:SI 1 "arm_not_operand" "")
+         (match_operand:SI 2 "arm_not_operand" "")))]
+  "TARGET_THUMB2 && reload_completed
+   && (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1]))
+   && REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])"
+[(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 1)))]
+{
+   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), VOIDmode, operands[4],
+                                 const0_rtx);
+})
+
 (define_insn "*call_reg_thumb2"
   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
          (match_operand 1 "" ""))

Reply via email to