- /* iterate over all blocks */
- pmap_foreach(chordal_env->border_heads, pme) {
- border_t *curr;
- struct list_head *head = pme->value;
-
- /* iterate over the first 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;
- if (!is_Phi(curr->irn))
- break;
-
- 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(values_interfere(chordal_env->lv, 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);
+
+ /* this is commented out because it will fail in case of unknown float */
+#if 0
+ ir_mode *m_phi = get_irn_mode(phi), *m_dupl = get_irn_mode(dupl);
+
+ /*
+ Conv signed <-> unsigned is killed on ia32
+ check for: (both int OR both float) AND equal mode sizes
+ */
+ assert(((mode_is_int(m_phi) && mode_is_int(m_dupl)) ||
+ (mode_is_float(m_phi) && mode_is_float(m_dupl))) &&
+ (get_mode_size_bits(m_phi) == get_mode_size_bits(m_dupl)));
+#endif /* if 0 */
+
+ 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->birg->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;
+ }