+#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
+ && EDGE_COUNT ((e)->dest->preds) >= 2)
+
+#define EDGE_COUNT(ev) VEC_length (edge, (ev))
+#define EDGE_I(ev,i) VEC_index (edge, (ev), (i))
+#define EDGE_PRED(bb,i) VEC_index (edge, (bb)->preds, (i))
+#define EDGE_SUCC(bb,i) VEC_index (edge, (bb)->succs, (i))
+
+/* Returns true if BB has precisely one successor. */
+
+static inline bool
+single_succ_p (basic_block bb)
+{
+ return EDGE_COUNT (bb->succs) == 1;
+}
+
+/* Returns true if BB has precisely one predecessor. */
+
+static inline bool
+single_pred_p (basic_block bb)
+{
+ return EDGE_COUNT (bb->preds) == 1;
+}
+
+/* Returns the single successor edge of basic block BB. Aborts if
+ BB does not have exactly one successor. */
+
+static inline edge
+single_succ_edge (basic_block bb)
+{
+ gcc_assert (single_succ_p (bb));
+ return EDGE_SUCC (bb, 0);
+}
+
+/* Returns the single predecessor edge of basic block BB. Aborts
+ if BB does not have exactly one predecessor. */
+
+static inline edge
+single_pred_edge (basic_block bb)
+{
+ gcc_assert (single_pred_p (bb));
+ return EDGE_PRED (bb, 0);
+}
+
+/* Returns the single successor block of basic block BB. Aborts
+ if BB does not have exactly one successor. */
+
+static inline basic_block
+single_succ (basic_block bb)
+{
+ return single_succ_edge (bb)->dest;
+}
+
+/* Returns the single predecessor block of basic block BB. Aborts
+ if BB does not have exactly one predecessor.*/
+
+static inline basic_block
+single_pred (basic_block bb)
+{
+ return single_pred_edge (bb)->src;
+}
+
+/* Iterator object for edges. */
+
+typedef struct {
+ unsigned index;
+ VEC(edge,gc) **container;
+} edge_iterator;
+
+static inline VEC(edge,gc) *
+ei_container (edge_iterator i)
+{
+ gcc_assert (i.container);
+ return *i.container;
+}
+
+#define ei_start(iter) ei_start_1 (&(iter))
+#define ei_last(iter) ei_last_1 (&(iter))
+
+/* Return an iterator pointing to the start of an edge vector. */
+static inline edge_iterator
+ei_start_1 (VEC(edge,gc) **ev)
+{
+ edge_iterator i;
+
+ i.index = 0;
+ i.container = ev;
+
+ return i;
+}
+
+/* Return an iterator pointing to the last element of an edge
+ vector. */
+static inline edge_iterator
+ei_last_1 (VEC(edge,gc) **ev)
+{
+ edge_iterator i;
+
+ i.index = EDGE_COUNT (*ev) - 1;
+ i.container = ev;
+
+ return i;
+}
+
+/* Is the iterator `i' at the end of the sequence? */
+static inline bool
+ei_end_p (edge_iterator i)
+{
+ return (i.index == EDGE_COUNT (ei_container (i)));
+}
+
+/* Is the iterator `i' at one position before the end of the
+ sequence? */
+static inline bool
+ei_one_before_end_p (edge_iterator i)
+{
+ return (i.index + 1 == EDGE_COUNT (ei_container (i)));
+}
+
+/* Advance the iterator to the next element. */
+static inline void
+ei_next (edge_iterator *i)
+{
+ gcc_assert (i->index < EDGE_COUNT (ei_container (*i)));
+ i->index++;
+}
+
+/* Move the iterator to the previous element. */
+static inline void
+ei_prev (edge_iterator *i)
+{
+ gcc_assert (i->index > 0);
+ i->index--;
+}
+
+/* Return the edge pointed to by the iterator `i'. */
+static inline edge
+ei_edge (edge_iterator i)
+{
+ return EDGE_I (ei_container (i), i.index);
+}
+
+/* Return an edge pointed to by the iterator. Do it safely so that
+ NULL is returned when the iterator is pointing at the end of the
+ sequence. */
+static inline edge
+ei_safe_edge (edge_iterator i)
+{
+ return !ei_end_p (i) ? ei_edge (i) : NULL;
+}
+
+/* Return 1 if we should continue to iterate. Return 0 otherwise.
+ *Edge P is set to the next edge if we are to continue to iterate
+ and NULL otherwise. */
+
+static inline bool
+ei_cond (edge_iterator ei, edge *p)
+{
+ if (!ei_end_p (ei))
+ {
+ *p = ei_edge (ei);
+ return 1;
+ }
+ else
+ {
+ *p = NULL;
+ return 0;
+ }
+}
+
+/* This macro serves as a convenient way to iterate each edge in a
+ vector of predecessor or successor edges. It must not be used when
+ an element might be removed during the traversal, otherwise
+ elements will be missed. Instead, use a for-loop like that shown
+ in the following pseudo-code:
+
+ FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
+ {
+ IF (e != taken_edge)
+ remove_edge (e);
+ ELSE
+ ei_next (&ei);
+ }
+*/
+
+#define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \
+ for ((ITER) = ei_start ((EDGE_VEC)); \
+ ei_cond ((ITER), &(EDGE)); \
+ ei_next (&(ITER)))