be_abi_put_ignore_regs returns now number of ignore registers as unsigned
[libfirm] / ir / be / bespillremat.c
index c54f3f4..5aa573b 100644 (file)
@@ -1,12 +1,28 @@
-/** vim: set sw=4 ts=4:
- * @file   bespillremat.c
- * @date   2006-04-06
- * @author Adam M. Szalkowski & Sebastian Hack
+/*
+ * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
  *
- * ILP based spilling & rematerialization
+ * This file is part of libFirm.
  *
- * Copyright (C) 2006 Universitaet Karlsruhe
- * Released under the GPL
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief       ILP based spilling & rematerialization
+ * @author      Adam M. Szalkowski
+ * @date        06.04.2006
+ * @version     $Id$
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -29,8 +45,9 @@
 #include "irnode_t.h"
 #include "ircons_t.h"
 #include "irloop_t.h"
+#include "irnodeset.h"
 #include "phiclass.h"
-#include "iredges.h"
+#include "iredges_t.h"
 #include "execfreq.h"
 #include "irvrfy.h"
 #include "irbackedge_t.h"
 #include <lpp/lpp_cplex.h>
 
 #include "be_t.h"
+#include "beirg_t.h"
 #include "belive_t.h"
 #include "besched_t.h"
-#include "beirgmod.h"
-#include "bearch.h"
+#include "bessaconstr.h"
+#include "bearch_t.h"
+#include "beintlive_t.h"
 #include "beabi.h"
 #include "benode_t.h"
 #include "beutil.h"
@@ -53,8 +72,8 @@
 #include "bepressurestat.h"
 #include "beprofile.h"
 #include "bespilloptions.h"
-
 #include "bechordal_t.h"
+#include "bemodule.h"
 
 #include <libcore/lc_opts.h>
 #include <libcore/lc_opts_enum.h>
@@ -1588,6 +1607,7 @@ luke_endwalker(ir_node * bb, void * data)
        del_pset(use_end);
 }
 
+#ifndef NDEBUG
 /**
  * Find a remat of value @p value in the epilog of @p pos
  */
@@ -1615,6 +1635,7 @@ find_post_remat(const ir_node * value, const ir_node * pos)
 
        return NULL;
 }
+#endif
 
 static spill_t *
 add_to_spill_bb(spill_ilp_t * si, ir_node * bb, ir_node * irn)
@@ -2439,11 +2460,13 @@ skip_one_must_die:
                        assert(has_reg_class(si, tmp));
                }
 
+#ifndef NDEBUG
                for (n=get_irn_arity(irn)-1; n>=0; --n) {
                        ir_node        *arg = get_irn_n(irn, n);
 
                        assert(!find_post_remat(arg, irn) && "there should be no post remat for an argument of an op");
                }
+#endif
 
                del_pset(remat_defs);
                del_pset(used);
@@ -2889,19 +2912,19 @@ set_insert_interference(spill_ilp_t * si, set * set, ir_node * a, ir_node * b, i
        return result;
 }
 
-static int
-values_interfere_in_block(const spill_ilp_t * si, const ir_node * bb, const ir_node * a, const ir_node * b)
+static
+int values_interfere_in_block(const spill_ilp_t *si, const ir_node *bb, const ir_node *a, const ir_node *b)
 {
        const ir_edge_t *edge;
 
-       if(get_nodes_block(a) != bb && get_nodes_block(b) != bb) {
+       if (get_nodes_block(a) != bb && get_nodes_block(b) != bb) {
                /* both values are live in, so they interfere */
                return 1;
        }
 
        /* ensure a dominates b */
-       if(value_dominates(b,a)) {
-               const ir_node * t;
+       if (value_dominates(b, a)) {
+               const ir_node *t;
                t = b;
                b = a;
                a = t;
@@ -2910,15 +2933,15 @@ values_interfere_in_block(const spill_ilp_t * si, const ir_node * bb, const ir_n
 
 
        /* the following code is stolen from bera.c */
-       if(be_is_live_end(si->lv, bb, a))
+       if (be_is_live_end(si->lv, bb, a))
                return 1;
 
        foreach_out_edge(a, edge) {
                const ir_node *user = edge->src;
-               if(get_nodes_block(user) == bb
-                               && !is_Phi(user)
+               if (get_nodes_block(user) == bb
+                               && ! is_Phi(user)
                                && b != user
-                               && !pset_find_ptr(si->inverse_ops, user)
+                               && ! pset_find_ptr(si->inverse_ops, user)
                                && value_dominates(b, user))
                        return 1;
        }
@@ -4126,10 +4149,10 @@ static void
 rewire_uses(spill_ilp_t * si)
 {
        defs_t               *defs;
-       pset                 *ignore = pset_new_ptr(1);
-       be_dom_front_info_t *dom_front = si->birg->dom_front;
+       ir_nodeset_t         ignore;
 
-       pset_insert_ptr(ignore, get_irg_end(si->birg->irg));
+       ir_nodeset_init(&ignore);
+       ir_nodeset_insert(&ignore, get_irg_end(si->birg->irg));
 
        /* then fix uses of spills */
        set_foreach(si->values, defs) {
@@ -4152,11 +4175,25 @@ rewire_uses(spill_ilp_t * si)
                spills = get_spills_for_value(si, defs->value);
                DBG((si->dbg, LEVEL_2, "\t  %d remats, %d reloads, and %d spills for value %+F\n", remats, pset_count(reloads), pset_count(spills), defs->value));
                if(pset_count(spills) > 1) {
+                       be_ssa_construction_env_t senv;
+                       ir_node *node;
                        //assert(pset_count(reloads) > 0);
                        //                              print_irn_pset(spills);
                        //                              print_irn_pset(reloads);
 
-                       be_ssa_constr_set_ignore(dom_front, si->lv, spills, ignore);
+                       be_ssa_construction_init(&senv, si->birg);
+                       be_ssa_construction_set_ignore_uses(&senv, &ignore);
+                       pset_foreach(spills, node) {
+                               be_ssa_construction_add_copy(&senv, node);
+                       }
+                       pset_foreach(spills, node) {
+                               be_ssa_construction_fix_users(&senv, node);
+                       }
+                       be_ssa_construction_update_liveness_phis(&senv, si->lv);
+                       pset_foreach(spills, node) {
+                               be_liveness_update(si->lv, node);
+                       }
+                       be_ssa_construction_destroy(&senv);
                }
 
                del_pset(reloads);
@@ -4165,29 +4202,51 @@ rewire_uses(spill_ilp_t * si)
 
        /* first fix uses of remats and reloads */
        set_foreach(si->values, defs) {
-               pset           *nodes;
                const ir_node  *next = defs->remats;
                int             orig_kept = 0;
 
                if(next) {
-                       nodes = pset_new_ptr_default();
+                       be_ssa_construction_env_t senv;
+
+                       be_ssa_construction_init(&senv, si->birg);
+
                        if(sched_is_scheduled(defs->value)) {
-                               pset_insert_ptr(nodes, defs->value);
+                               be_ssa_construction_add_copy(&senv, (ir_node*) defs->value);
                                orig_kept = 1;
                        }
 
+                       next = defs->remats;
                        while(next) {
-                               pset_insert_ptr(nodes, next);
+                               be_ssa_construction_add_copy(&senv, (ir_node*) next);
                                next = get_irn_link(next);
                        }
 
-                       DBG((si->dbg, LEVEL_4, "\t    %d new definitions for value %+F\n", pset_count(nodes)-orig_kept, defs->value));
-                       be_ssa_constr_set_ignore(dom_front, si->lv, nodes, NULL);
+                       if(sched_is_scheduled(defs->value)) {
+                               be_ssa_construction_fix_users(&senv, (ir_node*) defs->value);
+                       }
+
+                       next = defs->remats;
+                       while(next) {
+                               be_ssa_construction_fix_users(&senv, (ir_node*) next);
+                               next = get_irn_link(next);
+                       }
+
+                       be_ssa_construction_update_liveness_phis(&senv, si->lv);
+                       if(sched_is_scheduled(defs->value)) {
+                               be_liveness_update(si->lv, (ir_node*) defs->value);
+                       }
+
+                       next = defs->remats;
+                       while(next) {
+                               be_liveness_update(si->lv, (ir_node*) next);
+                               next = get_irn_link(next);
+                       }
 
-                       del_pset(nodes);
+                       be_ssa_construction_destroy(&senv);
                }
        }
 
+       ir_nodeset_destroy(&ignore);
 //     remove_unused_defs(si);
 }