Simplify collect_and_rewire_users(): Use get_edge_src_pos() instead of searching...
[libfirm] / ir / be / ia32 / ia32_x87.c
index 2b1e41a..fe2607a 100644 (file)
@@ -420,36 +420,34 @@ static inline const arch_register_t *get_st_reg(int index)
        return &ia32_registers[REG_ST0 + index];
 }
 
-/* -------------- x87 perm --------------- */
-
 /**
- * Creates a fxch for shuffle.
- *
- * @param state     the x87 state
- * @param pos       parameter for fxch
- * @param block     the block were fxch is inserted
+ * Create a fxch node before another node.
  *
- * Creates a new fxch node and reroute the user of the old node
- * to the fxch.
+ * @param state   the x87 state
+ * @param n       the node after the fxch
+ * @param pos     exchange st(pos) with st(0)
  *
- * @return the fxch node
+ * @return the fxch
  */
-static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block)
+static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
 {
-       ir_node         *fxch;
-       ia32_x87_attr_t *attr;
+       x87_fxch(state, pos);
 
-       fxch = new_bd_ia32_fxch(NULL, block);
-       attr = get_ia32_x87_attr(fxch);
+       ir_node         *const block = get_nodes_block(n);
+       ir_node         *const fxch  = new_bd_ia32_fxch(NULL, block);
+       ia32_x87_attr_t *const attr  = get_ia32_x87_attr(fxch);
        attr->x87[0] = get_st_reg(pos);
        attr->x87[2] = get_st_reg(0);
 
        keep_alive(fxch);
 
-       x87_fxch(state, pos);
+       sched_add_before(n, fxch);
+       DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
        return fxch;
 }
 
+/* -------------- x87 perm --------------- */
+
 /**
  * Calculate the necessary permutations to reach dst_state.
  *
@@ -470,7 +468,6 @@ static x87_state *x87_shuffle(ir_node *block, x87_state *state, const x87_state
        int      i, n_cycles, k, ri;
        unsigned cycles[4], all_mask;
        char     cycle_idx[4][8];
-       ir_node  *fxch, *before, *after;
 
        assert(state->depth == dst_state->depth);
 
@@ -546,73 +543,31 @@ static x87_state *x87_shuffle(ir_node *block, x87_state *state, const x87_state
        }
 #endif
 
-       after = NULL;
-
        /*
         * Find the place node must be insert.
         * We have only one successor block, so the last instruction should
         * be a jump.
         */
-       before = sched_last(block);
+       ir_node *const before = sched_last(block);
        assert(is_cfop(before));
 
        /* now do the permutations */
        for (ri = 0; ri < n_cycles; ++ri) {
                if ((cycles[ri] & 1) == 0) {
                        /* this cycle does not include the tos */
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
-                       if (after)
-                               sched_add_after(after, fxch);
-                       else
-                               sched_add_before(before, fxch);
-                       after = fxch;
+                       x87_create_fxch(state, before, cycle_idx[ri][0]);
                }
                for (k = 1; cycle_idx[ri][k] != -1; ++k) {
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][k], block);
-                       if (after)
-                               sched_add_after(after, fxch);
-                       else
-                               sched_add_before(before, fxch);
-                       after = fxch;
+                       x87_create_fxch(state, before, cycle_idx[ri][k]);
                }
                if ((cycles[ri] & 1) == 0) {
                        /* this cycle does not include the tos */
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
-                       sched_add_after(after, fxch);
+                       x87_create_fxch(state, before, cycle_idx[ri][0]);
                }
        }
        return state;
 }
 
-/**
- * Create a fxch node before another node.
- *
- * @param state   the x87 state
- * @param n       the node after the fxch
- * @param pos     exchange st(pos) with st(0)
- *
- * @return the fxch
- */
-static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
-{
-       ir_node         *fxch;
-       ia32_x87_attr_t *attr;
-       ir_node         *block = get_nodes_block(n);
-
-       x87_fxch(state, pos);
-
-       fxch = new_bd_ia32_fxch(NULL, block);
-       attr = get_ia32_x87_attr(fxch);
-       attr->x87[0] = get_st_reg(pos);
-       attr->x87[2] = get_st_reg(0);
-
-       keep_alive(fxch);
-
-       sched_add_before(n, fxch);
-       DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
-       return fxch;
-}
-
 /**
  * Create a fpush before node n.
  *
@@ -1069,12 +1024,7 @@ static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *
 
                /* if the user is scheduled after the store: rewire */
                if (sched_is_scheduled(user) && sched_comes_after(store, user)) {
-                       int i;
-                       /* find the input of the user pointing to the old value */
-                       for (i = get_irn_arity(user) - 1; i >= 0; i--) {
-                               if (get_irn_n(user, i) == old_val)
-                                       set_irn_n(user, i, new_val);
-                       }
+                       set_irn_n(user, get_edge_src_pos(edge), new_val);
                }
        }
 }