On 10/13/11 18:50, Bernd Schmidt wrote:
> On 10/13/11 14:27, Alan Modra wrote:
>> Without the ifcvt
>> optimization for a function "int foo (int x)" we might have something
>> like
>>
>> r29 = r3; // save r3 in callee saved reg
>> if (some test) goto exit_label
>> // main body of foo, calling other functions
>> r3 = 0;
>> return;
>> exit_label:
>> r3 = 1;
>> return;
>>
>> Bernd's http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00380.html quite
>> happily rearranges the r29 assignment to be after the "if", and shrink
>> wrapping occurs. With the ifcvt optimization we get
>>
>> r29 = r3; // save r3 in callee saved reg
>> r3 = 1;
>> if (some test) goto exit_label
>> // main body of foo, calling other functions
>> r3 = 0;
>> exit_label:
>> return;
>
> I wonder if this can't be described as another case for moving an insn
> downwards in prepare_shrink_wrap, rather than stopping ifcvt?
I.e. something like this? Minimally tested by inspecting some generated
assembly. I haven't found a case where it enables extra shrink-wrapping
on i686, but maybe it's different on ppc?
Bernd
Index: /local/src/egcs/scratch-trunk/gcc/function.c
===================================================================
--- /local/src/egcs/scratch-trunk/gcc/function.c (revision 179848)
+++ /local/src/egcs/scratch-trunk/gcc/function.c (working copy)
@@ -5369,13 +5369,13 @@ static void
prepare_shrink_wrap (basic_block entry_block)
{
rtx insn, curr;
- FOR_BB_INSNS_SAFE (entry_block, insn, curr)
+ FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
{
basic_block next_bb;
edge e, live_edge;
edge_iterator ei;
- rtx set, scan;
- unsigned destreg, srcreg;
+ rtx set, src, dst, scan;
+ unsigned destreg;
if (!NONDEBUG_INSN_P (insn))
continue;
@@ -5383,12 +5383,14 @@ prepare_shrink_wrap (basic_block entry_b
if (!set)
continue;
- if (!REG_P (SET_SRC (set)) || !REG_P (SET_DEST (set)))
+ src = SET_SRC (set);
+ dst = SET_DEST (set);
+ if (!(REG_P (src) || CONSTANT_P (src)) || !REG_P (dst))
continue;
- srcreg = REGNO (SET_SRC (set));
- destreg = REGNO (SET_DEST (set));
- if (hard_regno_nregs[srcreg][GET_MODE (SET_SRC (set))] > 1
- || hard_regno_nregs[destreg][GET_MODE (SET_DEST (set))] > 1)
+ destreg = REGNO (dst);
+ if (hard_regno_nregs[destreg][GET_MODE (dst)] > 1)
+ continue;
+ if (REG_P (src) && hard_regno_nregs[REGNO (src)][GET_MODE (src)] > 1)
continue;
next_bb = entry_block;
@@ -5436,7 +5438,8 @@ prepare_shrink_wrap (basic_block entry_b
if (REG_NOTE_KIND (link) == REG_INC)
record_hard_reg_sets (XEXP (link, 0), NULL, &set_regs);
- if (TEST_HARD_REG_BIT (set_regs, srcreg)
+ if ((REG_P (src)
+ && TEST_HARD_REG_BIT (set_regs, REGNO (src)))
|| reg_referenced_p (SET_DEST (set),
PATTERN (scan)))
{