diff mbox

[RFC,ARM,1/5] Split if_then_else into cond_execs

Message ID 4EFDEA53.3000307@ispras.ru
State New
Headers show

Commit Message

Dmitry Melnik Dec. 30, 2011, 4:44 p.m. UTC
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).
diff mbox

Patch

2011-12-08  Sevak Sargsyan <sevak.sargsyan@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 "" ""))