This fixes VOP renaming in IPA split (well, or rather adds to its
crudeness).  We really need to rename the reaching VDEF of the
exit of the SESE region we kill, as that VDEF will be released
when removing the definitions basic-block.  What we really would
want to do is replace that SESE region with the call using the
reaching VDEF of its entry and the reaching VDEF of its exit
as virtual operands.  But the current code is somewhat twisted
so I got lost and the following is what also works for me.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Honza, I fail to see the exact constraints on the region we
outline, so you might want to provide a better fix?

Thanks,
Richard.

2011-03-23  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/48193
        * ipa-slit.c (split_function): Properly rename the reaching
        VDEF.

Index: gcc/ipa-split.c
===================================================================
--- gcc/ipa-split.c     (revision 171352)
+++ gcc/ipa-split.c     (working copy)
@@ -169,8 +169,9 @@ static void
 dump_split_point (FILE * file, struct split_point *current)
 {
   fprintf (file,
-          "Split point at BB %i header time:%i header size: %i"
-          " split time: %i split size: %i\n  bbs: ",
+          "Split point at BB %i\n"
+          "  header time: %i header size: %i\n"
+          "  split time: %i split size: %i\n  bbs: ",
           current->entry_bb->index, current->header_time,
           current->header_size, current->split_time, current->split_size);
   dump_bitmap (file, current->split_bbs);
@@ -1036,12 +1037,13 @@ split_function (struct split_point *spli
 
   /* If RETURN_BB has virtual operand PHIs, they must be removed and the
      virtual operand marked for renaming as we change the CFG in a way that
-     tree-inline is not able to compensate for. 
+     tree-inline is not able to compensate for.
 
      Note this can happen whether or not we have a return value.  If we have
      a return value, then RETURN_BB may have PHIs for real operands too.  */
   if (return_bb != EXIT_BLOCK_PTR)
     {
+      bool phi_p = false;
       for (gsi = gsi_start_phis (return_bb); !gsi_end_p (gsi);)
        {
          gimple stmt = gsi_stmt (gsi);
@@ -1052,7 +1054,28 @@ split_function (struct split_point *spli
            }
          mark_virtual_phi_result_for_renaming (stmt);
          remove_phi_node (&gsi, true);
+         phi_p = true;
        }
+      /* In reality we have to rename the reaching definition of the
+        virtual operand at return_bb as we will eventually release it
+        when we remove the code region we outlined.
+        So we have to rename all immediate virtual uses of that region
+        if we didn't see a PHI definition yet.  */
+      /* ???  In real reality we want to set the reaching vdef of the
+         entry of the SESE region as the vuse of the call and the reaching
+        vdef of the exit of the SESE region as the vdef of the call.  */
+      if (!phi_p)
+       for (gsi = gsi_start_bb (return_bb); !gsi_end_p (gsi); gsi_next (&gsi))
+         {
+           gimple stmt = gsi_stmt (gsi);
+           if (gimple_vuse (stmt))
+             {
+               gimple_set_vuse (stmt, NULL_TREE);
+               update_stmt (stmt);
+             }
+           if (gimple_vdef (stmt))
+             break;
+         }
     }
 
   /* Now create the actual clone.  */

Reply via email to