BugFix: equivalent_node_Bound() was too greedy, reduced to a safe minimum (now mostly...
[libfirm] / ir / ir / irnode.c
index 478a42a..8f445b3 100644 (file)
@@ -41,6 +41,7 @@
 #include "irprog_t.h"
 #include "iredgekinds.h"
 #include "iredges_t.h"
+#include "ircons.h"
 
 #include "irhooks.h"
 #include "irtools.h"
@@ -227,40 +228,41 @@ get_irn_in(const ir_node *node) {
 void
 set_irn_in(ir_node *node, int arity, ir_node **in) {
        int i;
-       ir_node *** arr;
+       ir_node *** pOld_in;
        ir_graph *irg = current_ir_graph;
        assert(node);
        if (get_interprocedural_view()) { /* handle Filter and Block specially */
-               if (get_irn_opcode(node) == iro_Filter) {
+               ir_opcode code = get_irn_opcode(node);
+               if (code  == iro_Filter) {
                        assert(node->attr.filter.in_cg);
-                       arr = &node->attr.filter.in_cg;
-               } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
-                       arr = &node->attr.block.in_cg;
+                       pOld_in = &node->attr.filter.in_cg;
+               } else if (code == iro_Block && node->attr.block.in_cg) {
+                       pOld_in = &node->attr.block.in_cg;
                } else {
-                       arr = &node->in;
+                       pOld_in = &node->in;
                }
        } else {
-               arr = &node->in;
+               pOld_in = &node->in;
        }
 
        for (i = 0; i < arity; i++) {
-               if (i < ARR_LEN(*arr)-1)
-                       edges_notify_edge(node, i, in[i], (*arr)[i+1], irg);
+               if (i < ARR_LEN(*pOld_in)-1)
+                       edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
                else
-                       edges_notify_edge(node, i, in[i], NULL,        irg);
+                       edges_notify_edge(node, i, in[i], NULL,            irg);
        }
-       for(;i < ARR_LEN(*arr)-1; i++) {
-               edges_notify_edge(node, i, NULL, (*arr)[i+1], irg);
+       for (;i < ARR_LEN(*pOld_in)-1; i++) {
+               edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
        }
 
-       if (arity != ARR_LEN(*arr) - 1) {
-               ir_node * block = (*arr)[0];
-               *arr = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
-               (*arr)[0] = block;
+       if (arity != ARR_LEN(*pOld_in) - 1) {
+               ir_node * block = (*pOld_in)[0];
+               *pOld_in = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
+               (*pOld_in)[0] = block;
        }
        fix_backedges(irg->obst, node);
 
-       memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
+       memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
 }
 
 ir_node *
@@ -877,6 +879,17 @@ ir_node *get_Block_MacroBlock(const ir_node *block) {
        return mbh;
 }
 
+/* returns the macro block header of a node. */
+ir_node *get_irn_MacroBlock(const ir_node *n) {
+       if (! is_Block(n)) {
+               n = get_nodes_block(n);
+               /* if the Block is Bad, do NOT try to get it's MB, it will fail. */
+               if (is_Bad(n))
+                       return (ir_node *)n;
+       }
+       return get_Block_MacroBlock(n);
+}
+
 /* returns the graph of a Block. */
 ir_graph *get_Block_irg(const ir_node *block) {
        assert(is_Block(block));
@@ -2543,9 +2556,10 @@ ir_node *skip_Confirm(ir_node *node) {
 }
 
 /* skip all high-level ops */
-ir_node *skip_HighLevel(ir_node *node) {
-       if (is_op_highlevel(get_irn_op(node)))
-               return get_irn_n(node, 0);
+ir_node *skip_HighLevel_ops(ir_node *node) {
+       while (is_op_highlevel(get_irn_op(node))) {
+               node = get_irn_n(node, 0);
+       }
        return node;
 }
 
@@ -2696,6 +2710,11 @@ int
        return _is_Tuple(node);
 }
 
+int
+(is_Bound)(const ir_node *node) {
+       return _is_Bound(node);
+}
+
 int
 (is_Start)(const ir_node *node) {
   return _is_Start(node);