- } else if (op == op_Phi && get_irn_mode(node) == mode_M) {
- /*
- * found a memory Phi: Here, we must create new Phi nodes
- */
- block = get_nodes_block(node);
- value_arr = get_irn_link(block);
-
- n = get_Block_n_cfgpreds(block);
-
- in = alloca(sizeof(*in) * n);
-
- for (i = env->nvals - 1; i >= 0; --i) {
- unk = new_Unknown(env->modes[i]);
- for (j = n - 1; j >= 0; --j)
- in[j] = unk;
-
- value_arr[i] = new_r_Phi(current_ir_graph, block, n, in, env->modes[i]);
-
- l = obstack_alloc(&env->obst, sizeof(*l));
- l->node = value_arr[i];
- l->vnum = i;
-
- set_irn_link(value_arr[i], env->fix_phis);
- env->fix_phis = l;
- }
- }
-}
-
-/**
- * Walker: allocate the value array for every block.
- */
-static void alloc_value_arr(ir_node *block, void *ctx) {
- env_t *env = ctx;
- ir_node **var_arr = obstack_alloc(&env->obst, sizeof(*var_arr) * env->nvals);
-
- /* the value array is empty at start */
- memset(var_arr, 0, sizeof(*var_arr) * env->nvals);
- set_irn_link(block, var_arr);
-}
-
-/**
- * searches through blocks beginning from block for value
- * vnum and return it.
- */
-static ir_node *find_vnum_value(ir_node *block, unsigned vnum) {
- ir_node **value_arr;
- int i;
- ir_node *res;
-
- if (Block_not_block_visited(block)) {
- mark_Block_block_visited(block);
-
- value_arr = get_irn_link(block);
-
- if (value_arr[vnum])
- return value_arr[vnum];
-
- for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
- ir_node *pred = get_Block_cfgpred(block, i);
-
- res = find_vnum_value(get_nodes_block(pred), vnum);
- if (res)
- return res;
- }
- }
- return NULL;
-}
-
-/**
- * fix the Phi list
- */
-static void fix_phis(env_t *env) {
- list_entry_t *l;
- ir_node *phi, *block, *pred, *val;
- int i;
-
- for (l = env->fix_phis; l; l = get_irn_link(phi)) {
- phi = l->node;
-
- block = get_nodes_block(phi);
- for (i = get_irn_arity(phi) - 1; i >= 0; --i) {
- pred = get_Block_cfgpred(block, i);
- pred = get_nodes_block(pred);
-
- inc_irg_block_visited(current_ir_graph);
- val = find_vnum_value(pred, l->vnum);
-
- if (val)
- set_irn_n(phi, i, val);
- }
- }
-}
-
-/**
- * fix the Load list
- */
-static void fix_loads(env_t *env) {
- list_entry_t *l;
- ir_node *load, *block, *pred, *val = NULL, *mem;
- ir_mode *mode;
- int i;
-
- for (l = env->fix_loads; l; l = get_irn_link(load)) {
- load = l->node;
-
- block = get_nodes_block(load);
- for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
- pred = get_Block_cfgpred(block, i);
- pred = get_nodes_block(pred);
-
- inc_irg_block_visited(current_ir_graph);
- val = find_vnum_value(pred, l->vnum);
-
- if (val)
- break;
- }
-
- if (! val) {
- /* access of an uninitialized value */
- val = new_Unknown(env->modes[l->vnum]);
- }
-
- /* Beware: A Load can contain a hidden conversion in Firm.
- Handle this here. */
- mode = get_Load_mode(load);
- if (mode != get_irn_mode(val))
- val = new_d_Conv(get_irn_dbg_info(load), val, mode);
-
- mem = get_Load_mem(load);
-
- turn_into_tuple(load, pn_Load_max);
- set_Tuple_pred(load, pn_Load_M, mem);
- set_Tuple_pred(load, pn_Load_res, val);
- set_Tuple_pred(load, pn_Load_X_regular, new_r_Jmp(current_ir_graph, block));
- set_Tuple_pred(load, pn_Load_X_except, new_Bad());