+static void topologic_walker(ir_node *node, void *ctx) {
+ env_t *env = ctx;
+ 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_d_Conv(get_irn_dbg_info(node), 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_Jmp());
+ set_Tuple_pred(node, pn_Load_X_except, new_Bad());
+ } 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));
+
+ /* 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_d_Conv(get_irn_dbg_info(node), val, env->modes[vnum]);
+
+ block = get_nodes_block(node);
+ set_cur_block(block);
+ 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_Jmp());
+ set_Tuple_pred(node, pn_Store_X_except, new_Bad());
+ }