/* Split BB into entry part and the rest (the rest is the newly created block).
Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
- part. Returns the edge connecting the entry part to the rest. */
+ part. Returns the edge connecting the entry part to the rest.
+ DATA gets passed on to REDIRECT_EDGE_P. */
edge
-make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge))
+make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge, void*), void *data)
{
edge e, fallthru;
edge_iterator ei;
{
basic_block e_src;
- if (redirect_edge_p (e))
+ if (redirect_edge_p (e, data))
{
dummy->count += e->count ();
ei_next (&ei);
extern basic_block create_empty_bb (basic_block);
extern bool can_merge_blocks_p (basic_block, basic_block);
extern void merge_blocks (basic_block, basic_block);
-extern edge make_forwarder_block (basic_block, bool (*)(edge));
+extern edge make_forwarder_block (basic_block, bool (*)(edge, void*), void*);
extern basic_block force_nonfallthru (edge);
extern void tidy_fallthru_edge (edge);
extern void tidy_fallthru_edges (void);
}
/* Callback for make_forwarder_block. Returns true if the edge E is marked
- in the set MFB_REIS_SET. */
+ in the set SET(DATA). */
-static hash_set<edge> *mfb_reis_set;
static bool
-mfb_redirect_edges_in_set (edge e)
+mfb_redirect_edges_in_set (edge e, void *data)
{
- return mfb_reis_set->contains (e);
+ hash_set<edge> *set = (hash_set<edge> *)data;
+ return set->contains (e);
}
/* Creates a subloop of LOOP with latch edge LATCH. */
edge e, new_entry;
class loop *new_loop;
- mfb_reis_set = new hash_set<edge>;
+ hash_set<edge> *reis_set = new hash_set<edge>;
FOR_EACH_EDGE (e, ei, loop->header->preds)
{
if (e != latch)
- mfb_reis_set->add (e);
+ reis_set->add (e);
}
- new_entry = make_forwarder_block (loop->header, mfb_redirect_edges_in_set);
- delete mfb_reis_set;
+ new_entry = make_forwarder_block (loop->header, mfb_redirect_edges_in_set, reis_set);
+ delete reis_set;
loop->header = new_entry->src;
if (dump_file)
fprintf (dump_file, "Merged latch edges of loop %d\n", loop->num);
- mfb_reis_set = new hash_set<edge>;
+ hash_set<edge> *reis_set = new hash_set<edge>;
FOR_EACH_VEC_ELT (latches, i, e)
- mfb_reis_set->add (e);
- latch = make_forwarder_block (loop->header, mfb_redirect_edges_in_set);
- delete mfb_reis_set;
+ reis_set->add (e);
+ latch = make_forwarder_block (loop->header, mfb_redirect_edges_in_set, reis_set);
+ delete reis_set;
loop->header = latch->dest;
loop->latch = latch->src;
}
/* A callback for make_forwarder block, to redirect all edges except for
- MFB_KJ_EDGE to the entry part. E is the edge for that we should decide
+ OTHER(DATA) to the entry part. E is the edge for that we should decide
whether to redirect it. */
-edge mfb_kj_edge;
bool
-mfb_keep_just (edge e)
+mfb_keep_just (edge e, void *data)
{
- return e != mfb_kj_edge;
+ edge other = (edge)data;
+ return e != other;
}
/* True when a candidate preheader BLOCK has predecessors from LOOP. */
return NULL;
}
- mfb_kj_edge = loop_latch_edge (loop);
- latch_edge_was_fallthru = (mfb_kj_edge->flags & EDGE_FALLTHRU) != 0;
+ edge latch;
+ latch = loop_latch_edge (loop);
+ latch_edge_was_fallthru = (latch->flags & EDGE_FALLTHRU) != 0;
if (nentry == 1
&& ((flags & CP_FALLTHRU_PREHEADERS) == 0
|| (single_entry->flags & EDGE_CROSSING) == 0))
dummy = split_edge (single_entry);
else
{
- edge fallthru = make_forwarder_block (loop->header, mfb_keep_just);
+ edge fallthru = make_forwarder_block (loop->header, mfb_keep_just, latch);
dummy = fallthru->src;
loop->header = fallthru->dest;
}
discriminators to
distinguish loop
iterations. */
-extern edge mfb_kj_edge;
-
extern bool remove_path (edge, bool * = NULL, bitmap = NULL);
extern void place_new_loop (struct function *, class loop *);
extern void add_loop (class loop *, class loop *);
extern bool
duplicate_loop_body_to_header_edge (class loop *, edge, unsigned, sbitmap, edge,
vec<edge> *, int);
-extern bool mfb_keep_just (edge);
+extern bool mfb_keep_just (edge, void *);
basic_block create_preheader (class loop *, int);
extern void create_preheaders (int);
extern void force_single_succ_latches (void);
return retval;
}
+/* Callback function for make_forwarder_block which returns
+ true when E is not a latch. */
+
static bool
-mfb_keep_latches (edge e)
+mfb_keep_latches (edge e, void*)
{
return !((dom_info_available_p (CDI_DOMINATORS)
&& dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
create a forwarder. */
if (found_latch && ! any_abnormal && n > 1)
{
- edge fallthru = make_forwarder_block (bb, mfb_keep_latches);
+ edge fallthru = make_forwarder_block (bb, mfb_keep_latches, NULL);
loop->header = fallthru->dest;
if (! loops_state_satisfies_p (LOOPS_NEED_FIXUP))
{
must have only a single successor, but the original header had at
least two successors. */
loop->latch = NULL;
- mfb_kj_edge = single_succ_edge (new_preheader);
- loop->header = mfb_kj_edge->dest;
- latch = make_forwarder_block (tgt_bb, mfb_keep_just);
+ edge keep_edge;
+ keep_edge = single_succ_edge (new_preheader);
+ loop->header = keep_edge->dest;
+ latch = make_forwarder_block (tgt_bb, mfb_keep_just, keep_edge);
loop->header = latch->dest;
loop->latch = latch->src;
return true;