- repairs_t key, *value;
- ir_node *load_ptr, *load_mem, *nods_block;
- unsigned i;
-
- nods_block = get_nodes_block(load);
- load_ptr = get_Load_ptr(load);
- load_mem = get_Load_mem(load);
- // DDMN(load);
- /* The pointer predecessor of Load muss be a Sel node. */
- if (get_irn_op(load_ptr) == op_Sel) {
- /* If the link field of sel's entity is set to "ADDRESS_TAKEN", that means this value
- can't be scalar replaced. It is nothing to do and load_handling() must be exited. */
- if (get_entity_link(get_Sel_entity(load_ptr)) == ADDRESS_TAKEN)
- return;
-
- key.irn = nods_block;
- value = set_find(repairs, &key, sizeof(key), HASH_PTR(nods_block));
-
- /* Load's pointer predecessor's link field contains the position in the block's link, where
- must be searched the predecessor of this Load. */
- i = (unsigned)get_irn_link(load_ptr);
-
- /* If the link of Load's block doesn't contains at position "i" a node or isn't calculated,
- than pred_search() must be called .*/
- if (value == NULL) {
- block_link(load, env, repairs);
- key.irn = nods_block;
- value = set_find(repairs, &key, sizeof(key), HASH_PTR(nods_block));
- pred_search(load, value, repairs, i, 0);
- } else if (value->link[i] == NULL)
- pred_search(load, value, repairs, i, 0);
-
- /* If after the pred_search() call the link of Load's block at position "i" is equal to NULL,
- that means the loaded value wasn't initialized and the load predecessor is set to Unknown */
- if (value->link[i] == NULL)
- value->link[i] = new_Unknown(env->modes[i]);
-
- /* The Load node can be turned into a tuple now. This tuple will be optimized later. */
- turn_into_tuple(load, pn_Load_max);
- set_Tuple_pred(load, pn_Load_M, load_mem);
- set_Tuple_pred(load, pn_Load_res, value->link[i]);
- set_Tuple_pred(load, pn_Load_X_except, new_Bad());
- }
+ env_t *env = (env_t*)ctx;
+ ir_graph *irg = get_irn_irg(node);
+ ir_node *adr, *block, *mem, *val;
+ ir_mode *mode;
+ unsigned vnum;
+
+ if (is_Load(node)) {
+ /* a load, check if we can resolve it */
+ adr = get_Load_ptr(node);
+
+ DB((dbg, SET_LEVEL_3, " checking %+F for replacement ", node));
+ if (! is_Sel(adr)) {
+ DB((dbg, SET_LEVEL_3, "no Sel input (%+F)\n", adr));
+ return;
+ }
+
+ if (! pset_find_ptr(env->sels, adr)) {
+ DB((dbg, SET_LEVEL_3, "Sel %+F has no VNUM\n", adr));
+ return;
+ }
+
+ /* ok, we have a Load that will be replaced */
+ vnum = GET_VNUM(adr);
+ assert(vnum < (unsigned)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);
+ 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 */
+ adr = get_Store_ptr(node);
+
+ if (! is_Sel(adr)) {
+ DB((dbg, SET_LEVEL_3, "no Sel input (%+F)\n", adr));
+ return;
+ }
+
+ if (! pset_find_ptr(env->sels, adr)) {
+ DB((dbg, SET_LEVEL_3, "Sel %+F has no VNUM\n", adr));
+ return;
+ }
+
+ vnum = GET_VNUM(adr);
+ assert(vnum < (unsigned)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);
+ 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));
+ }