+/**
+ * Check if the current block is the meet block of a its predecessors.
+ */
+static void check_for_cf_meet(ir_node *block, void *ctx)
+{
+ environment_t *env = (environment_t*)ctx;
+ int i, k, n;
+ pred_t *preds;
+
+ if (block == get_irg_end_block(get_irn_irg(block))) {
+ /* always create a partition for the end block */
+ partition_for_end_block(block, env);
+ return;
+ }
+
+ n = get_Block_n_cfgpreds(block);
+ if (n <= 1) {
+ /* Must have at least two predecessors */
+ return;
+ }
+
+ NEW_ARR_A(pred_t, preds, n);
+ k = 0;
+ for (i = n - 1; i >= 0; --i) {
+ ir_node *pred = get_Block_cfgpred(block, i);
+ ir_node *pred_block;
+
+ /* pred must be a direct jump to us */
+ if (! is_Jmp(pred) && ! is_Raise(pred) && !is_Bad(pred))
+ continue;
+
+ pred_block = get_nodes_block(skip_Proj(pred));
+
+ preds[k].pred = pred;
+ preds[k].index = i;
+ }
+
+ if (k > 1)
+ partition_for_block(block, preds, k, env);
+} /* check_for_cf_meet */
+
+/**
+ * Compare two nodes for root ordering.
+ */
+static int cmp_nodes(const void *a, const void *b)
+{
+ const ir_node *const *pa = (const ir_node*const*)a;
+ const ir_node *const *pb = (const ir_node*const*)b;
+ const ir_node *irn_a = *pa;
+ const ir_node *irn_b = *pb;
+ unsigned code_a = get_irn_opcode(irn_a);
+ unsigned code_b = get_irn_opcode(irn_b);
+ ir_mode *mode_a, *mode_b;
+ unsigned idx_a, idx_b;
+
+ /* try opcode first */
+ if (code_a != code_b)
+ return code_a - code_b;
+
+ /* try mode */
+ mode_a = get_irn_mode(irn_a);
+ mode_b = get_irn_mode(irn_b);
+
+ if (mode_a != mode_b)
+ return mode_a < mode_b ? -1 : +1;
+
+ /* last resort: index */
+ idx_a = get_irn_idx(irn_a);
+ idx_b = get_irn_idx(irn_b);
+
+ return (idx_a > idx_b) - (idx_a < idx_b);
+} /* cmp_nodes */
+
+/**
+ * Add the roots to all blocks.
+ */
+static void add_roots(ir_graph *irg, environment_t *env)
+{
+ unsigned idx, n = get_irg_last_idx(irg);
+ ir_node **live_outs = env->live_outs;
+ block_t *bl;
+
+ for (idx = 0; idx < n; ++idx) {
+ ir_node *block = live_outs[idx];
+
+ if (block != NULL && is_Block(block)) {
+ block_t *bl = get_Block_entry(block);
+
+ if (bl != NULL) {
+ ir_node *irn = get_idx_irn(irg, idx);
+
+ if (!irn_visited_else_mark(irn)) {
+ ARR_APP1(ir_node *, bl->roots, irn);
+ }
+ }
+ }
+ }
+ /*
+ * Now sort the roots to normalize them as good as possible.
+ * Else, we will split identical blocks if we start which different roots.
+ */
+ for (bl = env->all_blocks; bl != NULL; bl = bl->all_next) {
+ size_t i, n = ARR_LEN(bl->roots);
+
+#if 1
+ /* TODO: is this really needed? The roots are already in
+ idx-order by construction, which might be good enough. */
+ qsort(bl->roots, n, sizeof(bl->roots[0]), cmp_nodes);
+#endif
+
+ DB((dbg, LEVEL_2, " Adding Roots for block %+F\n ", bl->block));
+ /* ok, add them sorted */
+ for (i = 0; i < n; ++i) {
+ DB((dbg, LEVEL_2, "%+F, ", bl->roots[i]));
+ create_node(bl->roots[i], bl, env);
+ }
+ DB((dbg, LEVEL_2, "\n"));
+ DEL_ARR_F(bl->roots);
+ bl->roots = NULL;
+ }
+} /* add_roots */
+#endif /* GENERAL_SHAPE */