+/**
+ * check if a node n is clean in block block.
+ */
+static int _is_clean(ir_node *n, ir_node *block)
+{
+ int i;
+
+ if (get_nodes_block(n) != block)
+ return 1;
+ if (is_Phi(n))
+ return 1;
+
+ if (irn_visited(n))
+ return 0;
+
+ if (! is_nice_value(n))
+ goto bad;
+ for (i = get_irn_arity(n) - 1; i >= 0; --i) {
+ ir_node *pred = get_irn_n(n, i);
+ if (! _is_clean(pred, block))
+ goto bad;
+ }
+ return 1;
+bad:
+ mark_irn_visited(n);
+ return 0;
+}
+
+/**
+ * check if a node n is clean.
+ */
+static int is_clean(ir_node *n)
+{
+ int res = _is_clean(n, get_nodes_block(n));
+ return res;
+}
+
+/**
+ * Clean a node set.
+ * This function is called for node sets with is_clean
+ * nodes only, so we must just remove nodes that don't
+ * have available inputs
+ */
+static void clean_node_set(node_set *set, ir_node *blk)
+{
+ ir_node *n, *pred, *pred_blk;
+ int i;
+
+restart:
+ for (n = node_set_first(set); n; n = node_set_next(set)) {
+ for (i = get_irn_intra_arity(n) - 1; i >= 0; --i) {
+ pred = get_irn_intra_n(n, i);
+
+ pred_blk = get_irn_intra_n(pred, -1);
+ if (block_dominates(pred_blk, blk))
+ continue;
+ /* pred do not dominate it, but may be in the set */
+ if (node_lookup(set, pred) != NULL)
+ continue;
+ /* we found a node that must be removed */
+ node_set_break(set);
+ node_set_remove(set, n);
+ DB((dbg, LEVEL_2, "<-- Cleaning %+F\n", n));
+ goto restart;
+ }
+ }
+}
+