- in[0] = arg;
- in[1] = get_node_for_register(pairs, n, cycle->elems[i + 1], 0);
-
- cpyxchg = new_Perm(fact, reg_class, env->chord_env->irg, block, 2, in);
- set_Proj_pred(res, cpyxchg);
- set_Proj_proj(res, 0);
- set_Proj_pred(get_node_for_register(pairs, n, cycle->elems[i], 1), cpyxchg);
- set_Proj_proj(get_node_for_register(pairs, n, cycle->elems[i], 1), 1);
+ in[0] = arg1;
+ in[1] = arg2;
+
+ /* At this point we have to handle the following problem: */
+ /* */
+ /* If we have a cycle with more than two elements, then */
+ /* this could correspond to the following Perm node: */
+ /* */
+ /* +----+ +----+ +----+ */
+ /* | r1 | | r2 | | r3 | */
+ /* +-+--+ +-+--+ +--+-+ */
+ /* | | | */
+ /* | | | */
+ /* +-+--------+---------+-+ */
+ /* | Perm | */
+ /* +-+--------+---------+-+ */
+ /* | | | */
+ /* | | | */
+ /* +-+--+ +-+--+ +--+-+ */
+ /* |Proj| |Proj| |Proj| */
+ /* | r2 | | r3 | | r1 | */
+ /* +----+ +----+ +----+ */
+ /* */
+ /* This node is about to be split up into two 2x Perm's */
+ /* for which we need 4 Proj's and the one additional Proj */
+ /* of the first Perm has to be one IN of the second. So in */
+ /* general we need to create one additional Proj for each */
+ /* "middle" Perm and set this to one in node of the successor */
+ /* Perm. */
+
+ DBG((mod, LEVEL_1, "%+F creating exchange node (%+F, %s) and (%+F, %s) with\n",
+ irn, arg1, cycle->elems[i]->name, arg2, cycle->elems[i + 1]->name));
+ DBG((mod, LEVEL_1, "%+F (%+F, %s) and (%+F, %s)\n",
+ irn, res1, cycle->elems[i]->name, res2, cycle->elems[i + 1]->name));
+
+ cpyxchg = be_new_Perm(reg_class, env->chord_env->irg, block, 2, in);
+
+ if (i > 0) {
+ /* cycle is not done yet */
+ int pidx = get_pairidx_for_regidx(pairs, n, cycle->elems[i]->index, 0);
+
+ /* create intermediate proj */
+ res1 = new_r_Proj(get_irn_irg(irn), block, cpyxchg, get_irn_mode(res1), 0);
+
+ /* set as in for next Perm */
+ pairs[pidx].in_node = res1;
+ }
+ else {
+ sched_remove(res1);
+ }
+
+ sched_remove(res2);
+
+ set_Proj_pred(res2, cpyxchg);
+ set_Proj_proj(res2, 0);
+ set_Proj_pred(res1, cpyxchg);
+ set_Proj_proj(res1, 1);
+
+ sched_add_after(sched_point, res1);
+ sched_add_after(sched_point, res2);
+
+ arch_set_irn_register(arch_env, res2, cycle->elems[i + 1]);
+ arch_set_irn_register(arch_env, res1, cycle->elems[i]);
+
+ /* insert the copy/exchange node in schedule after the magic schedule node (see above) */
+ sched_add_after(sched_point, cpyxchg);
+
+ DBG((mod, LEVEL_1, "replacing %+F with %+F, placed new node after %+F\n", irn, cpyxchg, sched_point));
+
+ /* set the new scheduling point */
+ sched_point = res1;