public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix RTL unswitching loop verification ICE
@ 2013-02-13 10:11 Richard Biener
  2013-02-13 11:36 ` Marcus Shawcroft
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Biener @ 2013-02-13 10:11 UTC (permalink / raw)
  To: gcc-patches; +Cc: Marcus Shawcroft


This fixes the reported ICE on arm.  Similar to tree level unswitching
RTL level unswitching can expose formerly irreducible regions as new
loops.  The following patch makes sure to discover them (we now
verify we do).

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Richard.

2013-02-13  Richard Biener  <rguenther@suse.de>

	* loop-init.c (loop_optimizer_init): Clear loop state when
	re-initializing preserved loops.
	* loop-unswitch.c (unswitch_single_loop): Return whether
	we unswitched the loop.  Do not verify loop state here.
	(unswitch_loops): When we unswitched a loop discover new
	loops.

Index: gcc/loop-init.c
===================================================================
*** gcc/loop-init.c	(revision 195997)
--- gcc/loop-init.c	(working copy)
*************** loop_optimizer_init (unsigned flags)
*** 99,104 ****
--- 99,107 ----
  #ifdef ENABLE_CHECKING
        verify_loop_structure ();
  #endif
+ 
+       /* Clear all flags.  */
+       loops_state_clear (~0U);
      }
  
    /* Apply flags to loops.  */
Index: gcc/loop-unswitch.c
===================================================================
*** gcc/loop-unswitch.c	(revision 195997)
--- gcc/loop-unswitch.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 78,84 ****
    with handling this case.  */
  
  static struct loop *unswitch_loop (struct loop *, basic_block, rtx, rtx);
! static void unswitch_single_loop (struct loop *, rtx, int);
  static rtx may_unswitch_on (basic_block, struct loop *, rtx *);
  
  /* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if
--- 78,84 ----
    with handling this case.  */
  
  static struct loop *unswitch_loop (struct loop *, basic_block, rtx, rtx);
! static bool unswitch_single_loop (struct loop *, rtx, int);
  static rtx may_unswitch_on (basic_block, struct loop *, rtx *);
  
  /* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if
*************** unswitch_loops (void)
*** 140,152 ****
  {
    loop_iterator li;
    struct loop *loop;
  
    /* Go through inner loops (only original ones).  */
  
    FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
!     unswitch_single_loop (loop, NULL_RTX, 0);
  
    iv_analysis_done ();
  }
  
  /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
--- 140,161 ----
  {
    loop_iterator li;
    struct loop *loop;
+   bool changed = false;
  
    /* Go through inner loops (only original ones).  */
  
    FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
!     changed |= unswitch_single_loop (loop, NULL_RTX, 0);
  
    iv_analysis_done ();
+ 
+   /* If we unswitched any loop discover new loops that are eventually
+      exposed by making irreducible regions reducible.  */
+   if (changed)
+     {
+       calculate_dominance_info (CDI_DOMINATORS);
+       fix_loop_structure (NULL);
+     }
  }
  
  /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
*************** reversed_condition (rtx cond)
*** 241,248 ****
  /* Unswitch single LOOP.  COND_CHECKED holds list of conditions we already
     unswitched on and are therefore known to be true in this LOOP.  NUM is
     number of unswitchings done; do not allow it to grow too much, it is too
!    easy to create example on that the code would grow exponentially.  */
! static void
  unswitch_single_loop (struct loop *loop, rtx cond_checked, int num)
  {
    basic_block *bbs;
--- 250,258 ----
  /* Unswitch single LOOP.  COND_CHECKED holds list of conditions we already
     unswitched on and are therefore known to be true in this LOOP.  NUM is
     number of unswitchings done; do not allow it to grow too much, it is too
!    easy to create example on that the code would grow exponentially.
!    Returns true LOOP was unswitched.  */
! static bool 
  unswitch_single_loop (struct loop *loop, rtx cond_checked, int num)
  {
    basic_block *bbs;
*************** unswitch_single_loop (struct loop *loop,
*** 258,264 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
!       return;
      }
  
    /* Only unswitch innermost loops.  */
--- 268,274 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
!       return false;
      }
  
    /* Only unswitch innermost loops.  */
*************** unswitch_single_loop (struct loop *loop,
*** 266,272 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, not innermost loop\n");
!       return;
      }
  
    /* We must be able to duplicate loop body.  */
--- 276,282 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, not innermost loop\n");
!       return false;
      }
  
    /* We must be able to duplicate loop body.  */
*************** unswitch_single_loop (struct loop *loop,
*** 274,280 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n");
!       return;
      }
  
    /* The loop should not be too large, to limit code growth.  */
--- 284,290 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n");
!       return false;
      }
  
    /* The loop should not be too large, to limit code growth.  */
*************** unswitch_single_loop (struct loop *loop,
*** 282,288 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, loop too big\n");
!       return;
      }
  
    /* Do not unswitch in cold areas.  */
--- 292,298 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, loop too big\n");
!       return false;
      }
  
    /* Do not unswitch in cold areas.  */
*************** unswitch_single_loop (struct loop *loop,
*** 290,296 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, not hot area\n");
!       return;
      }
  
    /* Nor if the loop usually does not roll.  */
--- 300,306 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, not hot area\n");
!       return false;
      }
  
    /* Nor if the loop usually does not roll.  */
*************** unswitch_single_loop (struct loop *loop,
*** 299,305 ****
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
!       return;
      }
  
    do
--- 309,315 ----
      {
        if (dump_file)
  	fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
!       return false;
      }
  
    do
*************** unswitch_single_loop (struct loop *loop,
*** 317,323 ****
        if (i == loop->num_nodes)
  	{
  	  free (bbs);
! 	  return;
  	}
  
        if (cond != const0_rtx
--- 327,333 ----
        if (i == loop->num_nodes)
  	{
  	  free (bbs);
! 	  return false;
  	}
  
        if (cond != const0_rtx
*************** unswitch_single_loop (struct loop *loop,
*** 364,373 ****
    nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn);
    gcc_assert (nloop);
  
- #ifdef ENABLE_CHECKING
-   verify_loop_structure ();
- #endif
- 
    /* Invoke itself on modified loops.  */
    unswitch_single_loop (nloop, rconds, num + 1);
    unswitch_single_loop (loop, conds, num + 1);
--- 374,379 ----
*************** unswitch_single_loop (struct loop *loop,
*** 377,382 ****
--- 383,390 ----
      free_EXPR_LIST_node (rconds);
  
    free (bbs);
+ 
+   return true;
  }
  
  /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON.  We only support

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix RTL unswitching loop verification ICE
  2013-02-13 10:11 [PATCH] Fix RTL unswitching loop verification ICE Richard Biener
@ 2013-02-13 11:36 ` Marcus Shawcroft
  0 siblings, 0 replies; 2+ messages in thread
From: Marcus Shawcroft @ 2013-02-13 11:36 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On 13 February 2013 10:11, Richard Biener <rguenther@suse.de> wrote:
>
> This fixes the reported ICE on arm.  Similar to tree level unswitching
> RTL level unswitching can expose formerly irreducible regions as new
> loops.  The following patch makes sure to discover them (we now
> verify we do).
>
> Bootstrap and regtest pending on x86_64-unknown-linux-gnu.
>
> Richard.

Thanks for looking at this.

The proposed patch resolves the issue on both arm and aarch64.

Cheers
/Marcus

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-02-13 11:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-13 10:11 [PATCH] Fix RTL unswitching loop verification ICE Richard Biener
2013-02-13 11:36 ` Marcus Shawcroft

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).