- ir_node *nodes_block;
- repairs_t key, *value_pred;
- int i, n;
-
- DDMN(node);
- nodes_block = get_nodes_block(node);
-
- /* If the predecessor is found. */
- if ((pos == -2 && value->link[pos] != NULL))
- return;
-
- n = get_Block_n_cfgpreds(nodes_block);
-
- for (i = n - 1; i >= 0; --i) {
- ir_node *pred = get_Block_cfgpred(nodes_block, i);
-
- key.irn = nodes_block;
- value_pred = set_find(repairs, &key, sizeof(key), HASH_PTR(key.irn));
- /* If nodes_block don't have the necessary information and the predecessor of it isn't
- visited "pred_search" was called recursive. Else the necessary information is found
- and the recursion stops. */
- if (value_pred == NULL || value_pred->link[pos] == NULL) {
- if (get_irn_link(pred) != PRED_SEARCH) {
- set_irn_link(node, PRED_SEARCH);
- pred_search(pred, value, repairs, pos, phi_pred);
- }
- }
- else {
- if (value->link[pos] == NULL && pos != -2) {
- if (get_Block_dom_depth(value->irn) >=
- get_Block_dom_depth(get_nodes_block(value_pred->link[pos]))) {
- value->link[pos] = value_pred->link[pos];
- pos = -2;
- break;
+ env_t *env = (env_t*)ctx;
+ ir_graph *irg = get_irn_irg(node);
+ ir_node *addr, *block, *mem, *val;
+ ir_mode *mode;
+ unsigned vnum;
+
+ if (is_Load(node)) {
+ /* a load, check if we can resolve it */
+ addr = get_Load_ptr(node);
+
+ DB((dbg, SET_LEVEL_3, " checking %+F for replacement ", node));
+ if (! is_Sel(addr)) {
+ DB((dbg, SET_LEVEL_3, "no Sel input (%+F)\n", addr));
+ return;
+ }
+
+ if (! pset_find_ptr(env->sels, addr)) {
+ DB((dbg, SET_LEVEL_3, "Sel %+F has no VNUM\n", addr));
+ return;
+ }
+
+ /* ok, we have a Load that will be replaced */
+ vnum = get_vnum(addr);
+ assert(vnum < env->nvals);
+
+ DB((dbg, SET_LEVEL_3, "replacing by value %u\n", vnum));
+
+ block = get_nodes_block(node);
+ set_cur_block(block);
+
+ /* check, if we can replace this Load */
+ val = get_value(vnum, env->modes[vnum]);
+
+ /* Beware: A Load can contain a hidden conversion in Firm.
+ This happens for instance in the following code:
+
+ int i;
+ unsigned j = *(unsigned *)&i;
+
+ Handle this here. */
+ mode = get_Load_mode(node);
+ if (mode != get_irn_mode(val))
+ val = new_rd_Conv(get_irn_dbg_info(node), block, val, mode);
+
+ mem = get_Load_mem(node);
+ turn_into_tuple(node, pn_Load_max+1);
+ set_Tuple_pred(node, pn_Load_M, mem);
+ set_Tuple_pred(node, pn_Load_res, val);
+ set_Tuple_pred(node, pn_Load_X_regular, new_r_Jmp(block));
+ set_Tuple_pred(node, pn_Load_X_except, new_r_Bad(irg, mode_X));
+ } else if (is_Store(node)) {
+ DB((dbg, SET_LEVEL_3, " checking %+F for replacement ", node));
+
+ /* a Store always can be replaced */
+ addr = get_Store_ptr(node);
+
+ if (! is_Sel(addr)) {
+ DB((dbg, SET_LEVEL_3, "no Sel input (%+F)\n", addr));
+ return;
+ }
+
+ if (! pset_find_ptr(env->sels, addr)) {
+ DB((dbg, SET_LEVEL_3, "Sel %+F has no VNUM\n", addr));
+ return;
+ }
+
+ vnum = get_vnum(addr);
+ assert(vnum < env->nvals);
+
+ DB((dbg, SET_LEVEL_3, "replacing by value %u\n", vnum));
+
+ block = get_nodes_block(node);
+ set_cur_block(block);
+
+ /* Beware: A Store can contain a hidden conversion in Firm. */
+ val = get_Store_value(node);
+ if (get_irn_mode(val) != env->modes[vnum])
+ val = new_rd_Conv(get_irn_dbg_info(node), block, val, env->modes[vnum]);
+
+ set_value(vnum, val);
+
+ mem = get_Store_mem(node);
+ turn_into_tuple(node, pn_Store_max+1);
+ set_Tuple_pred(node, pn_Store_M, mem);
+ set_Tuple_pred(node, pn_Store_X_regular, new_r_Jmp(block));
+ set_Tuple_pred(node, pn_Store_X_except, new_r_Bad(irg, mode_X));