+static INLINE int get_hyp_color(ir_node *irn) {
+ hyp_col_t hc;
+ hyp_col_t *found;
+ hc.irn = irn;
+ found = set_find(hyp_cols, &hc, sizeof(hc), HASH_PTR(irn));
+ if (found)
+ return found->color;
+ else
+ return get_irn_color(irn);
+}
+
+/**
+ * Sets the hypothetic color of an irn
+ */
+static INLINE void set_hyp_color(ir_node *irn, int color) {
+ hyp_col_t hc;
+ hyp_col_t *found;
+ hc.irn = irn;
+ found = set_find(hyp_cols, &hc, sizeof(hc), HASH_PTR(irn));
+ if (found)
+ found->color = color;
+ else {
+ hc.color = color;
+ set_insert(hyp_cols, &hc, sizeof(hc), HASH_PTR(irn));
+ }
+}
+
+
+
+/**
+ * Variable neede in _color_irn.
+ * Not on stack, because never changed during recursion.
+ */
+static perform_t _color_irn_perform;
+
+/**
+ * Get all nodes which conflict with the color-setting of a node, because they
+ * have the same color and are living together at some point in time.
+ * @param irn The ir_node to find conflicting nodes for
+ * @param color The color the conflicting nodes must have
+ * @param bl The root-block of the dom-sub-tree to start the search from.
+ * @param exc An exceptional node which is never added to the result set of conflicting nodes
+ * @param res An obstack to grow the resulting nodes on.
+ */
+static void get_conflicting_nodes(const ir_node *irn, int color, ir_node *bl, const ir_node *exc, struct obstack *res) {
+ struct obstack q;
+ int in, out;
+
+ /* setup the queue */
+ obstack_init(&q);
+ obstack_ptr_grow(&q, bl);
+ in = 1;
+ out = 0;
+
+ /* process the queue */
+ while (out < in) {
+ ir_node *curr_bl, *sub_bl;
+ int i, max;
+
+ curr_bl = ((ir_node **)obstack_base(&q))[out++];
+
+ /* Add to the result all nodes in the block which live in target color
+ * and interfere with the irn */
+ for (i = 0, max = get_irn_n_outs(curr_bl); i < max; ++i) {
+ ir_node *n = get_irn_out(curr_bl, i);
+ int n_col;
+ if (!is_allocatable_irn(n))
+ continue;
+ if (_color_irn_perform == perform)
+ n_col = get_irn_color(n);
+ else
+ n_col = get_hyp_color(n);
+
+ if (n != exc && get_hyp_color(n) == color && phi_ops_interfere(irn, n))
+ obstack_ptr_grow(res, n);
+ }
+
+ /* If irn lives out check i-dominated blocks where the irn lives in */
+ /* Fill the queue */
+ if (is_live_out(curr_bl, irn)) {
+ dominates_for_each(curr_bl, sub_bl)
+ if (is_live_in(sub_bl, irn)) {
+ obstack_ptr_grow(&q, sub_bl);
+ in++;
+ }
+ }
+ }
+
+ obstack_free(&q, NULL);