- changed Phi0 attribute to be a struct
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 23 May 2007 13:15:57 +0000 (13:15 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 23 May 2007 13:15:57 +0000 (13:15 +0000)
- Phi0 attribute is only available onb Phi0 nodes

This should now allow CSE on Phi nodes!

[r14002]

ir/ir/ircons.c
ir/ir/irnode.c
ir/ir/irnode_t.h
ir/ir/irop.c
ir/ir/iropt.c

index b30e1a2..8c2fed5 100644 (file)
@@ -250,7 +250,7 @@ new_bd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode)
                        break;
                }
 
-       if (!has_unknown) res = optimize_node (res);
+       if (!has_unknown) res = optimize_node(res);
        IRN_VRFY_IRG(res, irg);
 
        /* Memory Phis in endless loops must be kept alive.
@@ -2056,8 +2056,7 @@ get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
                /* Error Message */
                printf("Error: no value set.  Use of undefined variable.  Initializing to zero.\n");
                assert(mode->code >= irm_F && mode->code <= irm_P);
-               res = new_rd_Const(NULL, current_ir_graph, block, mode,
-                                  tarval_mode_null[mode->code]);
+               res = new_rd_Const(NULL, current_ir_graph, block, mode, tarval_mode_null[mode->code]);
        }
 
        /* The local valid value is available now. */
@@ -2251,11 +2250,11 @@ get_r_frag_value_internal(ir_node *block, ir_node *cfOp, int pos, ir_mode *mode)
                        if (block->attr.block.matured) {
                                int ins = get_irn_arity(block);
                                ir_node **nin;
-                               NEW_ARR_A (ir_node *, nin, ins);
+                               NEW_ARR_A(ir_node *, nin, ins);
                                res = phi_merge(block, pos, mode, nin, ins);
                        } else {
-                               res = new_rd_Phi0 (current_ir_graph, block, mode);
-                               res->attr.phi0_pos = pos;
+                               res = new_rd_Phi0(current_ir_graph, block, mode);
+                               res->attr.phi0.pos = pos;
                                res->link = block->link;
                                block->link = res;
                        }
@@ -2462,8 +2461,8 @@ get_r_value_internal(ir_node *block, int pos, ir_mode *mode) {
                   The Phi0 has to remember the pos of it's internal value.  If the real
                   Phi is computed, pos is used to update the array with the local
                   values. */
-               res = new_rd_Phi0 (current_ir_graph, block, mode);
-               res->attr.phi0_pos = pos;
+               res = new_rd_Phi0(current_ir_graph, block, mode);
+               res->attr.phi0.pos = pos;
                res->link = block->link;
                block->link = res;
        }
@@ -2502,19 +2501,19 @@ mature_immBlock(ir_node *block) {
           assert (!get_Block_matured(block) && "Block already matured"); */
 
        if (!get_Block_matured(block)) {
-               ins = ARR_LEN (block->in)-1;
+               ins = ARR_LEN(block->in)-1;
                /* Fix block parameters */
                block->attr.block.backedge = new_backedge_arr(current_ir_graph->obst, ins);
 
                /* An array for building the Phi nodes. */
-               NEW_ARR_A (ir_node *, nin, ins);
+               NEW_ARR_A(ir_node *, nin, ins);
 
                /* Traverse a chain of Phi nodes attached to this block and mature
                these, too. **/
                for (n = block->link; n; n = next) {
                        inc_irg_visited(current_ir_graph);
                        next = n->link;
-                       exchange(n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
+                       exchange(n, phi_merge(block, n->attr.phi0.pos, n->mode, nin, ins));
                }
 
                block->attr.block.matured = 1;
index 3c542d9..72e2c68 100644 (file)
@@ -139,9 +139,9 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo
        int i;
 
        assert(irg && op && mode);
-       p = obstack_alloc (irg->obst, node_size);
+       p = obstack_alloc(irg->obst, node_size);
        memset(p, 0, node_size);
-       res = (ir_node *) (p + firm_add_node_size);
+       res = (ir_node *)(p + firm_add_node_size);
 
        res->kind     = k_ir_node;
        res->op       = op;
@@ -152,10 +152,10 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo
        res->deps     = NULL;
 
        if (arity < 0) {
-               res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
+               res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
        } else {
-               res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
-               memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
+               res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1));
+               memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
        }
 
        res->in[0] = block;
@@ -166,10 +166,10 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo
        res->node_nr = get_irp_new_node_nr();
 #endif
 
-       for(i = 0; i < EDGE_KIND_LAST; ++i)
+       for (i = 0; i < EDGE_KIND_LAST; ++i)
                INIT_LIST_HEAD(&res->edge_info[i].outs_head);
 
-       // don't put this into the for loop, arity is -1 for some nodes!
+       /* don't put this into the for loop, arity is -1 for some nodes! */
        edges_notify_edge(res, -1, res->in[0], NULL, irg);
        for (i = 1; i <= arity; ++i)
                edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
@@ -382,11 +382,10 @@ int add_irn_dep(ir_node *node, ir_node *dep)
        return res;
 }
 
-void add_irn_deps(ir_node *tgt, ir_node *src)
-{
+void add_irn_deps(ir_node *tgt, ir_node *src) {
        int i, n;
 
-       for(i = 0, n = get_irn_deps(src); i < n; ++i)
+       for (i = 0, n = get_irn_deps(src); i < n; ++i)
                add_irn_dep(tgt, get_irn_dep(src, i));
 }
 
@@ -439,9 +438,7 @@ ir_opcode
 const char *
 get_irn_opname(const ir_node *node) {
        assert(node);
-       if ((get_irn_op((ir_node *)node) == op_Phi) &&
-               (get_irg_phase_state(get_irn_irg((ir_node *)node)) == phase_building) &&
-               (get_irn_arity((ir_node *)node) == 0)) return "Phi0";
+       if (is_Phi0(node)) return "Phi0";
        return get_id_str(node->op->name);
 }
 
@@ -585,9 +582,9 @@ get_irn_sel_attr(ir_node *node) {
 }
 
 int
-get_irn_phi_attr(ir_node *node) {
-       assert(node->op == op_Phi);
-       return node->attr.phi0_pos;
+get_irn_phi0_attr(ir_node *node) {
+       assert(is_Phi0(node));
+       return node->attr.phi0.pos;
 }
 
 block_attr
index 7d72c62..a2d461f 100644 (file)
@@ -169,6 +169,16 @@ typedef struct {
        ir_volatility volatility;     /**< the volatility of a Store operation */
 } store_attr;
 
+typedef struct {
+       int            pos;  /**< For Phi. Used to remember the value defined by
+                        this Phi node.  Needed when the Phi is completed
+                        to call get_r_internal_value to find the
+                        predecessors. If this attribute is set, the Phi
+                        node takes the role of the obsolete Phi0 node,
+                        therefore the name. */
+} phi0_attr;
+
+
 typedef pn_Cmp confirm_attr;    /**< Attribute to hold compare operation */
 
 /** CopyB attribute. */
@@ -209,12 +219,7 @@ typedef union {
        cast_attr      cast;   /**< For Cast. */
        load_attr      load;   /**< For Load. */
        store_attr     store;  /**< For Store. */
-       int            phi0_pos;  /**< For Phi. Used to remember the value defined by
-                        this Phi node.  Needed when the Phi is completed
-                        to call get_r_internal_value to find the
-                        predecessors. If this attribute is set, the Phi
-                        node takes the role of the obsolete Phi0 node,
-                        therefore the name. */
+       phi0_attr      phi0;   /**< for Phi0 nodes. */
        int *phi_backedge;    /**< For Phi after construction.
                                   Field n set to true if pred n is backedge.
                                   @todo Ev. replace by bitfield! */
@@ -295,7 +300,7 @@ symconst_attr get_irn_symconst_attr (ir_node *node);
 ir_type      *get_irn_call_attr     (ir_node *node);
 ir_type      *get_irn_funccall_attr (ir_node *node);
 sel_attr      get_irn_sel_attr      (ir_node *node);
-int           get_irn_phi_attr      (ir_node *node);
+int           get_irn_phi0_attr     (ir_node *node);
 block_attr    get_irn_block_attr    (ir_node *node);
 load_attr     get_irn_load_attr     (ir_node *node);
 store_attr    get_irn_store_attr    (ir_node *node);
index 9502bd6..1971fd3 100644 (file)
@@ -298,7 +298,7 @@ init_op(void)
        op_Carry     = new_ir_op(iro_Carry,     "Carry",     op_pin_state_floats, C,       oparity_binary,    0, 0, NULL);
        op_Borrow    = new_ir_op(iro_Borrow,    "Borrow",    op_pin_state_floats, N,       oparity_binary,    0, 0, NULL);
 
-       op_Phi       = new_ir_op(iro_Phi,       "Phi",       op_pin_state_pinned, N,       oparity_variable, -1, sizeof(int), NULL);
+       op_Phi       = new_ir_op(iro_Phi,       "Phi",       op_pin_state_pinned, N,       oparity_variable, -1, sizeof(phi0_attr), NULL);
 
        op_Load      = new_ir_op(iro_Load,      "Load",      op_pin_state_exc_pinned, F,   oparity_any,      -1, sizeof(load_attr), NULL);
        op_Store     = new_ir_op(iro_Store,     "Store",     op_pin_state_exc_pinned, F,   oparity_any,      -1, sizeof(store_attr), NULL);
index 093b1f3..38e5f08 100644 (file)
@@ -3172,17 +3172,24 @@ static ir_node *transform_node_Shl(ir_node *n) {
  * in keep alive list.  We do not generate a new End node.
  */
 static ir_node *transform_node_End(ir_node *n) {
-       int i, n_keepalives = get_End_n_keepalives(n);
+       int i, j, n_keepalives = get_End_n_keepalives(n);
+       ir_node **in;
 
-       for (i = 0; i < n_keepalives; ++i) {
+       NEW_ARR_A(ir_node *, in, n_keepalives);
+
+       for (i = j = 0; i < n_keepalives; ++i) {
                ir_node *ka = get_End_keepalive(n, i);
                if (is_Block(ka)) {
-                       if (is_Block_dead(ka)) {
-                               set_End_keepalive(n, i, new_Bad());
+                       if (is_Block_dead(ka)) {
+                               in[j++] = ka;
                        }
-               } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka)))
-                       set_End_keepalive(n, i, new_Bad());
+               } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) {
+                       continue;
+               } if (is_Phi(ka) || is_irn_keep(ka))
+                       in[j++] = ka;
        }
+       if (j != n_keepalives)
+               set_End_keepalives(n, j, in);
        return n;
 }  /* transform_node_End */
 
@@ -3443,7 +3450,13 @@ static int node_cmp_attr_Sel(ir_node *a, ir_node *b) {
 
 /** Compares the attributes of two Phi nodes. */
 static int node_cmp_attr_Phi(ir_node *a, ir_node *b) {
-       return get_irn_phi_attr (a) != get_irn_phi_attr (b);
+       /* we can only enter this function if both nodes have the same number of inputs,
+          hence it is enough to check if one of them is a Phi0 */
+       if (is_Phi0(a)) {
+               /* check the Phi0 attribute */
+               return get_irn_phi0_attr(a) != get_irn_phi0_attr(b);
+       }
+       return 0;
 }  /* node_cmp_attr_Phi */
 
 /** Compares the attributes of two Conv nodes. */