tv: Remove mul_table[][][] and simply use * and <<.
[libfirm] / ir / be / beflags.c
index 6ea8dd1..3ffae62 100644 (file)
@@ -21,7 +21,6 @@
  * @file
  * @brief       modifies schedule so flags dependencies are respected.
  * @author      Matthias Braun, Christoph Mallon
- * @version     $Id: besched.h 14693 2007-06-21 15:35:49Z beck $
  *
  * Fixup schedule to respect flag constraints by moving and rematerialisation of
  * nodes.
@@ -54,6 +53,7 @@
 #include "besched.h"
 #include "benode.h"
 #include "belive.h"
+#include "beabihelper.h"
 
 static const arch_register_class_t *flag_class;
 static const arch_register_t       *flags_reg;
@@ -87,7 +87,6 @@ static bool default_check_modifies(const ir_node *node)
  */
 static bool can_move(ir_node *node, ir_node *after)
 {
-       const ir_edge_t *edge;
        ir_node *node_block = get_nodes_block(node);
        assert(node_block == get_nodes_block(after));
 
@@ -98,7 +97,6 @@ static bool can_move(ir_node *node, ir_node *after)
        foreach_out_edge(node, edge) {
                ir_node *out = get_edge_src_irn(edge);
                if (is_Proj(out)) {
-                       const ir_edge_t *edge2;
                        assert(get_irn_n_edges_kind(out, EDGE_KIND_DEP) == 0);
                        foreach_out_edge(out, edge2) {
                                ir_node *out2 = get_edge_src_irn(edge2);
@@ -108,7 +106,6 @@ static bool can_move(ir_node *node, ir_node *after)
                                if (is_Phi(out2) || is_End(out2))
                                        continue;
                                if (is_Sync(out2)) {
-                                       const ir_edge_t *edge3;
                                        foreach_out_edge(out2, edge3) {
                                                ir_node *out3 = get_edge_src_irn(edge3);
                                                /* Phi or End represents a usage at block end. */
@@ -161,6 +158,7 @@ static void rematerialize_or_move(ir_node *flags_needed, ir_node *node,
        if (get_irn_mode(copy) == mode_T) {
                ir_mode *mode = flag_class->mode;
                value = new_rd_Proj(NULL, copy, mode, pn);
+               be_add_missing_keeps_node(copy);
        } else {
                value = copy;
        }
@@ -205,19 +203,21 @@ static void rematerialize_or_move(ir_node *flags_needed, ir_node *node,
  */
 static void fix_flags_walker(ir_node *block, void *env)
 {
-       ir_node *node;
        ir_node *flags_needed   = NULL;
        ir_node *flag_consumers = NULL;
        int      pn = -1;
        (void) env;
 
+       ir_node *place = block;
        sched_foreach_reverse(block, node) {
                int i, arity;
                ir_node *new_flags_needed = NULL;
                ir_node *test;
 
-               if (is_Phi(node))
+               if (is_Phi(node)) {
+                       place = node;
                        break;
+               }
 
                if (node == flags_needed) {
                        /* all ok */
@@ -240,8 +240,9 @@ static void fix_flags_walker(ir_node *block, void *env)
                /* test whether the current node needs flags */
                arity = get_irn_arity(node);
                for (i = 0; i < arity; ++i) {
-                       const arch_register_class_t *cls = arch_get_irn_reg_class(node, i);
-                       if (cls == flag_class) {
+                       const arch_register_req_t *req
+                               = arch_get_irn_register_req_in(node, i);
+                       if (req->cls == flag_class) {
                                assert(new_flags_needed == NULL);
                                new_flags_needed = get_irn_n(node, i);
                        }
@@ -279,7 +280,7 @@ static void fix_flags_walker(ir_node *block, void *env)
 
        if (flags_needed != NULL) {
                assert(get_nodes_block(flags_needed) != block);
-               rematerialize_or_move(flags_needed, node, flag_consumers, pn);
+               rematerialize_or_move(flags_needed, place, flag_consumers, pn);
                flags_needed   = NULL;
                flag_consumers = NULL;
        }