+static ir_region *new_NaturalLoop(struct obstack *obst, ir_region *head)
+{
+ ir_region *reg = alloc_region(obst, ir_rk_WhileLoop);
+ ir_region *c, *n;
+ size_t i, j, k, len, n_pred, n_succ;
+
+ /* count number of parts */
+ for (len = 0, c = head; c != NULL; c = (ir_region*) c->link)
+ ++len;
+
+ reg->nr = head->nr;
+ reg->parts = NEW_ARR_D(ir_reg_or_blk, obst, len);
+
+ /* enter all parts */
+ for (i = 0, c = head; c != NULL; c = n) {
+ reg->parts[i++].region = c;
+ c->parent = reg;
+ n = (ir_region*) c->link;
+ c->link = NULL;
+ }
+
+ /* count number of preds */
+ n_pred = 0;
+ for (i = get_region_n_preds(head); i > 0;) {
+ ir_region *pred = get_region_pred(head, --i);
+ if (pred->parent != reg)
+ ++n_pred;
+ }
+ reg->pred = NEW_ARR_D(ir_region *, obst, n_pred);
+ for (j = 0, i = get_region_n_preds(head); i > 0;) {
+ ir_region *pred = get_region_pred(head, --i);
+ if (pred->parent != reg)
+ reg->pred[j++] = pred;
+ }
+
+ /* count number of succs */
+ n_succ = 0;
+ for (j = 0; j < len; ++j) {
+ ir_region *pc = reg->parts[j].region;
+ for (i = get_region_n_succs(pc); i > 0;) {
+ ir_region *succ = get_region_succ(pc, --i);
+ if (succ->parent != reg)
+ ++n_succ;
+ }
+ }
+ reg->succ = NEW_ARR_D(ir_region *, obst, n_succ);
+ k = 0;
+ for (j = 0; j < len; ++j) {
+ ir_region *pc = reg->parts[j].region;
+ for (i = get_region_n_succs(pc); i > 0;) {
+ ir_region *succ = get_region_succ(pc, --i);
+ if (succ->parent != reg)
+ reg->succ[k++] = succ;
+ }
+ }
+
+ DEBUG_ONLY(
+ DB((dbg, LEVEL_2, " Created NaturalLoop(%u)Head(%u)\n", reg->nr, head->nr));
+ for (i = 1; i < len; ++i) {
+ ir_region *p = reg->parts[i].region;
+ DB((dbg, LEVEL_2, " Body(%u)\n", p->nr));
+ }
+ )
+ return reg;
+} /* new_NaturalLoop */
+
+/**
+ * Return true if region a is an ancestor of region b in DFS search.
+ */
+static int is_ancestor(const ir_region *a, const ir_region *b)
+{