/* Natural loop discovery code for GNU compiler.
- Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
loop->exits = GGC_CNEW (struct loop_exit);
loop->exits->next = loop->exits->prev = loop->exits;
+ loop->can_be_parallel = false;
return loop;
}
another edge. */
static edge
-find_subloop_latch_edge_by_ivs (struct loop *loop, VEC (edge, heap) *latches)
+find_subloop_latch_edge_by_ivs (struct loop *loop ATTRIBUTE_UNUSED, VEC (edge, heap) *latches)
{
edge e, latch = VEC_index (edge, latches, 0);
unsigned i;
- tree phi, lop;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree lop;
basic_block bb;
/* Find the candidate for the latch edge. */
/* Check for a phi node that would deny that this is a latch edge of
a subloop. */
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
lop = PHI_ARG_DEF_FROM_EDGE (phi, latch);
/* Ignore the values that are not changed inside the subloop. */
if (TREE_CODE (lop) != SSA_NAME
|| SSA_NAME_DEF_STMT (lop) == phi)
continue;
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (lop));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (lop));
if (!bb || !flow_bb_inside_loop_p (loop, bb))
continue;
/* Return nonzero if basic block BB belongs to LOOP. */
bool
-flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
+flow_bb_inside_loop_p (const struct loop *loop, const_basic_block bb)
{
struct loop *source_loop;
/* Enumeration predicate for get_loop_body_with_size. */
static bool
-glb_enum_p (basic_block bb, void *glb_loop)
+glb_enum_p (const_basic_block bb, const void *glb_loop)
{
- struct loop *loop = (struct loop *) glb_loop;
+ const struct loop *const loop = (const struct loop *) glb_loop;
return (bb != loop->header
&& dominated_by_p (CDI_DOMINATORS, bb, loop->header));
}
unsigned max_size)
{
return dfs_enumerate_from (loop->header, 1, glb_enum_p,
- body, max_size, (void *) loop);
+ body, max_size, loop);
}
/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
return tovisit;
}
+/* Gets body of a LOOP sorted via provided BB_COMPARATOR. */
+
+basic_block *
+get_loop_body_in_custom_order (const struct loop *loop,
+ int (*bb_comparator) (const void *, const void *))
+{
+ basic_block *bbs = get_loop_body (loop);
+
+ qsort (bbs, loop->num_nodes, sizeof (basic_block), bb_comparator);
+
+ return bbs;
+}
+
/* Get body of a LOOP in breadth first sort order. */
basic_block *
/* Returns true if E is an exit of LOOP. */
bool
-loop_exit_edge_p (const struct loop *loop, edge e)
+loop_exit_edge_p (const struct loop *loop, const_edge e)
{
return (flow_bb_inside_loop_p (loop, e->src)
&& !flow_bb_inside_loop_p (loop, e->dest));
else
return NULL;
}
+
+/* Returns true when BB has an edge exiting LOOP. */
+
+bool
+is_loop_exit (struct loop *loop, basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (loop_exit_edge_p (loop, e))
+ return true;
+
+ return false;
+}