- /* iterate over all blocks */
- pmap_foreach(chordal_env->border_heads, pme) {
- border_t *curr;
- struct list_head *head = pme->value;
-
- /* iterate over all ops in the block */
- list_for_each_entry_reverse(border_t, curr, head, list)
- if (curr->is_def && curr->is_real && is_Phi(curr->irn)) {
- const arch_register_t *phi_reg, *arg_reg;
- phi_reg = get_reg(curr->irn);
- /* iterate over all args of phi */
- for(i=0, max=get_irn_arity(curr->irn); i<max; ++i) {
- arg_reg = get_reg(get_irn_n(curr->irn, i));
- assert(phi_reg == arg_reg && "WTF? You can do it better!?");
+ DBG((dbg, LEVEL_1, " for %+F(%s) -- %+F(%s)\n", phi, phi_reg->name, arg, arg_reg->name));
+
+ if(nodes_interfere(chordal_env, phi, arg)) {
+ /* Insert a duplicate in arguments block,
+ * make it the new phi arg,
+ * set its register,
+ * insert it into schedule,
+ * pin it
+ */
+ ir_node *dupl = be_new_Copy(cls, chordal_env->irg, arg_block, arg);
+ assert(get_irn_mode(phi) == get_irn_mode(dupl));
+ set_irn_n(phi, i, dupl);
+ set_reg(dupl, phi_reg);
+ sched_add_after(sched_skip(sched_last(arg_block), 0, sched_skip_cf_predicator, chordal_env->main_env->arch_env), dupl);
+ pin_irn(dupl, phi_block);
+ DBG((dbg, LEVEL_1, " they do interfere: insert %+F(%s)\n", dupl, get_reg(dupl)->name));
+ continue; /* with next argument */
+ }
+
+ if (phi_reg == arg_reg) {
+ /* Phi and arg have the same register,
+ * so pin and continue
+ */
+ pin_irn(arg, phi_block);
+ DBG((dbg, LEVEL_1, " arg has same reg: pin %+F(%s)\n", arg, get_reg(arg)->name));
+ continue;
+ }
+
+ DBG((dbg, LEVEL_1, " they do not interfere\n"));
+ assert(is_Proj(arg));
+ /*
+ * First check if there is an other phi
+ * - in the same block
+ * - having arg at the current pos in its arg-list
+ * - having the same color as arg
+ *
+ * If found, then pin the arg (for that phi)
+ */
+ if (!is_pinned(arg)) {
+ ir_node *other_phi;
+ DBG((dbg, LEVEL_1, " searching for phi with same arg having args register\n"));
+ for(other_phi = get_irn_link(phi_block); other_phi; other_phi = get_irn_link(other_phi)) {
+ assert(is_Phi(other_phi) && get_nodes_block(phi) == get_nodes_block(other_phi) && "link fields are screwed up");
+ if (get_irn_n(other_phi, i) == arg && get_reg(other_phi) == arg_reg) {
+ DBG((dbg, LEVEL_1, " found %+F(%s)\n", other_phi, get_reg(other_phi)->name));
+ pin_irn(arg, phi_block);
+ break;
+ }