- phi = new_r_Phi(current_ir_graph, block, n, in, mode);
- DB((dbg, LEVEL_1, "Created new %+F in %+F for now redundant %+F\n", phi, block, op->node));
-
- if (get_nodes_block(op->node) == block) {
- /* The redundant node was in the current block:
- In that case, DO NOT update avail_out. If it was NOT
- avail although it is executed in this bLock, it is killed by a later
- instruction.
- */
- memop_t *phi_op = clone_memop_phi(op, phi);
-
- update_memop_avail(bl, phi_op);
-
- mark_replace_load(op, phi);
- } else {
- /* The redundant node is NOT in the current block and anticipated. */
- memop_t *phi_op = clone_memop_phi(op, phi);
+ if (have_some && !all_same) {
+ ir_mode *mode = op->value.mode;
+ ir_node **in, *phi;
+ memop_t *phi_op;
+
+ NEW_ARR_A(ir_node *, in, n);
+
+ for (i = n - 1; i >= 0; --i) {
+ ir_node *pred = get_Block_cfgpred_block(block, i);
+ block_t *pred_bl = get_block_entry(pred);
+
+ if (pred_bl->avail == NULL) {
+ /* create a new Load here and make to make it fully redundant */
+ dbg_info *db = get_irn_dbg_info(op->node);
+ ir_node *last_mem = find_last_memory(pred_bl);
+ ir_node *load, *def;
+ memop_t *new_op;
+
+ assert(last_mem != NULL);
+ load = new_rd_Load(db, current_ir_graph, pred, last_mem, op->value.address, mode, cons_none);
+ def = new_r_Proj(current_ir_graph, pred, load, mode, pn_Load_res);
+ DB((dbg, LEVEL_1, "Created new %+F in %+F for party redundant %+F\n", load, pred, op->node));
+
+ new_op = alloc_memop(load);
+ new_op->mem = new_r_Proj(current_ir_graph, pred, load, mode_M, pn_Load_M);
+ new_op->value.address = op->value.address;
+ new_op->value.id = op->value.id;
+ new_op->value.mode = mode;
+ new_op->value.value = def;
+
+ new_op->projs[pn_Load_M] = new_op->mem;
+ new_op->projs[pn_Load_res] = def;
+
+ new_op->prev = pred_bl->memop_backward;
+ pred_bl->memop_backward = new_op;
+
+ if (pred_bl->memop_forward == NULL)
+ pred_bl->memop_forward = new_op;
+
+ if (get_nodes_block(last_mem) == pred) {
+ /* We have add a new last memory op in pred block.
+ If pred had already a last mem, reroute all memory
+ users. */
+ reroute_all_mem_users(last_mem, new_op->mem);
+ } else {
+ /* reroute only those memory going through the pre block */
+ reroute_mem_through(last_mem, new_op->mem, pred);
+ }