Enhance ifcvt conditional execution to handle IF-THEN-ELSE

Message ID CACgzC7A=oCn7QHiG_B6fbPoj5S2LhSmxEibt3MkuWepC+n8NGw@mail.gmail.com
State New
Headers show

Commit Message

Zhenqiang Chen Jan. 8, 2013, 8:51 a.m.

max (MAX_CONDITIONAL_EXECUTE) is doubled for IF-THEN-ELSE since there
is one more JUMP for the taken branch to goto the successor of
IF-THEN-ELSE. But when the last JUMP is a RETURN, the additional JUMP
can be optimized.

Here are the two different assemble codes the attached test case (-O2
-mthumb) for ARM.
IT block (current result):
        cmp     r0, #0
        itete   lt
        rsblt   r0, r0, #2
        movwge  r3, #21846
        addlt   r0, r0, r0, lsl #1
        movtge  r3, 21845
        iteee   lt
        lsllt   r0, r0, #1
        subge   r0, r0, #2
        smullge r2, r3, r3, r0
        subge   r0, r3, r0, asr #31
        bx      lr

Branch (after patch):
        cmp     r0, #0
        blt     .L5
        movw    r3, #21846
        subs    r0, r0, #2
        movt    r3, 21845
        smull   r2, r3, r3, r0
        sub     r0, r3, r0, asr #31
        bx      lr
        rsb     r0, r0, #2
        add     r0, r0, r0, lsl #1
        lsls    r0, r0, #1
        bx      lr

In general, I think the later one will have better performance.

The patch will check whether there is RETURN. If has, do not double max.

No make check regression and no performance regression for SPECINT2000 for ARM.

Is it OK?


2013-01-08 Zhenqiang Chen <zhenqiang.chen@linaro.org>

	* ifcvt.c (cond_exec_process_if_block): Do not increase max when there


	* gcc.target/arm/if-then-else-return.c: New.


diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index b518b0e..70cb53a 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -443,6 +443,8 @@  cond_exec_process_if_block (ce_if_block_t * ce_info,
   rtx else_first_tail = NULL_RTX;	/* First match at the tail of ELSE */
   int then_n_insns, else_n_insns, n_insns;
   enum rtx_code false_code;
+  bool has_return_p = FALSE;
+  rtx insn;

   /* If test is comprised of && or || elements, and we've failed at handling
      all of them together, just use the last test if it is the special case of
@@ -478,11 +480,19 @@  cond_exec_process_if_block (ce_if_block_t * ce_info,
   n_insns = then_n_insns;

+  insn = BB_END (then_bb);
+  if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
+    has_return_p = TRUE;
   if (else_bb)
       int n_matching;
+      insn = BB_END (else_bb);
+      if (!has_return_p && JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
+	has_return_p = TRUE;

-      max *= 2;
+      if (!has_return_p)
+        max *= 2;
       else_start = first_active_insn (else_bb);
       else_end = last_active_insn (else_bb, TRUE);
       else_n_insns = ce_info->num_else_insns = count_bb_insns (else_bb);