fehler109
[libfirm] / ir / be / belower.c
index 42c887e..ea01678 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -45,7 +45,6 @@
 #include "besched_t.h"
 #include "bestat.h"
 #include "bessaconstr.h"
-#include "benodesets.h"
 #include "beintlive_t.h"
 
 #undef KEEP_ALIVE_COPYKEEP_HACK
@@ -178,14 +177,14 @@ static int get_pairidx_for_regidx(reg_pair_t *pairs, int n, int reg_idx, int in_
        if (in_out) {
                for (i = 0; i < n; i++) {
                        /* out register matches */
-                       if (pairs[i].out_reg->index == reg_idx)
+                       if ((int) pairs[i].out_reg->index == reg_idx)
                                return i;
                }
        }
        else {
                for (i = 0; i < n; i++) {
                        /* in register matches */
-                       if (pairs[i].in_reg->index == reg_idx)
+                       if ((int) pairs[i].in_reg->index == reg_idx)
                                return i;
                }
        }
@@ -599,8 +598,8 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
        sched_add_after(irn, keep);
 
        /* insert the other different and it's copies into the set */
-       key.op         = other_different;
-       entry          = pset_find(op_set, &key, nodeset_hash(other_different));
+       key.op = other_different;
+       entry  = pset_find(op_set, &key, hash_irn(other_different));
 
        if (! entry) {
                entry         = obstack_alloc(&env->obst, sizeof(*entry));
@@ -617,7 +616,7 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
                ir_nodeset_insert(&entry->copies, keep);
        }
 
-       pset_insert(op_set, entry, nodeset_hash(other_different));
+       pset_insert(op_set, entry, hash_irn(other_different));
 }
 
 /**
@@ -631,12 +630,14 @@ static void assure_different_constraints(ir_node *irn, constraint_env_t *env) {
        req = arch_get_register_req(arch_env, irn, -1);
 
        if (arch_register_req_is(req, should_be_different)) {
-               ir_node *different_from = get_irn_n(belower_skip_proj(irn), req->other_different);
-               gen_assure_different_pattern(irn, different_from, env);
-       } else if (arch_register_req_is(req, should_be_different_from_all)) {
-               int i, n = get_irn_arity(belower_skip_proj(irn));
-               for (i = 0; i < n; i++) {
-                       gen_assure_different_pattern(irn, get_irn_n(belower_skip_proj(irn), i), env);
+               const unsigned other = req->other_different;
+               int i;
+
+               for (i = 0; 1U << i <= other; ++i) {
+                       if (other & (1U << i)) {
+                               ir_node *different_from = get_irn_n(belower_skip_proj(irn), i);
+                               gen_assure_different_pattern(irn, different_from, env);
+                       }
                }
        }
 }
@@ -754,21 +755,18 @@ static void melt_copykeeps(constraint_env_t *cenv) {
                                new_ck = be_new_CopyKeep(entry->cls, irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, get_irn_mode(ref));
 #endif /* KEEP_ALIVE_COPYKEEP_HACK */
 
-                               /* set register class for all keeped inputs */
+                               /* set register class for all kept inputs */
                                for (j = 1; j <= n_melt; ++j)
                                        be_node_set_reg_class(new_ck, j, entry->cls);
 
                                ir_nodeset_insert(&entry->copies, new_ck);
 
                                /* find scheduling point */
-                               if (get_irn_mode(ref_mode_T) == mode_T) {
-                                       /* walk along the Projs */
-                                       for (sched_pt = sched_next(ref_mode_T); is_Proj(sched_pt) || be_is_Keep(sched_pt) || be_is_CopyKeep(sched_pt); sched_pt = sched_next(sched_pt))
-                                               /* just walk along the schedule until a non-Proj/Keep/CopyKeep node is found*/ ;
-                               }
-                               else {
-                                       sched_pt = ref_mode_T;
-                               }
+                               sched_pt = ref_mode_T;
+                               do {
+                                       /* just walk along the schedule until a non-Keep/CopyKeep node is found */
+                                       sched_pt = sched_next(sched_pt);
+                               } while (be_is_Keep(sched_pt) || be_is_CopyKeep(sched_pt));
 
                                sched_add_before(sched_pt, new_ck);
                                DBG((cenv->dbg, LEVEL_1, "created %+F, scheduled before %+F\n", new_ck, sched_pt));
@@ -894,8 +892,8 @@ static int push_through_perm(ir_node *perm, void *data)
 
        int i, n;
        const ir_edge_t *edge;
-       ir_node *last_proj, *irn;
-       const arch_register_class_t *cls;
+       ir_node *last_proj = NULL, *irn;
+       const arch_register_class_t *cls = NULL;
 
        DBG((mod, LEVEL_1, "perm move %+F irg %+F\n", perm, irg));
 
@@ -929,8 +927,9 @@ found_front:
        node = sched_prev(perm);
        n_moved = 0;
        while(!sched_is_begin(node)) {
-               int      input = -1;
-               ir_node *proj;
+               const arch_register_req_t *req;
+               int                        input = -1;
+               ir_node                   *proj;
 
                foreach_out_edge(perm, edge) {
                        ir_node *out = get_edge_src_irn(edge);
@@ -949,6 +948,14 @@ found_front:
                        break;
                if(arch_irn_is(aenv, node, modify_flags))
                        break;
+               if(is_Proj(node)) {
+                       req = arch_get_register_req(aenv, get_Proj_pred(node),
+                                                   -1 - get_Proj_proj(node));
+               } else {
+                       req = arch_get_register_req(aenv, node, -1);
+               }
+               if(req->type != arch_register_req_type_normal)
+                       break;
                for(i = get_irn_arity(node) - 1; i >= 0; --i) {
                        ir_node *opop = get_irn_n(node, i);
                        if (arch_irn_consider_in_reg_alloc(aenv, cls, opop)) {