+/**
+ * A new assign...
+ */
+static void assign_new(ir_node *block, be_chordal_alloc_env_t *alloc_env, bitset_t *live_end_dom)
+{
+ be_chordal_env_t *env = alloc_env->chordal_env;
+ bitset_t *colors = alloc_env->colors;
+ bitset_t *in_colors = alloc_env->in_colors;
+ bitset_t *live = bitset_irg_malloc(env->irg);
+ const arch_env_t *arch_env = env->birg->main_env->arch_env;
+ be_irg_t *birg = env->birg;
+ lv_chk_t *lv = be_get_birg_liveness_chk(birg);
+
+ bitset_pos_t elm;
+ ir_node *irn;
+
+ bitset_clear_all(colors);
+ bitset_clear_all(in_colors);
+
+ /*
+ * All variables which are live in to this block are live out
+ * of the immediate dominator thanks to SSA properties. As we
+ * have already visited the immediate dominator, we know these
+ * variables. The only tjing left is to check wheather they are live
+ * in here (they also could be phi arguments to some ohi not
+ * in this block, hence we have to check).
+ */
+ bitset_foreach (live_end_dom, elm) {
+ ir_node *irn = get_idx_irn(env->irg, elm);
+ if (lv_chk_bl_in(lv, block, irn)) {
+ const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
+ int col;
+
+ assert(be_is_live_in(env->birg->lv, block, irn));
+ assert(reg && "Node must have been assigned a register");
+ col = arch_register_get_index(reg);
+
+ DBG((dbg, LEVEL_4, "%+F has reg %s\n", irn, reg->name));
+
+ /* Mark the color of the live in value as used. */
+ bitset_set(colors, col);
+ bitset_set(in_colors, col);
+
+ /* Mark the value live in. */
+ bitset_set(live, elm);
+ }
+
+ else {
+ assert(!be_is_live_in(env->birg->lv, block, irn));
+ }
+ }
+
+ /*
+ * Mind that the sequence of defs from back to front defines a perfect
+ * elimination order. So, coloring the definitions from first to last
+ * will work.
+ */
+ sched_foreach (block, irn) {
+ int nr = get_irn_idx(irn);
+ int ignore = arch_irn_is(arch_env, irn, ignore);
+
+ /* Clear the color upon a last use. */
+ if(!is_Phi(irn)) {
+ int i;
+ for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
+ ir_node *op = get_irn_n(irn, i);
+
+ /*
+ * If the reg class matches and the operand is not live after
+ * the node, irn is a last use of op and the register can
+ * be freed.
+ */
+ if (has_reg_class(env, op)) {
+ if (!be_lv_chk_after_irn(birg, op, irn)) {
+ const arch_register_t *reg = arch_get_irn_register(arch_env, op);
+ int col;
+
+ assert(reg && "Register must have been assigned");
+ col = arch_register_get_index(reg);
+ bitset_clear(colors, col);
+ bitset_clear(live, nr);
+ }
+ }
+ }
+ }
+
+ if (has_reg_class(env, irn)) {
+ const arch_register_t *reg;
+ int col = NO_COLOR;
+
+ /*
+ * Assign a color, if it is a local def. Global defs already have a
+ * color.
+ */
+ if(ignore || pset_find_ptr(alloc_env->pre_colored, irn)) {
+ reg = arch_get_irn_register(arch_env, irn);
+ col = reg->index;
+ assert(!bitset_is_set(colors, col) && "pre-colored register must be free");
+ } else {
+ col = get_next_free_reg(alloc_env, colors);
+ reg = arch_register_for_index(env->cls, col);
+ assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet");
+ assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register");
+ }
+
+ bitset_set(colors, col);
+ arch_set_irn_register(arch_env, irn, reg);
+
+ DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n", arch_register_get_name(reg), col, irn));
+
+ assert(!bitset_is_set(live, nr) && "Value's definition must not have been encountered");
+ bitset_set(live, nr);
+ }
+
+ }
+
+ dominates_for_each (block, irn) {
+ assign_new(irn, alloc_env, live);
+ }
+
+ bitset_free(live);
+}
+