Remove the unused attribute const arch_env_t *arch_env from struct draw_chordal_env_t.
[libfirm] / ir / ir / iredges.c
index 7eb0197..74f3240 100644 (file)
 #include "irgwalk.h"
 #include "irdump_t.h"
 #include "irprintf.h"
-#include "irhooks.h"
 #include "debug.h"
 #include "set.h"
 #include "bitset.h"
-#include "xmalloc.h"
 
 #include "iredgeset.h"
 #include "hashptr.h"
@@ -54,7 +52,7 @@
 #define ValueType                 ir_edge_t*
 #define NullValue                 NULL
 #define DeletedValue              ((ir_edge_t*)-1)
-#define Hash(this,key)            (HASH_PTR(key->src) ^ key->pos)
+#define Hash(this,key)            (HASH_PTR(key->src) ^ (key->pos * 40013))
 #define KeysEqual(this,key1,key2) ((key1->src) == (key2->src) && (key1->pos == key2->pos))
 #define SetRangeEmpty(ptr,size)   memset(ptr, 0, (size) * sizeof((ptr)[0]))
 
@@ -194,7 +192,7 @@ void edges_reset_private_data(ir_graph *irg, int offset, size_t size) {
 void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind) {
        if (edges_activated_kind(irg, kind)) {
                irg_edge_info_t *info = _get_irg_edge_info(irg, kind);
-               size_t amount = 32;
+               size_t amount = irg->estimated_node_count * 2;
 
                edges_used = 1;
                if(info->allocated) {
@@ -485,9 +483,6 @@ static void build_edges_walker(ir_node *irn, void *data) {
        ir_graph              *irg = w->irg;
        get_edge_src_n_func_t *get_n;
 
-       if (! edges_activated_kind(irg, kind))
-               return;
-
        get_n = edge_kind_info[kind].get_n;
        foreach_tgt(irn, i, n, kind) {
                ir_node *pred = get_n(irn, i, kind);
@@ -502,18 +497,56 @@ static void build_edges_walker(ir_node *irn, void *data) {
 static void init_lh_walker(ir_node *irn, void *data) {
        struct build_walker *w   = data;
        ir_edge_kind_t      kind = w->kind;
-       INIT_LIST_HEAD(_get_irn_outs_head(irn, kind));
+       list_head           *head = _get_irn_outs_head(irn, kind);
+       INIT_LIST_HEAD(head);
        _get_irn_edge_info(irn, kind)->out_count = 0;
 }
 
+/**
+ * Pre-Walker: initializes the list-heads and set the out-count
+ * of all nodes to 0.
+ *
+ * Additionally touches DEP nodes, as they might be DEAD.
+ * THIS IS UGLY, but I don't find a better way until we
+ *
+ * a) ensure that dead nodes are not used as input
+ * b) it might be sufficient to add those stupid NO_REG nodes
+ * to the anchor
+ */
+static void init_lh_walker_dep(ir_node *irn, void *data) {
+       struct build_walker *w   = data;
+       ir_edge_kind_t      kind = w->kind;
+       list_head           *head = _get_irn_outs_head(irn, kind);
+       int                 i;
+
+       INIT_LIST_HEAD(head);
+       _get_irn_edge_info(irn, kind)->out_count = 0;
+
+       for (i = get_irn_deps(irn) - 1; i >= 0; --i) {
+               ir_node *dep = get_irn_dep(irn, i);
+
+               head = _get_irn_outs_head(dep, kind);
+
+               INIT_LIST_HEAD(head);
+               _get_irn_edge_info(dep, kind)->out_count = 0;
+       }
+}
+
+typedef struct visitor_info_t {
+       irg_walk_func *visit;
+       void *data;
+} visitor_info_t;
+
 /**
  * Visitor: initializes the list-heads and set the out-count
  * of all nodes to 0 of nodes that are not seen so far.
  */
 static void visitor(ir_node *irn, void *data) {
-       if (irn_not_visited(irn)) {
+       visitor_info_t *info = data;
+
+       if (!irn_visited(irn)) {
                mark_irn_visited(irn);
-               init_lh_walker(irn, data);
+               info->visit(irn, info->data);
        }
 }
 
@@ -542,15 +575,27 @@ static void visitor(ir_node *irn, void *data) {
 void edges_activate_kind(ir_graph *irg, ir_edge_kind_t kind)
 {
        struct build_walker w;
-       irg_edge_info_t *info = _get_irg_edge_info(irg, kind);
+       irg_edge_info_t     *info = _get_irg_edge_info(irg, kind);
+       visitor_info_t      visit;
 
        w.irg  = irg;
        w.kind = kind;
 
+       visit.data = &w;
+
        info->activated = 1;
        edges_init_graph_kind(irg, kind);
-       irg_walk_anchors(irg, init_lh_walker, build_edges_walker, &w);
-       visit_all_identities(irg, visitor, &w);
+       if (kind == EDGE_KIND_DEP) {
+               irg_walk_anchors(irg, init_lh_walker_dep, NULL, &w);
+               /* Argh: Dep nodes might be dead, so we MUST visit identities first */
+               visit.visit = init_lh_walker_dep;
+               visit_all_identities(irg, visitor, &visit);
+               irg_walk_anchors(irg, NULL, build_edges_walker, &w);
+       } else {
+               irg_walk_anchors(irg, init_lh_walker, build_edges_walker, &w);
+               visit.visit = init_lh_walker;
+               visit_all_identities(irg, visitor, &visit);
+       }
 }
 
 void edges_deactivate_kind(ir_graph *irg, ir_edge_kind_t kind)
@@ -834,11 +879,15 @@ void edges_init_dbg(int do_dbg) {
 void edges_activate(ir_graph *irg) {
        edges_activate_kind(irg, EDGE_KIND_NORMAL);
        edges_activate_kind(irg, EDGE_KIND_BLOCK);
+       if (get_irg_phase_state(irg) == phase_backend)
+               edges_activate_kind(irg, EDGE_KIND_DEP);
 }
 
 void edges_deactivate(ir_graph *irg) {
-       edges_deactivate_kind(irg, EDGE_KIND_NORMAL);
+       if (get_irg_phase_state(irg) == phase_backend)
+               edges_deactivate_kind(irg, EDGE_KIND_DEP);
        edges_deactivate_kind(irg, EDGE_KIND_BLOCK);
+       edges_deactivate_kind(irg, EDGE_KIND_NORMAL);
 }
 
 int edges_assure(ir_graph *irg) {
@@ -902,7 +951,7 @@ static void irg_block_edges_walk2(ir_node *bl,
                                 void *env) {
        const ir_edge_t *edge, *next;
 
-       if (Block_not_block_visited(bl)) {
+       if (!Block_block_visited(bl)) {
                mark_Block_block_visited(bl);
 
                if (pre)
@@ -919,8 +968,6 @@ static void irg_block_edges_walk2(ir_node *bl,
        }
 }
 
-/* Walks only over Block nodes in the graph.  Has it's own visited
-   flag, so that it can be interleaved with the other walker.         */
 void irg_block_edges_walk(ir_node *node,
                           irg_walk_func *pre, irg_walk_func *post,
                           void *env) {
@@ -928,6 +975,10 @@ void irg_block_edges_walk(ir_node *node,
        assert(edges_activated(current_ir_graph));
        assert(is_Block(node));
 
+       ir_reserve_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED);
+
        inc_irg_block_visited(current_ir_graph);
        irg_block_edges_walk2(node, pre, post, env);
+
+       ir_free_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED);
 }