Removed phase which elimiated phi interferences.
authorDaniel Grund <grund@cs.uni-saarland.de>
Thu, 28 Jul 2005 15:21:39 +0000 (15:21 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Thu, 28 Jul 2005 15:21:39 +0000 (15:21 +0000)
Adapted copyopt, heur, ilp and ssa-destruction to this new-old :-( situation.
free-bugfix in bechordal
comments and debug stuff

ir/be/bechordal.c
ir/be/becopyheur.c
ir/be/becopyilp.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/bedupl.c [deleted file]
ir/be/bedupl.h [deleted file]
ir/be/beirgmod.c
ir/be/bemain.c
ir/be/bessadestr.c

index 2fcb990..f7c7d4c 100644 (file)
@@ -38,7 +38,7 @@
 #include "bechordal_t.h"
 #include "bechordal_draw.h"
 
-#define DBG_LEVEL 0
+#define DBG_LEVEL 0 //SET_LEVEL_4
 #define NO_COLOR (-1)
 
 #undef DUMP_INTERVALS
@@ -484,7 +484,7 @@ static void assign(ir_node *block, void *env_ptr)
        }
 
        /* Free the auxillary data on the obstack. */
-       obstack_free(obst, obstack_level);
+       //obstack_free(obst, obstack_level);
 
   del_pset(live_in);
 }
index f215625..97969cc 100644 (file)
@@ -524,7 +524,7 @@ static void ou_optimize(unit_t *ou) {
        /* apply the best found qnode */
        if (curr->mis_size >= 2) {
                node_stat_t *ns;
-               DBG((dbg, LEVEL_1, "\t  Best color: %d  Costs: %d/%d\n", curr->color, ou->complete_costs - curr->mis_costs, ou->complete_costs));
+               DBG((dbg, LEVEL_1, "\t  Best color: %d  Costs: %d << %d << %d\n", curr->color, ou->min_nodes_costs, ou->all_nodes_costs - curr->mis_costs, ou->all_nodes_costs));
                /* globally pin root and all args which have the same color */
                pset_insert_ptr(pinned_global, ou->nodes[0]);
                for (i=1; i<ou->node_count; ++i) {
index ef2a603..2e34e2f 100644 (file)
@@ -347,13 +347,13 @@ static void pi_add_constr_S(problem_instance_t *pi) {
                int cst_idx, y_idx, i;
                char buf[32];
 
-               if (curr->minimal_costs == 0)
+               if (curr->min_nodes_costs == 0)
                        continue;
 
                root = curr->nodes[0];
                rootnr = get_irn_graph_nr(root);
                mangle_cst(buf, 'S', cst_counter++);
-               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, curr->minimal_costs);
+               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, curr->min_nodes_costs);
 
                /* for all arguments */
                for (i = 1; i < curr->node_count; ++i) {
@@ -381,6 +381,10 @@ static INLINE int get_costs(problem_instance_t *pi, ir_node *phi, ir_node *irn)
        return 0;
 }
 
+/*
+ * TODO: Because this here uses a phi-walker and not the ou's,
+ * it is possible, that the interfering args of a phi will cause a bug ??!!
+ */
 static void M_constr_walker(ir_node *block, void *env) {
        problem_instance_t *pi = env;
        int count, arity, row, col, other_row, *costs;
index 8ed83f9..9369e21 100644 (file)
@@ -88,7 +88,7 @@ static int ou_max_ind_set_costs(unit_t *ou) {
  * to remember all roots.
  */
 static void co_append_unit(copy_opt_t *co, ir_node *root) {
-       int i, arity;
+       int i, arity, inevitable_costs = 0;
        unit_t *unit;
        struct list_head *tmp;
 
@@ -104,41 +104,44 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) {
        arity = get_irn_arity(root);
        unit = xcalloc(1, sizeof(*unit));
        unit->co = co;
-       unit->node_count = 1;
        unit->nodes = xmalloc((arity+1) * sizeof(*unit->nodes));
        unit->costs = xmalloc((arity+1) * sizeof(*unit->costs));
+       unit->node_count = 1;
        unit->nodes[0] = root;
-       unit->complete_costs = 0;
-       unit->sort_key = 0;
        INIT_LIST_HEAD(&unit->queue);
 
        /* check all args */
        if (is_Phi(root)) {
                for (i=0; i<arity; ++i) {
+                       int o, arg_pos = 0;
                        ir_node *arg = get_irn_n(root, i);
+
                        assert(is_curr_reg_class(arg) && "Argument not in same register class.");
-                       if (arg != root) {
-                               int o, arg_pos = 0;
-                               if (nodes_interfere(co->chordal_env, root, arg))
-                                       assert(0 && "root and arg interfere");
-                               DBG((dbg, LEVEL_1, "\t   Member: %n %N\n", arg, arg));
-
-                               /* check if arg has occurred at a prior position in the arg/list */
-                               for (o=0; o<unit->node_count; ++o)
-                                       if (unit->nodes[o] == arg) {
-                                               arg_pos = o;
-                                               break;
-                                       }
-
-                               if (!arg_pos) { /* a new argument */
-                                       /* insert node, set costs */
-                                       unit->nodes[unit->node_count] = arg;
-                                       unit->costs[unit->node_count] = co->get_costs(root, arg, i);
-                                       unit->node_count++;
-                               } else { /* arg has occured before in same phi */
-                                       /* increase costs for existing arg */
-                                       unit->costs[arg_pos] = co->get_costs(root, arg, i);
+                       if (arg == root)
+                               continue;
+                       if (nodes_interfere(co->chordal_env, root, arg)) {
+                               inevitable_costs += co->get_costs(root, arg, i);
+                               continue;
+                       }
+
+                       /* Else insert the argument of the phi to the members of this ou */
+                       DBG((dbg, LEVEL_1, "\t   Member: %n %N\n", arg, arg));
+
+                       /* Check if arg has occurred at a prior position in the arg/list */
+                       for (o=0; o<unit->node_count; ++o)
+                               if (unit->nodes[o] == arg) {
+                                       arg_pos = o;
+                                       break;
                                }
+
+                       if (!arg_pos) { /* a new argument */
+                               /* insert node, set costs */
+                               unit->nodes[unit->node_count] = arg;
+                               unit->costs[unit->node_count] = co->get_costs(root, arg, i);
+                               unit->node_count++;
+                       } else { /* arg has occured before in same phi */
+                               /* increase costs for existing arg */
+                               unit->costs[arg_pos] += co->get_costs(root, arg, i);
                        }
                }
                unit->nodes = xrealloc(unit->nodes, unit->node_count * sizeof(*unit->nodes));
@@ -155,19 +158,24 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) {
        /* TODO add ou's for 2-addr-code instructions */
 
 
+       /* Init costs with inevitable_costs */
+       unit->all_nodes_costs = inevitable_costs;
+       unit->min_nodes_costs = inevitable_costs;
+
+       /* Determine the maximum costs this unit can cause: all_nodes_cost */
        for(i=1; i<unit->node_count; ++i) {
                unit->sort_key = MAX(unit->sort_key, unit->costs[i]);
-               unit->complete_costs += unit->costs[i];
+               unit->all_nodes_costs += unit->costs[i];
        }
 
-       /* insert according to average costs */
+       /* Determine the minimal costs this unit will cause: min_nodes_costs */
+       unit->min_nodes_costs += unit->all_nodes_costs - ou_max_ind_set_costs(unit);
+
+       /* Insert the new ou according to its sort_key */
        tmp = &co->units;
        while (tmp->next != &co->units && list_entry_units(tmp->next)->sort_key > unit->sort_key)
                tmp = tmp->next;
        list_add(&unit->units, tmp);
-
-       /* Init ifg_mis_size to node_count. So get_lower_bound returns correct results. */
-       unit->minimal_costs = unit->complete_costs - ou_max_ind_set_costs(unit);
 }
 
 static void co_collect_in_block(ir_node *block, void *env) {
@@ -277,6 +285,6 @@ int co_get_lower_bound(const copy_opt_t *co) {
        int res = 0;
        unit_t *curr;
        list_for_each_entry(unit_t, curr, &co->units, units)
-               res += curr->minimal_costs;
+               res += curr->min_nodes_costs;
        return res;
 }
index 3555169..8e76547 100644 (file)
@@ -60,13 +60,12 @@ typedef struct _unit_t {
        int node_count;                         /**< size of the nodes array */
        ir_node **nodes;                        /**< [0] is the root-node, others are non interfering args of it. */
        int *costs;                                     /**< costs[i] are arising, if nodes[i] has a different color */
-       int complete_costs;                     /**< sum of all costs[i] */
-       int minimal_costs;                      /**< a lower bound for this ou, considering only ifg (not coloring conflicts) */
-
-       int sort_key;                           /**< maximum costs. controls the order of ou's. */
+       int all_nodes_costs;            /**< sum of all costs[i] */
+       int min_nodes_costs;            /**< a lower bound for this ou, considering only ifg (not coloring conflicts) */
+       int sort_key;                           /**< maximum costs. controls the order of ou's in the struct list_head units. */
 
        /* for heuristic */
-       struct list_head queue;         /**< list of (mis/color) sorted by size of mis */
+       struct list_head queue;         /**< list of qn's sorted by weight of qn-mis */
 } unit_t;
 
 /* Helpers */
diff --git a/ir/be/bedupl.c b/ir/be/bedupl.c
deleted file mode 100644 (file)
index 3983e94..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file   bedupl.c
- * @date   15.07.2005
- * @author Sebastian Hack
- *
- * Insert duplicates for phi operands which interfere with the phi.
- *
- * Copyright (C) 2005 Universitaet Karlsruhe
- * Released under the GPL
- */
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irgwalk.h"
-
-#include "be_t.h"
-#include "bearch.h"
-#include "bera.h"
-#include "benode_t.h"
-#include "besched_t.h"
-
-static void eliminate_phi_int_walker(ir_node *irn, void *data)
-{
-  const be_main_session_env_t *env = data;
-  const arch_register_class_t *cls =
-    arch_get_irn_reg_class(env->main_env->arch_env, irn, arch_pos_make_out(0));
-
-  if(is_Phi(irn) && cls != NULL) {
-    int i, n;
-    ir_node *phi_bl = get_nodes_block(irn);
-
-    for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
-      ir_node *operand   = get_irn_n(irn, i);
-      ir_node *bl        = get_Block_cfgpred_block(phi_bl, i);
-
-      if(is_live_in(phi_bl, irn)) { // values_interfere(irn, operand)) {
-        ir_node *copy = new_Copy(env->main_env->node_factory, cls, env->irg, bl, operand);
-        set_irn_n(irn, i, copy);
-        sched_add_after(sched_last(bl), copy);
-      }
-    }
-  }
-}
-
-void be_eliminate_phi_interferences(const be_main_session_env_t *env)
-{
-  irg_walk_graph(env->irg, eliminate_phi_int_walker, NULL, (void *) env);
-}
diff --git a/ir/be/bedupl.h b/ir/be/bedupl.h
deleted file mode 100644 (file)
index cb20b15..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @file   bedupl.h
- * @date   19.07.2005
- * @author Sebastian Hack
- *
- * Handling of duplicates
- *
- * Copyright (C) 2005 Universitaet Karlsruhe
- * Released under the GPL
- */
-
-#ifndef _BEDUPL_H
-#define _BEDUPL_H
-
-void be_eliminate_phi_interferences(const be_main_session_env_t *env);
-
-#endif /* _BEDUPL_H */
index 73050d3..cd54bde 100644 (file)
@@ -28,7 +28,7 @@
 #include "beirgmod.h"
 
 #define DBG_MODULE firm_dbg_register("firm.be.irgmod")
-#define DBG_LEVEL 0
+#define DBG_LEVEL 0 //SET_LEVEL_4
 
 struct _dom_front_info_t {
   pmap *df_map;
index c42486e..abbff7d 100644 (file)
@@ -150,10 +150,6 @@ static void be_main_loop(void)
                /* Build liveness information */
                be_liveness(irg);
 
-               /* Remove all cases where a phi and one of its arguments interfere */
-               be_eliminate_phi_interferences(&session);
-               dump_ir_block_graph(session.irg, "-prephase");
-
                /* Liveness analysis */
                be_liveness(irg);
 
index 64e561d..a478e38 100644 (file)
 #include "benode_t.h"
 #include "besched_t.h"
 
+static firm_dbg_module_t *dbg = NULL;
+#define DEBUG_LVL SET_LEVEL_2
+
+
 #define get_reg(irn) arch_get_irn_register(chordal_env->arch_env, irn, 0)
 #define set_reg(irn, reg) arch_set_irn_register(chordal_env->arch_env, irn, 0, reg)
 
@@ -47,32 +51,38 @@ static int set_cmp_b2p(const void *x, const void *y, size_t size) {
 #define is_curr_reg_class(irn)  (get_reg_cls(p) == chordal_env->cls)
 
 static ir_node *get_or_insert_perm(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *block) {
-  block2perm_t find, *found;
-  ir_node *p;
-  set *b2p = chordal_env->data;
-  const arch_env_t *arch_env = chordal_env->arch_env;
-
-  /* iff needed insert perm node */
-
-  /* .if the perm is in the pset return it */
-  find.block = block;
-  find.perm = NULL;
-  found = set_insert(b2p, &find, sizeof(find), HASH_PTR(find.block));
-  if (found->perm)
-    return found->perm;
-
-  /* .else look for a perm of right register class in the schedule */
-  p = sched_last(find.block);
-  while (!is_Block(p) && (is_Branch(p) || (is_Perm(p) && !is_curr_reg_class(p))))
-    p = sched_prev(p);
-
-  /* if we haven't found a perm of the right register class create a new one */
-  if (! (is_Perm(p) && is_curr_reg_class(p)))
+       block2perm_t find, *found;
+       ir_node *p;
+       set *b2p = chordal_env->data;
+       const arch_env_t *arch_env = chordal_env->arch_env;
+
+
+       /* iff needed insert perm node */
+       DBG((dbg, LEVEL_1, "    Getting perm in %+F\n", block));
+
+       /* .if the perm is in the pset return it */
+       find.block = block;
+       find.perm = NULL;
+       found = set_insert(b2p, &find, sizeof(find), HASH_PTR(find.block));
+       if (found->perm) {
+               DBG((dbg, LEVEL_1, "      found it %+F in map\n", found->perm));
+               return found->perm;
+       }
+
+       /* .else look for a perm of right register class in the schedule */
+       p = sched_last(find.block);
+       while (!is_Block(p) && (is_Branch(p) || (is_Perm(p) && !is_curr_reg_class(p))))
+               p = sched_prev(p);
+
+       /* if we haven't found a perm of the right register class create a new one */
+       if (! (is_Perm(p) && is_curr_reg_class(p))) {
+               DBG((dbg, LEVEL_1, "      insert it after %+F\n", p));
                p = insert_Perm_after(session, chordal_env->cls, p);
+       }
 
-  /* insert perm into pset */
-  found->perm = p;
-  return p;
+       /* insert perm into pset and return it*/
+       found->perm = p;
+       return p;
 }
 
 #define is_pinned(irn) (get_irn_link(irn))
@@ -84,18 +94,20 @@ static ir_node *get_or_insert_perm(be_main_session_env_t *session, be_chordal_en
  * by inserting perm nodes, if necessary.
  * @param phi The phi node to adjust operands for
  */
-static void adjust_arguments(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *phi) {
+static void adjust_phi_arguments(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *phi) {
        int i, max;
        ir_node *arg, *phi_block, *arg_block;
        const arch_register_t *phi_reg, *arg_reg;
        const arch_register_class_t *cls;
 
        assert(is_Phi(phi) && "Can only handle phi-destruction :)");
+       DBG((dbg, LEVEL_1, "  for %+F\n", phi));
 
        cls = arch_get_irn_reg_class(session->main_env->arch_env, phi, arch_pos_make_out(0));
        phi_block = get_nodes_block(phi);
        phi_reg = get_reg(phi);
-       /* all arguments of the phi */
+
+       /* process all arguments of the phi */
        for(i=0, max=get_irn_arity(phi); i<max; ++i) {
                ir_node *perm;
 
@@ -104,28 +116,38 @@ static void adjust_arguments(be_main_session_env_t *session, be_chordal_env_t *c
                arg_reg = get_reg(arg);
                perm = get_Proj_pred(arg);
 
+               DBG((dbg, LEVEL_1, "    arg %+F has perm %+F\n", arg, perm));
                /* if registers don't match ...*/
                if (phi_reg != arg_reg) {
+                       DBG((dbg, LEVEL_1, "      regs don't match %d %d\n", phi_reg, arg_reg));
 
                        /* First check if there is another phi in the same block
-                        * having arg at the same pos in its arg-list */
+                        * having arg at the same pos in its arg-list and the same color as arg */
                        if (!is_pinned(arg)) {
+                               DBG((dbg, LEVEL_1, "      arg is not pinned\n"));
                                ir_node *other_phi = phi;
                                while ((other_phi = get_irn_link(other_phi)) != phi) {
-                                       assert(is_Phi(other_phi) && "link fields are screwed up");
-                                       if (get_irn_n(other_phi, i) == arg && get_reg(other_phi) == arg_reg)
+                                       assert(is_Phi(other_phi) && get_nodes_block(phi) == get_nodes_block(other_phi) && "link fields are screwed up");
+                                       if (get_irn_n(other_phi, i) == arg && get_reg(other_phi) == arg_reg) {
+                                               DBG((dbg, LEVEL_1, "      other phi pinned the argument\n"));
                                                pin_irn(arg, phi_block);
+                                       }
                                }
                        }
 
-                       if (is_pinned(arg)) {
+                       /* If arg is pinned, another phi set the color of arg and pinned it.
+                        * So this phi can't change the color again and a duplicate must be inserted.
+                        *
+                        * If arg interferes with phi, one can never set the same color for both
+                        * Hence, a duplicate must be inserted */
+                       if (is_pinned(arg) || nodes_interfere(chordal_env, phi, arg)) {
                                ir_node *dupl, *tmp;
-                               /* Arg is pinned. So another phi has locked it.
-                                * Hence, a duplicate must be inserted */
                                assert(get_pinning_block(arg) == phi_block && "If arg is pinned it must be due to a phi in the same block");
+
                                dupl = new_Copy(session->main_env->node_factory, cls, session->irg, arg_block, arg);
                                set_irn_n(phi, i, dupl);
                                set_reg(dupl, phi_reg);
+                               DBG((dbg, LEVEL_1, "      inserting dupl %+F\n", dupl));
 
                                /* Add dupl to schedule */
                                tmp = sched_next(perm);
@@ -149,24 +171,26 @@ static void adjust_arguments(be_main_session_env_t *session, be_chordal_env_t *c
                                 * livein(PhiBl) = liveout(ArgBl), if all phis are processed then
                                 * every color is used exactly once.
                                 */
-                                set_reg(arg, phi_reg);
+                               DBG((dbg, LEVEL_1, "      just set color\n"));
+                               set_reg(arg, phi_reg);
                        }
                }
-               /* Now the color of the arg and the phi-result are equal.
-                * Pin it, so everyone knows
+
+               /* Now the color of the arg (arg may be a dupl now) and the phi-result are equal.
+                * Pin it, so everyone knows and it never gets changed again.
                 * An arg never is a phi, because perms were inserted. So the link field is free */
+               DBG((dbg, LEVEL_1, "      arg has correct color (now), so pin it\n"));
                pin_irn(arg, phi_block);
        }
 }
 
-void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
+
+static void insert_all_perms(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
        pmap_entry *pme;
-       set *b2p;
        int i, max;
        ir_node *first_phi, *recent_phi;
 
-       b2p = new_set(set_cmp_b2p, 32);
-       chordal_env->data = b2p;
+       DBG((dbg, LEVEL_1, "Placing perms...\n"));
 
        /* place perms in cf-preds of phis */
        pmap_foreach(chordal_env->border_heads, pme) {
@@ -177,10 +201,8 @@ void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chorda
                /* iterate over the first ops in the block until a non-phi is reached */
                list_for_each_entry(border_t, curr, head, list) {
                        ir_node *phi = curr->irn;
-                       if (curr->is_def && curr->is_real) {
-                               if (!is_Phi(phi))
-                                       break;
 
+                       if (curr->is_def && curr->is_real && is_Phi(phi)) {
                                set_irn_link(phi, NULL);
                                /* chain of phis in a block */
                                if (first_phi == NULL)
@@ -190,11 +212,12 @@ void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chorda
                                recent_phi = phi;
 
                                /* insert perms */
+                               DBG((dbg, LEVEL_1, "  for %+F\n", phi));
                                for(i=0, max=get_irn_arity(phi); i<max; ++i) {
                                        ir_node *perm;
 
-                                       ir_printf("Placing perm for %+F \n", phi);
                                        perm = get_or_insert_perm(session, chordal_env, get_Block_cfgpred_block(get_nodes_block(phi), i));
+                                       DBG((dbg, LEVEL_1, "    %+F in block %N\n", perm, get_Block_cfgpred_block(get_nodes_block(phi), i)));
                                        set_irn_link(perm, NULL);
                                }
                        }
@@ -202,8 +225,12 @@ void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chorda
                if (first_phi)
                        set_irn_link(recent_phi, first_phi);
        }
+}
 
-       dump_ir_block_graph(session->irg, "-ssa_destr_perms_placed");
+static void    set_regs_or_place_dupls(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
+       pmap_entry *pme;
+
+       DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n"));
 
        /* iterate over all blocks and correct color of arguments*/
        pmap_foreach(chordal_env->border_heads, pme) {
@@ -212,14 +239,27 @@ void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chorda
 
                /* iterate over the first ops in the block until a non-phi is reached */
                list_for_each_entry(border_t, curr, head, list)
-                       if (curr->is_def && curr->is_real) {
-                               if (!is_Phi(curr->irn))
-                                       break;
-                               adjust_arguments(session, chordal_env, curr->irn);
-                       }
+                       if (curr->is_def && curr->is_real && is_Phi(curr->irn))
+                               adjust_phi_arguments(session, chordal_env, curr->irn);
        }
+}
+
+void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
+       set *b2p;
+
+       dbg = firm_dbg_register("ir.be.ssadestr");
+       firm_dbg_set_mask(dbg, DEBUG_LVL);
+
+       /* create a map for fast lookup of perms: block --> perm */
+       b2p = new_set(set_cmp_b2p, 32);
+       chordal_env->data = b2p;
+
+       insert_all_perms(session, chordal_env);
+       dump_ir_block_graph(session->irg, "-ssa_destr_perms_placed");
+
+       set_regs_or_place_dupls(session, chordal_env);
+       dump_ir_block_graph(session->irg, "-ssa_destr_regs_set");
 
-       dump_ir_block_graph(session->irg, "-ssa_destr_colors_set");
        del_set(b2p);
 }
 
@@ -234,24 +274,22 @@ void be_ssa_destruction_check(be_main_session_env_t *session, be_chordal_env_t *
 
                /* iterate over the first ops in the block */
                list_for_each_entry(border_t, curr, head, list)
-               if (curr->is_def && curr->is_real && is_Phi(curr->irn)) {
-                       const arch_register_t *phi_reg, *arg_reg;
-                       ir_node *phi = curr->irn;
-                       if (!is_Phi(phi))
-                               break;
-
-                       phi_reg = get_reg(phi);
-                       /* iterate over all args of phi */
-                       for(i=0, max=get_irn_arity(phi); i<max; ++i) {
-                               ir_node *arg = get_irn_n(phi, i);
-                               arg_reg = get_reg(arg);
-                               if(phi_reg != arg_reg) {
-                                       ir_printf("Registers of %+F and %+F differ: %s %s\n", phi, arg, phi_reg->name, arg_reg->name);
-                                       assert(0 && "Registers of phi and arg differ\n");
+                       if (curr->is_def && curr->is_real && is_Phi(curr->irn)) {
+                               const arch_register_t *phi_reg, *arg_reg;
+                               ir_node *phi = curr->irn;
+
+                               phi_reg = get_reg(phi);
+                               /* iterate over all args of phi */
+                               for(i=0, max=get_irn_arity(phi); i<max; ++i) {
+                                       ir_node *arg = get_irn_n(phi, i);
+                                       arg_reg = get_reg(arg);
+                                       if(phi_reg != arg_reg) {
+                                               ir_printf("Registers of %+F and %+F differ: %s %s\n", phi, arg, phi_reg->name, arg_reg->name);
+                                               assert(0 && "Registers of phi and arg differ\n");
+                                       }
+                                       if(!is_pinned(arg))
+                                               ir_printf("Warning: Arg %+F not pinned\n", arg);
                                }
-                               if(!is_pinned(arg))
-                                       ir_printf("Warning: Arg not pinned %n %N\n", arg, arg);
                        }
-               }
        }
 }