#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
+#include "obstack.h"
#include "basic-block.h"
#include "cfgloop.h"
#include "cfglayout.h"
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;
/* BB must end in a simple conditional jump. */
- if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
+ if (EDGE_COUNT (bb->succs) != 2)
return NULL_RTX;
if (!any_condjump_p (BB_END (bb)))
return NULL_RTX;
/* With branches inside loop. */
- if (!flow_bb_inside_loop_p (loop, bb->succ->dest)
- || !flow_bb_inside_loop_p (loop, bb->succ->succ_next->dest))
+ if (!flow_bb_inside_loop_p (loop, EDGE_SUCC (bb, 0)->dest)
+ || !flow_bb_inside_loop_p (loop, EDGE_SUCC (bb, 1)->dest))
return NULL_RTX;
/* It must be executed just once each iteration (because otherwise we
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;
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;
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)
{
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
/* Some sanity checking. */
if (!flow_bb_inside_loop_p (loop, unswitch_on))
abort ();
- if (!unswitch_on->succ || !unswitch_on->succ->succ_next ||
- unswitch_on->succ->succ_next->succ_next)
+ if (EDGE_COUNT (unswitch_on->succs) != 2)
abort ();
if (!just_once_each_iteration_p (loop, unswitch_on))
abort ();
if (loop->inner)
abort ();
- if (!flow_bb_inside_loop_p (loop, unswitch_on->succ->dest))
+ if (!flow_bb_inside_loop_p (loop, EDGE_SUCC (unswitch_on, 0)->dest))
abort ();
- if (!flow_bb_inside_loop_p (loop, unswitch_on->succ->succ_next->dest))
+ if (!flow_bb_inside_loop_p (loop, EDGE_SUCC (unswitch_on, 1)->dest))
abort ();
entry = loop_preheader_edge (loop);
unswitch_on_alt = unswitch_on->rbi->copy;
true_edge = BRANCH_EDGE (unswitch_on_alt);
false_edge = FALLTHRU_EDGE (unswitch_on);
- latch_edge = loop->latch->rbi->copy->succ;
+ latch_edge = EDGE_SUCC (loop->latch->rbi->copy, 0);
/* Create a block with the condition. */
prob = true_edge->probability;
if (irred_flag)
{
switch_bb->flags |= BB_IRREDUCIBLE_LOOP;
- switch_bb->succ->flags |= EDGE_IRREDUCIBLE_LOOP;
- switch_bb->succ->succ_next->flags |= EDGE_IRREDUCIBLE_LOOP;
+ EDGE_SUCC (switch_bb, 0)->flags |= EDGE_IRREDUCIBLE_LOOP;
+ EDGE_SUCC (switch_bb, 1)->flags |= EDGE_IRREDUCIBLE_LOOP;
}
else
{
switch_bb->flags &= ~BB_IRREDUCIBLE_LOOP;
- switch_bb->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
- switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ EDGE_SUCC (switch_bb, 0)->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ EDGE_SUCC (switch_bb, 1)->flags &= ~EDGE_IRREDUCIBLE_LOOP;
}
/* Loopify from the copy of LOOP body, constructing the new loop. */
nloop = loopify (loops, latch_edge,
- loop->header->rbi->copy->pred, switch_bb);
+ EDGE_PRED (loop->header->rbi->copy, 0), switch_bb,
+ BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true);
/* Remove branches that are now unreachable in new loops. */
remove_path (loops, true_edge);