This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ifcvt: cond_exec-like behavior on cc0 machines
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: 03 Aug 2003 15:16:52 -0300
- Subject: Re: ifcvt: cond_exec-like behavior on cc0 machines
- Organization: GCC Team, Red Hat
- References: <orel0pngi8.fsf@free.redhat.lsd.ic.unicamp.br><ord6g3v9l6.fsf@free.redhat.lsd.ic.unicamp.br><20030721233209.GC17924@redhat.com><orispvtd55.fsf@free.redhat.lsd.ic.unicamp.br><orr84hvjua.fsf@free.redhat.lsd.ic.unicamp.br>
On Jul 23, 2003, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Jul 22, 2003, Alexandre Oliva <aoliva@redhat.com> wrote:
>> IIRC, get_condition() may have failed in a case that had one of
>> these setting (cc0) before the branch.
> Actually, the reason get_condition() failed was that it was not the
> function I should be using. Later on, I realized I wanted
> canonicalize_condition, that wouldn't attempt to reverse the
> condition, which caused it to sometimes fail, e.g., for (ge (cc0)
> (const_int 0)). Why it failed to reverse it, I didn't investigate (or
> I don't remember), since I realized I didn't want it to ever revert
> the condition anyway. With canonicalize_condition(), I got better
> results, but init_propagate_block_info() still crashed when it got a
> cond_true that looked like (ne (zero_extract reg 1 0) 0), because the
> operand of the comparison wasn't a reg or subreg of a reg.
> I'm not sure what to do in this case. Can we just skip the block that
> would mark registers as conditionally dead in this case, or do we need
> to take some alternate action?
> The other thing I'm unsure about is whether ifcvt should require a
> canonical condition. Ports might legitimately define cond_exec using
> cc0, but ifcvt wouldn't be able to convert a multi-insn bb to it, but
> it could still convert a single-insn bb into a cc0-using cond_exec
> insn, and this would simplify ports that actually need a separate
> cc0-setting instruction. OTOH, one can always accept a cc0-less
> condition and then split it into a cc0-setting insn followed by the
> use, but this could get painful. In this one port I'm working on, the
> conditional insn cannot take a cc0 condition, so I know there are uses
> for the canonicalization, but I'm unsure about the alternative.
> Comments?
Here's a patch that doesn't introduce any regressions in the port I've
been working on, after converting it back to use cond_exec instead of
the if_then_else operations. I've also bootstrapped it on
i686-pc-linux-gnu, just in case. Ok to install?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* ifcvt.c (cond_exec_process_if_block): Use a condition that
doesn't mention cc0.
* flow.c (init_propagate_block_info): Likewise. Don't abort if
condition code is not based on a REG.
Index: gcc/ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.124
diff -u -p -r1.124 ifcvt.c
--- gcc/ifcvt.c 26 Jul 2003 18:38:42 -0000 1.124
+++ gcc/ifcvt.c 3 Aug 2003 14:05:31 -0000
@@ -411,6 +411,16 @@ cond_exec_process_if_block (ce_if_block_
if (! test_expr)
return FALSE;
+#ifdef HAVE_cc0
+ if (reg_mentioned_p (cc0_rtx, test_expr))
+ {
+ rtx test_insn;
+ test_expr = noce_get_condition (test_bb->end, &test_insn);
+ if (! test_expr)
+ return FALSE;
+ }
+#endif
+
/* If the conditional jump is more than just a conditional jump,
then we can not do conditional execution conversion on this block. */
if (! onlyjump_p (test_bb->end))
Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.561
diff -u -p -r1.561 flow.c
--- gcc/flow.c 19 Jul 2003 14:47:05 -0000 1.561
+++ gcc/flow.c 3 Aug 2003 14:05:34 -0000
@@ -1901,6 +1901,10 @@ init_propagate_block_info (basic_block b
/* Extract the condition from the branch. */
set_src = SET_SRC (pc_set (bb->end));
cond_true = XEXP (set_src, 0);
+#ifdef HAVE_cc0
+ if (reg_mentioned_p (cc0_rtx, cond_true))
+ cond_true = canonicalize_condition (bb->end, cond_true, 0, 0, 0);
+#endif
cond_false = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
GET_MODE (cond_true), XEXP (cond_true, 0),
XEXP (cond_true, 1));
@@ -1921,7 +1925,7 @@ init_propagate_block_info (basic_block b
reg = SUBREG_REG (reg);
if (GET_CODE (reg) != REG)
- abort ();
+ goto cond_is_not_a_reg;
SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
@@ -1947,6 +1951,7 @@ init_propagate_block_info (basic_block b
});
}
+ cond_is_not_a_reg:
FREE_REG_SET (diff);
}
#endif
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer