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 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
{
loop_iterator li;
struct loop *loop;
+ bool changed = false;
/* Go through inner loops (only original ones). */
FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
- unswitch_single_loop (loop, NULL_RTX, 0);
+ 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
/* 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
+ 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;
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
- return;
+ return false;
}
/* Only unswitch innermost loops. */
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, not innermost loop\n");
- return;
+ return false;
}
/* We must be able to duplicate loop body. */
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n");
- return;
+ return false;
}
/* The loop should not be too large, to limit code growth. */
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, loop too big\n");
- return;
+ return false;
}
/* Do not unswitch in cold areas. */
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, not hot area\n");
- return;
+ return false;
}
/* Nor if the loop usually does not roll. */
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
- return;
+ return false;
}
do
if (i == loop->num_nodes)
{
free (bbs);
- return;
+ return false;
}
if (cond != const0_rtx
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);
free_EXPR_LIST_node (rconds);
free (bbs);
+
+ return true;
}
/* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support