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))) {