Fix a latent bug in cfgcleanup by updating loop's latch info if necessary

Submitted by Bin Cheng on March 10, 2014, 9:29 a.m.

Details

Message ID 005101cf3c43$4f50e250$edf2a6f0$@arm.com
State New
Headers show

Commit Message

Bin Cheng March 10, 2014, 9:29 a.m.
Hi,
When I investigating PR60363 which is caused by previous patch for PR60280,
I found there is a latent bug in remove_forwarder_block_with_phi because GCC
doesn't update loop's latch information.  Without this patch, cfgcleanup
facility will remove and rebuild the loop structure, resulting in loss of
loop meta information.

This patch is just an obvious pickup, but it isn't intended to fix pr60363.

Test on cortex-m3
Bootstrap and test on x86_64

Is it OK?


2014-03-10  Bin Cheng  <bin.cheng@arm.com>

	* tree-cfgcleanup.c (remove_forwarder_block_with_phi): Record
	bb's single pred and update the father loop's latch info later.

Comments

Richard Guenther March 11, 2014, 10:50 a.m.
On Mon, Mar 10, 2014 at 10:29 AM, bin.cheng <bin.cheng@arm.com> wrote:
> Hi,
> When I investigating PR60363 which is caused by previous patch for PR60280,
> I found there is a latent bug in remove_forwarder_block_with_phi because GCC
> doesn't update loop's latch information.  Without this patch, cfgcleanup
> facility will remove and rebuild the loop structure, resulting in loss of
> loop meta information.
>
> This patch is just an obvious pickup, but it isn't intended to fix pr60363.
>
> Test on cortex-m3
> Bootstrap and test on x86_64
>
> Is it OK?

Ok.

Thanks,
Richard.

>
> 2014-03-10  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Record
>         bb's single pred and update the father loop's latch info later.

Patch hide | download patch | download mbox

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c	(revision 208447)
+++ gcc/tree-cfgcleanup.c	(working copy)
@@ -820,6 +820,12 @@  remove_forwarder_block_with_phi (basic_block bb)
       && DECL_NONLOCAL (gimple_label_label (label)))
     return false;
 
+  /* Record bb's single pred in case we need to update the father
+     loop's latch information later.  */
+  basic_block pred = NULL;
+  if (single_pred_p (bb))
+    pred = single_pred (bb);
+
   /* Redirect each incoming edge to BB to DEST.  */
   while (EDGE_COUNT (bb->preds) > 0)
     {
@@ -904,6 +910,11 @@  remove_forwarder_block_with_phi (basic_block bb)
 
   set_immediate_dominator (CDI_DOMINATORS, dest, dom);
 
+  /* Adjust latch infomation of BB's parent loop as otherwise
+     the cfg hook has a hard time not to kill the loop.  */
+  if (current_loops && bb->loop_father->latch == bb)
+    bb->loop_father->latch = pred;
+
   /* Remove BB since all of BB's incoming edges have been redirected
      to DEST.  */
   delete_basic_block (bb);