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

Reply via email to