static rtx
may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
{
- rtx test, at, insn, op[2];
+ rtx test, at, insn, op[2], stest;
struct rtx_iv iv;
unsigned i;
enum machine_mode mode;
return NULL_RTX;
/* Condition must be invariant. */
- test = get_condition (BB_END (bb), &at, true);
+ test = get_condition (BB_END (bb), &at, true, false);
if (!test)
return NULL_RTX;
continue;
insn = iv_get_reaching_def (at, op[i]);
- if (!iv_analyse (insn, op[i], &iv))
+ if (!iv_analyze (insn, op[i], &iv))
return NULL_RTX;
if (iv.step != const0_rtx
|| iv.first_special)
return test;
}
+ stest = simplify_gen_relational (GET_CODE (test), SImode,
+ mode, op[0], op[1]);
+ if (stest == const0_rtx
+ || stest == const_true_rtx)
+ return stest;
+
return canon_condition (gen_rtx_fmt_ee (GET_CODE (test), SImode,
op[0], op[1]));
}
basic_block *bbs;
struct loop *nloop;
unsigned i;
- rtx cond, rcond, conds, rconds, acond, cinsn = NULL_RTX;
+ rtx cond, rcond = NULL_RTX, conds, rconds, acond, cinsn = NULL_RTX;
int repeat;
edge e;
/* Do not unswitch too much. */
if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching anymore, hit max level\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
return;
}
/* Only unswitch innermost loops. */
if (loop->inner)
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching, not innermost loop\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Not unswitching, not innermost loop\n");
return;
}
/* We must be able to duplicate loop body. */
if (!can_duplicate_loop_p (loop))
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching, can't duplicate loop\n");
+ 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. */
if (num_loop_insns (loop) > PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching, loop too big\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Not unswitching, loop too big\n");
return;
}
/* Do not unswitch in cold areas. */
if (!maybe_hot_bb_p (loop->header))
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching, not hot area\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Not unswitching, not hot area\n");
return;
}
/* Nor if the loop usually does not roll. */
if (expected_loop_iterations (loop) < 1)
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Not unswitching, loop iterations < 1\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
return;
}
return;
}
- rcond = reversed_condition (cond);
- if (rcond)
- rcond = canon_condition (rcond);
+ if (cond != const0_rtx
+ && cond != const_true_rtx)
+ {
+ rcond = reversed_condition (cond);
+ if (rcond)
+ rcond = canon_condition (rcond);
- /* Check whether the result can be predicted. */
- for (acond = cond_checked; acond; acond = XEXP (acond, 1))
- simplify_using_condition (XEXP (acond, 0), &cond, NULL);
+ /* Check whether the result can be predicted. */
+ for (acond = cond_checked; acond; acond = XEXP (acond, 1))
+ simplify_using_condition (XEXP (acond, 0), &cond, NULL);
+ }
if (cond == const_true_rtx)
{
else
rconds = cond_checked;
- if (rtl_dump_file)
- fprintf (rtl_dump_file, ";; Unswitching loop\n");
+ if (dump_file)
+ fprintf (dump_file, ";; Unswitching loop\n");
/* Unswitch the loop on this condition. */
nloop = unswitch_loop (loops, loop, bbs[i], cond, cinsn);
free_EXPR_LIST_node (conds);
if (rcond)
free_EXPR_LIST_node (rconds);
+
+ free (bbs);
}
/* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support