fixed some minor bugs
[libfirm] / ir / be / beirgmod.c
index 71b8da9..773343f 100644 (file)
@@ -175,16 +175,16 @@ static void determine_phi_blocks(pset *copies, pset* copy_blocks, pset *phi_bloc
  * traversing from the predecessor block which corresponds to the phi
  * usage.
  *
- * @param usage The node which uses the original node.
- * @param pos The number of the argument which corresponds to the
- * original node.
- * @param copy_blocks A set containing all basic block in which copies
- * of the original node are located.
- * @param copies A set containing all node which are copies from the
- * original node.
- * @return The valid copy for usage.
+ * @param usage       The node which uses the original node.
+ * @param pos         The position of the argument which corresponds to the original node.
+ * @param copies      A set containing all node which are copies from the original node.
+ * @param copy_blocks A set containing all basic block in which copies of the original node are located.
+ * @param phis        A set where all created phis are recorded.
+ * @param phi_blocks  A set of all blocks where Phis shall be inserted (iterated dominance frontier).
+ * @param mode        The mode for the Phi if one has to be created.
+ * @return            The valid copy for usage.
  */
-static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks, pset *phi_blocks, ir_mode *mode)
+static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks, pset *phis, pset *phi_blocks, ir_mode *mode)
 {
        ir_node *curr_bl;
        ir_node *start_irn;
@@ -232,7 +232,7 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo
                        if(!phi) {
                                int i, n_preds = get_irn_arity(curr_bl);
                                ir_graph *irg = get_irn_irg(curr_bl);
-                               ir_node **ins = malloc(n_preds * sizeof(ins[0]));
+                               ir_node **ins = xmalloc(n_preds * sizeof(ins[0]));
 
                                for(i = 0; i < n_preds; ++i)
                                        ins[i] = new_r_Unknown(irg, mode);
@@ -245,10 +245,13 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo
                                free(ins);
 
                                for(i = 0; i < n_preds; ++i) {
-                                       ir_node *arg = search_def(phi, i, copies, copy_blocks, phi_blocks, mode);
+                                       ir_node *arg = search_def(phi, i, copies, copy_blocks, phis, phi_blocks, mode);
                                        DBG((dbg, LEVEL_2, "\t\t%+F(%d) -> %+F\n", phi, i, arg));
                                        set_irn_n(phi, i, arg);
                                }
+
+                               if(phis)
+                                       pset_insert_ptr(phis, phi);
                        }
 
                        return phi;
@@ -263,7 +266,7 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo
        return NULL;
 }
 
-static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *ignore_uses)
+static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *phis, pset *ignore_uses)
 {
        firm_dbg_module_t *dbg = DBG_MODULE;
        int n_outs             = 0;
@@ -304,11 +307,11 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *
        for(i = 0; i < n_outs; ++i) {
                ir_node *irn  = outs[i].irn;
                int pos       = outs[i].pos;
-               ir_mode *mode = get_irn_mode(irn);
+               ir_mode *mode = get_irn_mode(get_irn_n(irn, pos));
 
                ir_node *def;
 
-               def = search_def(irn, pos, copies, copy_blocks, phi_blocks, mode);
+               def = search_def(irn, pos, copies, copy_blocks, phis, phi_blocks, mode);
                DBG((dbg, LEVEL_2, "\t%+F(%d) -> %+F\n", irn, pos, def));
 
                if(def != NULL)
@@ -351,17 +354,22 @@ static void remove_odd_phis(pset *copies, pset *unused_copies)
        }
 }
 
-void be_ssa_constr_ignore(dom_front_info_t *info, int n, ir_node *nodes[], pset *ignore_uses)
+void be_ssa_constr_phis_ignore(dom_front_info_t *info, int n, ir_node *nodes[], pset *phis, pset *ignore_uses)
 {
        pset *irns = pset_new_ptr(n);
        int i;
 
        for(i = 0; i < n; ++i)
                pset_insert_ptr(irns, nodes[i]);
-       be_ssa_constr_set_ignore(info, irns, ignore_uses);
+       be_ssa_constr_set_phis_ignore(info, irns, phis, ignore_uses);
        del_pset(irns);
 }
 
+void be_ssa_constr_ignore(dom_front_info_t *info, int n, ir_node *nodes[], pset *ignore_uses)
+{
+       be_ssa_constr_phis_ignore(info, n, nodes, NULL, ignore_uses);
+}
+
 void be_ssa_constr(dom_front_info_t *info, int n, ir_node *nodes[])
 {
        pset *empty_set = be_empty_set();
@@ -369,7 +377,7 @@ void be_ssa_constr(dom_front_info_t *info, int n, ir_node *nodes[])
        be_ssa_constr_ignore(info, n, nodes, empty_set);
 }
 
-void be_ssa_constr_set_ignore(dom_front_info_t *df, pset *nodes, pset *ignore_uses)
+void be_ssa_constr_set_phis_ignore(dom_front_info_t *df, pset *nodes, pset *phis, pset *ignore_uses)
 {
        int n                  = pset_count(nodes);
        pset *blocks           = pset_new_ptr(n);
@@ -401,7 +409,7 @@ void be_ssa_constr_set_ignore(dom_front_info_t *df, pset *nodes, pset *ignore_us
        * Place the phi functions and reroute the usages.
        */
        determine_phi_blocks(nodes, blocks, phi_blocks, df);
-       fix_usages(nodes, blocks, phi_blocks, ignore_uses);
+       fix_usages(nodes, blocks, phi_blocks, phis, ignore_uses);
 
        /* reset the optimizations */
        set_optimize(save_optimize);
@@ -412,10 +420,22 @@ void be_ssa_constr_set_ignore(dom_front_info_t *df, pset *nodes, pset *ignore_us
 
 }
 
-void be_ssa_constr_set(dom_front_info_t *info, pset *nodes)
+void be_ssa_constr_set_phis(dom_front_info_t *df, pset *nodes, pset *phis)
 {
        pset *empty_set = be_empty_set();
+       assert(pset_count(empty_set) == 0);
 
+       be_ssa_constr_set_phis_ignore(df, nodes,phis, empty_set);
+}
+
+void be_ssa_constr_set_ignore(dom_front_info_t *df, pset *nodes, pset *ignore_uses)
+{
+       be_ssa_constr_set_phis_ignore(df, nodes, NULL, ignore_uses);
+}
+
+void be_ssa_constr_set(dom_front_info_t *info, pset *nodes)
+{
+       pset *empty_set = be_empty_set();
        assert(pset_count(empty_set) == 0);
        be_ssa_constr_set_ignore(info, nodes, empty_set);
 }