- BugFix: when splitting by input, ensure than Z is split by ALL inputs
[libfirm] / ir / ir / irnode.c
index 6fa35b1..d6b9289 100644 (file)
@@ -356,6 +356,8 @@ void (set_irn_dep)(ir_node *node, int pos, ir_node *dep) {
 int add_irn_dep(ir_node *node, ir_node *dep) {
        int res = 0;
 
+       /* DEP edges are only allowed in backend phase */
+       assert(get_irg_phase_state(get_irn_irg(node)) == phase_backend);
        if (node->deps == NULL) {
                node->deps = NEW_ARR_F(ir_node *, 1);
                node->deps[0] = dep;
@@ -927,22 +929,35 @@ void set_End_keepalives(ir_node *end, int n, ir_node *in[]) {
 
 /* Set new keep-alives from old keep-alives, skipping irn */
 void remove_End_keepalive(ir_node *end, ir_node *irn) {
-       int     n = get_End_n_keepalives(end);
-       ir_node **in;
-       int     i, idx;
-
-       NEW_ARR_A(ir_node *, in, n);
-
-       for (idx = i = 0; i < n; ++i) {
-               ir_node *old_ka = get_End_keepalive(end, i);
-
-               /* skip irn */
-               if (old_ka != irn)
-                       in[idx++] = old_ka;
+       int      n = get_End_n_keepalives(end);
+       int      i, idx;
+       ir_graph *irg;
+
+       idx = -1;
+       for (i = n -1; i >= 0; --i) {
+               ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];
+
+               /* find irn */
+               if (old_ka == irn) {
+                       idx = i;
+                       goto found;
+               }
        }
-
-       /* set new keep-alives */
-       set_End_keepalives(end, idx, in);
+       return;
+found:
+       irg = get_irn_irg(end);
+
+       /* remove the edge */
+       edges_notify_edge(end, idx, NULL, irn, irg);
+
+       if (idx != n - 1) {
+               /* exchange with the last one */
+               ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
+               edges_notify_edge(end, n - 1, NULL, old, irg);
+               end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
+               edges_notify_edge(end, idx, old, NULL, irg);
+       }
+       ARR_RESIZE(ir_node *, end->in, (n - 1) + 1 + END_KEEPALIVE_OFFSET);
 }
 
 void
@@ -2051,6 +2066,11 @@ set_Proj_proj(ir_node *node, long proj) {
 #endif /* INTERPROCEDURAL_VIEW */
 }
 
+/* Returns non-zero if a node is a routine parameter. */
+int (is_arg_Proj)(const ir_node *node) {
+       return _is_arg_Proj(node);
+}
+
 ir_node **
 get_Tuple_preds_arr(ir_node *node) {
        assert(is_Tuple(node));
@@ -3191,23 +3211,25 @@ ir_entity *get_Global_entity(const ir_node *node) {
 }
 #endif
 
-#ifdef DEBUG_libfirm
-void dump_irn(const ir_node *n) {
-       int i, arity = get_irn_arity(n);
-       printf("%s%s: %ld (%p)\n", get_irn_opname(n), get_mode_name(get_irn_mode(n)), get_irn_node_nr(n), (void *)n);
-       if (!is_Block(n)) {
-               ir_node *pred = get_irn_n(n, -1);
-               printf("  block: %s%s: %ld (%p)\n", get_irn_opname(pred), get_mode_name(get_irn_mode(pred)),
-                       get_irn_node_nr(pred), (void *)pred);
-       }
-       printf("  preds: \n");
-       for (i = 0; i < arity; ++i) {
-               ir_node *pred = get_irn_n(n, i);
-               printf("    %d: %s%s: %ld (%p)\n", i, get_irn_opname(pred), get_mode_name(get_irn_mode(pred)),
-                       get_irn_node_nr(pred), (void *)pred);
+/*
+ * Calculate a hash value of a node.
+ */
+unsigned firm_default_hash(const ir_node *node) {
+       unsigned h;
+       int i, irn_arity;
+
+       /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
+       h = irn_arity = get_irn_intra_arity(node);
+
+       /* consider all in nodes... except the block if not a control flow. */
+       for (i = is_cfop(node) ? -1 : 0;  i < irn_arity;  ++i) {
+               h = 9*h + HASH_PTR(get_irn_intra_n(node, i));
        }
-}
 
-#else  /* DEBUG_libfirm */
-void dump_irn(const ir_node *n) { (void) n; }
-#endif /* DEBUG_libfirm */
+       /* ...mode,... */
+       h = 9*h + HASH_PTR(get_irn_mode(node));
+       /* ...and code */
+       h = 9*h + HASH_PTR(get_irn_op(node));
+
+       return h;
+}  /* firm_default_hash */