- ir_node *curr_bl;
- ir_node *start_irn;
- firm_dbg_module_t *dbg = DBG_MODULE;
- firm_dbg_set_mask(dbg, -1);
-
- curr_bl = get_nodes_block(usage);
-
-
- DBG((dbg, LEVEL_1, "Searching valid def for use %+F at pos %d\n", usage, pos));
- /*
- * If the usage is in a phi node, search the copy in the
- * predecessor denoted by pos.
- */
- if(is_Phi(usage)) {
- curr_bl = get_Block_cfgpred_block(curr_bl, pos);
- start_irn = sched_last(curr_bl);
- } else {
- start_irn = sched_prev(usage);
- }
-
- /*
- * Traverse the dominance tree upwards from the
- * predecessor block of the usage.
- */
- while(curr_bl != NULL) {
-
- /*
- * If this block contains a copy, search the block
- * instruction by instruction.
- */
- if(pset_find_ptr(copy_blocks, curr_bl)) {
- ir_node *irn;
-
- /* Look at each instruction from last to first. */
- for(irn = start_irn; !is_Block(irn); irn = sched_prev(irn)) {
-
- /* Take the first copy we find. */
-
- DBG((dbg, LEVEL_1, "Is %F a copy?\n", irn));
- if(pset_find_ptr(copies, irn))
- return irn;
- }
- }
-
- /* If were not done yet, look in the immediate dominator */
- curr_bl = get_Block_idom(curr_bl);
- if(curr_bl)
- start_irn = sched_last(curr_bl);
- }
-
- assert(0 && "Did not find a valid def");
- return NULL;
-}
-
-static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks)
-{
- int i = 0;
- int n_outs = 0;
- const ir_edge_t *edge;
- firm_dbg_module_t *dbg = DBG_MODULE;
-
- struct {
- ir_node *irn;
- int pos;
- } *outs;
-
- /* Count the number of outs. */
- foreach_out_edge(orig, edge)
- n_outs++;
-
- /*
- * Put all outs into an array.
- * This is neccessary, since the outs would be modified while
- * interating on them what could bring the outs module in trouble.
- */
- DBG((dbg, LEVEL_2, " Users of %+F\n", orig));
- outs = malloc(n_outs * sizeof(outs[0]));
- foreach_out_edge(orig, edge) {
- outs[i].irn = get_edge_src_irn(edge);
- outs[i].pos = get_edge_src_pos(edge);
- i += 1;
- }
-
- /*
- * Search the valid def for each out and set it.
- */
- for(i = 0; i < n_outs; ++i) {
- ir_node *def;
- ir_node *irn = outs[i].irn;
- int pos = outs[i].pos;
-
- DBG((dbg, LEVEL_2, " %+F(%d) -> ???\n", irn, pos));
- def = search_def(irn, pos, copies, copy_blocks);
- DBG((dbg, LEVEL_2, " %+F(%d) -> %+F\n", irn, pos, def));
-
- if(def != NULL)
- set_irn_n(irn, pos, def);
- }
-
- free(outs);
-}
-
-struct phi_collect_info {
- const ir_node *orig;
- pset *copies;
- pset *copy_blocks;
-};
-
-static void add_all_phis_walker(ir_node *irn, void *data)
-{
- if(is_Phi(irn)) {
- int i, o, n;
- struct phi_collect_info *info = data;
-
- /*
- * Look at all operands of the phi. If one of them is the original
- * node, insert the phi into the copies and copy_blocks set.
- */
- for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
- if(get_irn_n(irn, i) == info->orig) {
- pset_insert_ptr(info->copies, irn);
- pset_insert_ptr(info->copy_blocks, get_nodes_block(irn));
-
- /* FIXED_DANIEL
- * If a phi is a copy insert all its args as copies too.
- * Else setting the phi-args will fail in serach_def */
- for(o=0; o<n; ++o) {
- const ir_node *arg = get_irn_n(irn, o);
- pset_insert_ptr(info->copies, arg);
- pset_insert_ptr(info->copy_blocks, get_nodes_block(arg));
- }
-
- break;
- }
- }
-
-
- }
-}
-
-/**
- * Add all phis using a node to a set.
- * @param orig The node the phis shall use.
- * @param copies The set where the phis shall be put into.
- * @param copy_blocks The set the blocks of the phis shall be put into.
- */
-static void add_all_phis_using(const ir_node *orig, pset *copies, pset *copy_blocks)
-{
- struct phi_collect_info info;
-
- info.copies = copies;
- info.copy_blocks = copy_blocks;
- info.orig = orig;
- irg_walk_graph(get_irn_irg(orig), add_all_phis_walker, NULL, &info);