ia32_Minus64Bit needs no contraint copies.
[libfirm] / ir / ir / iredges.c
index ac97bff..799dada 100644 (file)
@@ -313,7 +313,6 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt,
        irg_edge_info_t *info;
        ir_edgeset_t    *edges;
        ir_edge_t        templ;
-       ir_edge_t       *edge;
 
        assert(edges_activated_kind(irg, kind));
 
@@ -335,7 +334,7 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt,
         */
        if (tgt == NULL) {
                /* search the edge in the set. */
-               edge = ir_edgeset_find(edges, &templ);
+               ir_edge_t *edge = ir_edgeset_find(edges, &templ);
 
                /* mark the edge invalid if it was found */
                if (edge) {
@@ -365,7 +364,7 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt,
 
                /* If the old target is not null, the edge is moved. */
                if (old_tgt) {
-                       edge = ir_edgeset_find(edges, &templ);
+                       ir_edge_t *edge = ir_edgeset_find(edges, &templ);
                        assert(edge && "edge to redirect not found!");
                        assert(! edge->invalid && "Invalid edge encountered");
 
@@ -426,14 +425,29 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt,
                edges_notify_edge_kind(src, pos, tgt, old_tgt, EDGE_KIND_NORMAL, irg);
        }
 
-       if (edges_activated_kind(irg, EDGE_KIND_BLOCK) && is_Block(src)) {
-               ir_node *bl_old = old_tgt ? get_nodes_block(skip_Proj(old_tgt)) : NULL;
-               ir_node *bl_tgt = NULL;
-
-               if (tgt)
-                       bl_tgt = is_Bad(tgt) ? tgt : get_nodes_block(skip_Proj(tgt));
-
-               edges_notify_edge_kind(src, pos, bl_tgt, bl_old, EDGE_KIND_BLOCK, irg);
+       if (edges_activated_kind(irg, EDGE_KIND_BLOCK)) {
+               if (is_Block(src)) {
+                       ir_node *bl_old = old_tgt ? get_nodes_block(old_tgt) : NULL;
+                       ir_node *bl_tgt = NULL;
+
+                       if (tgt)
+                               bl_tgt = is_Bad(tgt) ? tgt : get_nodes_block(tgt);
+
+                       edges_notify_edge_kind(src, pos, bl_tgt, bl_old, EDGE_KIND_BLOCK, irg);
+               } else if (get_irn_mode(src) == mode_X && old_tgt != NULL && is_Block(old_tgt)) {
+                       /* moving a jump node from one block to another */
+                       const ir_edge_t *edge;
+                       const ir_edge_t *next;
+                       foreach_out_edge_kind_safe(old_tgt, edge, next, EDGE_KIND_BLOCK) {
+                               ir_node *succ       = get_edge_src_irn(edge);
+                               int      succ_pos   = get_edge_src_pos(edge);
+                               ir_node *block_pred = get_Block_cfgpred(succ, succ_pos);
+                               if (block_pred != src)
+                                       continue;
+                               edges_notify_edge_kind(succ, succ_pos, tgt, old_tgt,
+                                                      EDGE_KIND_BLOCK, irg);
+                       }
+               }
        }
 }
 
@@ -504,9 +518,7 @@ static void build_edges_walker(ir_node *irn, void *data)
        int                   i, n;
        ir_edge_kind_t        kind = w->kind;
        ir_graph              *irg = get_irn_irg(irn);
-       get_edge_src_n_func_t *get_n;
 
-       get_n = edge_kind_info[kind].get_n;
        foreach_tgt(irn, i, n, kind) {
                ir_node *pred = get_n(irn, i, kind);
                edges_notify_edge_kind(irn, i, pred, NULL, kind, irg);
@@ -576,6 +588,8 @@ static void visitor(ir_node *irn, void *data)
 
        if (is_Deleted(irn))
                return;
+       if (!is_Block(irn) && is_Deleted(get_nodes_block(irn)))
+               return;
 
        if (!irn_visited_else_mark(irn)) {
                info->visit(irn, info->data);
@@ -1005,9 +1019,8 @@ static void irg_walk_edges2(ir_node *node, irg_walk_func *pre,
 {
        const ir_edge_t *edge, *next;
 
-       if (irn_visited(node))
+       if (irn_visited_else_mark(node))
                return;
-       mark_irn_visited(node);
 
        if (pre != NULL)
                pre(node, env);