rename ir_phase to ir_nodemap and simplify interface
authorMatthias Braun <matze@braunis.de>
Wed, 19 Oct 2011 17:41:18 +0000 (19:41 +0200)
committerMatthias Braun <matze@braunis.de>
Thu, 20 Oct 2011 17:32:23 +0000 (19:32 +0200)
The new interface uses no complicated callbacks anymore, but is a simple
ir_node* -> void* nodemap. Adapted all users of ir_phase for this.

28 files changed:
include/libfirm/heights.h
include/libfirm/vrp.h
ir/ana/heights.c
ir/ana/irlivechk.c
ir/ana/irlivechk.h
ir/ana/vrp.c
ir/be/beabihelper.c
ir/be/becopyheur2.c
ir/be/becopyheur4.c
ir/be/becopyopt.c
ir/be/beifg.c
ir/be/beintlive_t.h
ir/be/bessaconstr.c
ir/be/bessaconstr.h
ir/be/betranshlp.c
ir/ir/irgraph.c
ir/ir/irgraph_t.h
ir/ir/irnodemap.h [new file with mode: 0644]
ir/ir/iropt.c
ir/ir/irphase.c [deleted file]
ir/ir/irphase.h [deleted file]
ir/ir/irphase_t.h [deleted file]
ir/ir/irtypes.h
ir/opt/convopt.c
ir/opt/dead_code_elimination.c
ir/opt/ldstopt.c
ir/opt/loop.c
ir/opt/opt_inline.c

index 0b0fe7e..e3b3848 100644 (file)
@@ -55,13 +55,6 @@ FIRM_API unsigned get_irn_height(const ir_heights_t *h, const ir_node *irn);
 FIRM_API int heights_reachable_in_block(ir_heights_t *h, const ir_node *n,
                                         const ir_node *m);
 
-/**
- * Recompute the height information.
- * This can be used to recompute the height information if the graph has changed since the last computation.
- * @param h The heights object.
- */
-FIRM_API void heights_recompute(ir_heights_t *h);
-
 /**
  * Recompute the height information for a certain block.
  * This can be used to recompute the height information of a block.
index 9a58bae..19ea825 100644 (file)
@@ -40,11 +40,12 @@ enum range_types {
 
 /** VRP information */
 typedef struct {
-       int valid;                   /**< This node has valid vrp information */
-       ir_tarval *bits_set;         /**< The bits which, by analysis, are  definitely set.
-                                         0: may be not set, 1: definitely set*/
+       ir_tarval *bits_set;         /**< The bits which, by analysis, are
+                                         definitely set:
+                                         0: may be not set, 1: definitely set */
        ir_tarval *bits_not_set;     /**< The bits which by analysis are definitely
-                                         not set, 1 for may be set, 0: definitely not set  */
+                                         not set:
+                                         1 for may be set, 0: definitely not set */
        enum range_types range_type; /**< The range represented by range_top, range_bottom */
        ir_tarval *range_bottom;
        ir_tarval *range_top;
@@ -56,6 +57,11 @@ typedef struct {
  */
 FIRM_API void set_vrp_data(ir_graph *irg);
 
+/**
+ * free vrp infos in an irg
+ */
+FIRM_API void free_vrp_data(ir_graph *irg);
+
 /**
  * Test, if the two nodes can be compared with their vrp information
  *
@@ -67,9 +73,9 @@ FIRM_API ir_relation vrp_cmp(const ir_node *left, const ir_node *right);
 
 /*
  * Return the vrp data for this node
+ * Note: only allowed for nodes with an integer mode!
  *
  * @param n: the node for which to return the vrp information
- *
  * @return a pointer to the vrp data or NULL if there is none
  */
 FIRM_API vrp_attr *vrp_get_info(const ir_node *n);
index 37c89bf..4586fc8 100644 (file)
 #include "irdump.h"
 #include "irgwalk.h"
 #include "irtools.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 #include "iredges_t.h"
 
 struct ir_heights_t {
-       ir_phase  phase;
-       unsigned  visited;
-       void     *dump_handle;
+       ir_nodemap      data;
+       unsigned        visited;
+       void           *dump_handle;
+       struct obstack  obst;
 };
 
 typedef struct {
@@ -50,30 +51,29 @@ typedef struct {
        unsigned visited;
 } irn_height_t;
 
-static void *irn_height_init(ir_phase *phase, const ir_node *node)
+static irn_height_t *maybe_get_height_data(const ir_heights_t *heights,
+                                           const ir_node *node)
 {
-       irn_height_t *h = (irn_height_t*) phase_alloc(phase, sizeof(*h));
-       (void) node;
-       memset(h, 0, sizeof(*h));
-       return h;
+       irn_height_t *height = (irn_height_t*)ir_nodemap_get(&heights->data, node);
+       return height;
 }
 
-static void *irn_height_reinit(ir_phase *phase, const ir_node *node,
-                               void *old_data)
+static irn_height_t *get_height_data(ir_heights_t *heights, const ir_node *node)
 {
-       irn_height_t *h = (irn_height_t*) old_data;
-       (void) node;
-       (void) phase;
-       memset(h, 0, sizeof(*h));
-       return h;
+       irn_height_t *height = (irn_height_t*)ir_nodemap_get(&heights->data, node);
+       if (height == NULL) {
+               height = obstack_alloc(&heights->obst, sizeof(*height));
+               memset(height, 0, sizeof(*height));
+               ir_nodemap_insert(&heights->data, node, height);
+       }
+       return height;
 }
 
 static void height_dump_cb(void *data, FILE *f, const ir_node *irn)
 {
-       ir_heights_t *heights = (ir_heights_t*) data;
-       irn_height_t *h       = (irn_height_t*) phase_get_irn_data(&heights->phase, irn);
-
-       if (h)
+       const ir_heights_t *heights = (const ir_heights_t*) data;
+       const irn_height_t *h       = maybe_get_height_data(heights, irn);
+       if (h != NULL)
                fprintf(f, "height: %u\n", h->height);
 }
 
@@ -84,8 +84,7 @@ static void height_dump_cb(void *data, FILE *f, const ir_node *irn)
  * @param tgt  The node we try to reach.
  * @return     1, one of tgt can be reached from curr, 0 else.
  */
-static bool search(const ir_heights_t *h, const ir_node *curr,
-                   const ir_node *tgt)
+static bool search(ir_heights_t *h, const ir_node *curr, const ir_node *tgt)
 {
        irn_height_t *h_curr;
        irn_height_t *h_tgt;
@@ -102,12 +101,12 @@ static bool search(const ir_heights_t *h, const ir_node *curr,
                return false;
 
        /* Check, if we have already been here. Coming more often won't help :-) */
-       h_curr = (irn_height_t*) phase_get_irn_data(&h->phase, curr);
+       h_curr = get_height_data(h, curr);
        if (h_curr->visited >= h->visited)
                return false;
 
        /* If we are too deep into the DAG we won't find the target either. */
-       h_tgt = (irn_height_t*) phase_get_irn_data(&h->phase, tgt);
+       h_tgt = get_height_data(h, tgt);
        if (h_curr->height > h_tgt->height)
                return false;
 
@@ -132,8 +131,8 @@ int heights_reachable_in_block(ir_heights_t *h, const ir_node *n,
                                const ir_node *m)
 {
        int res          = 0;
-       irn_height_t *hn = (irn_height_t*) phase_get_irn_data(&h->phase, n);
-       irn_height_t *hm = (irn_height_t*) phase_get_irn_data(&h->phase, m);
+       irn_height_t *hn = get_height_data(h, n);
+       irn_height_t *hm = get_height_data(h, m);
 
        assert(get_nodes_block(n) == get_nodes_block(m));
        assert(hn != NULL && hm != NULL);
@@ -154,7 +153,7 @@ int heights_reachable_in_block(ir_heights_t *h, const ir_node *n,
  */
 static unsigned compute_height(ir_heights_t *h, ir_node *irn, const ir_node *bl)
 {
-       irn_height_t *ih = (irn_height_t*) phase_get_or_set_irn_data(&h->phase, irn);
+       irn_height_t *ih = get_height_data(h, irn);
 
        const ir_edge_t *edge;
 
@@ -223,21 +222,22 @@ static void compute_heights_in_block_walker(ir_node *block, void *data)
 
 unsigned get_irn_height(const ir_heights_t *heights, const ir_node *irn)
 {
-       const irn_height_t *h = (irn_height_t*) phase_get_irn_data(&heights->phase, irn);
-       assert(h && "No height information for node");
-       return h->height;
+       const irn_height_t *height = maybe_get_height_data(heights, irn);
+       assert(height != NULL && "No height information for node");
+       return height->height;
 }
 
 unsigned heights_recompute_block(ir_heights_t *h, ir_node *block)
 {
+       ir_graph *irg = get_irn_irg(block);
        const ir_edge_t *edge;
 
-       edges_assure(phase_get_irg(&h->phase));
+       edges_assure(irg);
 
        /* reset phase data for all nodes in the block */
        foreach_out_edge(block, edge) {
                ir_node      *irn = get_edge_src_irn(edge);
-               irn_height_t *ih  = (irn_height_t*) phase_get_irn_data(&h->phase, irn);
+               irn_height_t *ih  = get_height_data(h, irn);
                memset(ih, 0, sizeof(*ih));
        }
 
@@ -245,29 +245,23 @@ unsigned heights_recompute_block(ir_heights_t *h, ir_node *block)
        return compute_heights_in_block(block, h);
 }
 
-void heights_recompute(ir_heights_t *h)
-{
-       ir_graph *irg = phase_get_irg(&h->phase);
-
-       edges_assure(irg);
-       phase_reinit_irn_data(&h->phase, irn_height_reinit);
-       h->visited = 0;
-       irg_block_walk_graph(irg, compute_heights_in_block_walker, NULL, h);
-}
-
 ir_heights_t *heights_new(ir_graph *irg)
 {
        ir_heights_t *res = XMALLOC(ir_heights_t);
-       phase_init(&res->phase, irg, irn_height_init);
+       ir_nodemap_init(&res->data, irg);
+       obstack_init(&res->obst);
        res->dump_handle = dump_add_node_info_callback(height_dump_cb, res);
-       heights_recompute(res);
+
+       edges_assure(irg);
+       irg_block_walk_graph(irg, compute_heights_in_block_walker, NULL, res);
 
        return res;
 }
 
 void heights_free(ir_heights_t *h)
 {
-       phase_deinit(&h->phase);
        dump_remove_node_info_callback(h->dump_handle);
+       obstack_free(&h->obst, NULL);
+       ir_nodemap_destroy(&h->data);
        xfree(h);
 }
index 914374f..40c8a73 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "irgraph_t.h"
 #include "irnode_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 #include "iredges_t.h"
 
 #include "irprintf.h"
@@ -73,29 +73,30 @@ typedef struct bl_info_t {
                                                                 in the reduced graph. */
 } bl_info_t;
 
-#define get_block_info(lv, bl) ((bl_info_t *) phase_get_irn_data(&(lv)->ph, bl))
-
 struct lv_chk_t {
-       ir_phase     ph;
-       const dfs_t *dfs;
-       int          n_blocks;
-       bitset_t    *back_edge_src;
-       bitset_t    *back_edge_tgt;
-       bl_info_t  **map;
+       ir_nodemap     block_infos;
+       struct obstack obst;
+       const dfs_t   *dfs;
+       int            n_blocks;
+       bitset_t      *back_edge_src;
+       bitset_t      *back_edge_tgt;
+       bl_info_t    **map;
        DEBUG_ONLY(firm_dbg_module_t *dbg;)
 };
 
-static void *init_block_data(ir_phase *ph, const ir_node *irn)
+static bl_info_t *get_block_info(lv_chk_t *lv, const ir_node *block)
 {
-       lv_chk_t *lv      = firm_container_of(ph, lv_chk_t, ph);
-       bl_info_t *bi     = (bl_info_t*) phase_alloc(ph, sizeof(bi[0]));
-
-       bi->id            = get_Block_dom_tree_pre_num(irn);
-       bi->block         = irn;
-       bi->red_reachable = bitset_obstack_alloc(phase_obst(ph), lv->n_blocks);
-       bi->be_tgt_reach  = bitset_obstack_alloc(phase_obst(ph), lv->n_blocks);
-       bi->be_tgt_calc   = 0;
-       return bi;
+       bl_info_t *info = ir_nodemap_get(&lv->block_infos, block);
+       if (info == NULL) {
+               info                = obstack_alloc(&lv->obst, sizeof(*info));
+               info->id            = get_Block_dom_tree_pre_num(block);
+               info->block         = block;
+               info->red_reachable = bitset_obstack_alloc(&lv->obst, lv->n_blocks);
+               info->be_tgt_reach  = bitset_obstack_alloc(&lv->obst, lv->n_blocks);
+               info->be_tgt_calc   = 0;
+               ir_nodemap_insert(&lv->block_infos, block, info);
+       }
+       return info;
 }
 
 /**
@@ -243,27 +244,26 @@ static inline void compute_back_edge_chains(lv_chk_t *lv)
 lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
 {
        lv_chk_t *res = XMALLOC(lv_chk_t);
-       struct obstack *obst;
        int i;
 
        assure_doms(irg);
 
        stat_ev_tim_push();
-       phase_init(&res->ph, irg, init_block_data);
-       obst = phase_obst(&res->ph);
+       ir_nodemap_init(&res->block_infos, irg);
+       obstack_init(&res->obst);
 
        FIRM_DBG_REGISTER(res->dbg, "ir.ana.lvchk");
 
        res->dfs           = dfs;
        res->n_blocks      = dfs_get_n_nodes(res->dfs);
-       res->back_edge_src = bitset_obstack_alloc(obst, res->n_blocks);
-       res->back_edge_tgt = bitset_obstack_alloc(obst, res->n_blocks);
-       res->map           = OALLOCNZ(obst, bl_info_t*, res->n_blocks);
+       res->back_edge_src = bitset_obstack_alloc(&res->obst, res->n_blocks);
+       res->back_edge_tgt = bitset_obstack_alloc(&res->obst, res->n_blocks);
+       res->map           = OALLOCNZ(&res->obst, bl_info_t*, res->n_blocks);
 
        /* fill the map which maps pre_num to block infos */
        for (i = res->n_blocks - 1; i >= 0; --i) {
                ir_node *irn  = (ir_node *) dfs_get_pre_num_node(res->dfs, i);
-               bl_info_t *bi = (bl_info_t*) phase_get_or_set_irn_data(&res->ph, irn);
+               bl_info_t *bi = get_block_info(res, irn);
                assert(bi->id < res->n_blocks);
                assert(res->map[bi->id] == NULL);
                res->map[bi->id] = bi;
@@ -295,7 +295,8 @@ lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
 
 void lv_chk_free(lv_chk_t *lv)
 {
-       phase_deinit(&lv->ph);
+       obstack_free(&lv->obst, NULL);
+       ir_nodemap_destroy(&lv->block_infos);
        xfree(lv);
 }
 
@@ -308,7 +309,7 @@ void lv_chk_free(lv_chk_t *lv)
  * @param var  The node to check for.
  * @return     A bitmask of lv_chk_state_XXX fields.
  */
-unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var)
+unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *var)
 {
        int res  = 0;
        ir_node *def_bl;
index 6b3c1ec..6479627 100644 (file)
@@ -67,7 +67,7 @@ extern void lv_chk_free(lv_chk_t *lv);
  * @param irn  The node to check for.
  * @return     A bitmask of <code>lv_chk_state_t</code>.
  */
-extern unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *irn);
+extern unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *irn);
 
 #define lv_chk_bl_in(lv, bl, irn)  ((lv_chk_bl_xxx((lv), (bl), (irn)) & lv_chk_state_in)  != 0)
 #define lv_chk_bl_end(lv, bl, irn) ((lv_chk_bl_xxx((lv), (bl), (irn)) & lv_chk_state_end) != 0)
index 21c871f..73c1169 100644 (file)
 #include "tv.h"
 #include "irop.h"
 #include "pdeq.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 #include "bitset.h"
 #include "debug.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
 typedef struct vrp_env_t {
-       waitq    *workqueue;
-       bitset_t *visited;
+       waitq       *workqueue;
+       bitset_t    *visited;
+       ir_vrp_info *info;
 } vrp_env_t;
 
-static vrp_attr *get_vrp_attr(const ir_node *node)
+static vrp_attr *vrp_get_or_set_info(ir_vrp_info *info, const ir_node *node)
 {
-       return (vrp_attr*) get_or_set_irn_phase_info(node, PHASE_VRP);
+       vrp_attr *attr = ir_nodemap_get(&info->infos, node);
+       if (attr == NULL) {
+               ir_mode *mode = get_irn_mode(node);
+               assert(mode_is_int(mode));
+
+               attr = obstack_alloc(&info->obst, sizeof(*attr));
+               memset(attr, 0, sizeof(*attr));
+               attr->range_type   = VRP_UNDEFINED;
+               attr->bits_set     = get_mode_null(mode);
+               attr->bits_not_set = get_mode_all_one(mode);
+               attr->range_bottom = get_tarval_top();
+               attr->range_top    = get_tarval_top();
+
+               ir_nodemap_insert(&info->infos, node, attr);
+       }
+       return attr;
+}
+
+vrp_attr *vrp_get_info(const ir_node *node)
+{
+       ir_graph *irg = get_irn_irg(node);
+       if (irg->vrp.infos.data == NULL)
+               return NULL;
+       return (vrp_attr*) ir_nodemap_get(&irg->vrp.infos, node);
 }
 
-static int vrp_update_node(ir_node *node)
+static int vrp_update_node(ir_vrp_info *info, ir_node *node)
 {
        ir_tarval *new_bits_set = get_tarval_bad();
        ir_tarval *new_bits_not_set = get_tarval_bad();
@@ -67,7 +91,7 @@ static int vrp_update_node(ir_node *node)
                return 0; /* we don't optimize for non-int-nodes*/
        }
 
-       vrp = get_vrp_attr(node);
+       vrp = vrp_get_or_set_info(info, node);
 
        /* TODO: Check if all predecessors have valid VRP information*/
 
@@ -87,8 +111,8 @@ static int vrp_update_node(ir_node *node)
 
                left = get_And_left(node);
                right = get_And_right(node);
-               vrp_left = get_vrp_attr(left);
-               vrp_right = get_vrp_attr(right);
+               vrp_left = vrp_get_or_set_info(info, left);
+               vrp_right = vrp_get_or_set_info(info, right);
                new_bits_set = tarval_and(vrp_left->bits_set, vrp_right->bits_set);
                new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set);
 
@@ -99,8 +123,8 @@ static int vrp_update_node(ir_node *node)
                int overflow_top, overflow_bottom;
                ir_tarval *new_top, *new_bottom;
                const vrp_attr *vrp_left, *vrp_right;
-               vrp_left = get_vrp_attr(get_Add_left(node));
-               vrp_right = get_vrp_attr(get_Add_right(node));
+               vrp_left = vrp_get_or_set_info(info, get_Add_left(node));
+               vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
 
                if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
                                VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
@@ -128,11 +152,17 @@ static int vrp_update_node(ir_node *node)
        }
 
        case iro_Sub: {
+               ir_node *left  = get_Sub_left(node);
+               ir_node *right = get_Sub_right(node);
                int overflow_top, overflow_bottom;
                ir_tarval *new_top, *new_bottom;
                const vrp_attr *vrp_left, *vrp_right;
-               vrp_left = get_vrp_attr(get_Sub_left(node));
-               vrp_right = get_vrp_attr(get_Sub_right(node));
+
+               if (!mode_is_int(get_irn_mode(left)))
+                       return 0;
+
+               vrp_left  = vrp_get_or_set_info(info, left);
+               vrp_right = vrp_get_or_set_info(info, right);
 
                if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
                                VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
@@ -161,8 +191,8 @@ static int vrp_update_node(ir_node *node)
        case iro_Or: {
                const vrp_attr *vrp_left, *vrp_right;
 
-               vrp_left = get_vrp_attr(get_Or_left(node));
-               vrp_right = get_vrp_attr(get_Or_right(node));
+               vrp_left = vrp_get_or_set_info(info, get_Or_left(node));
+               vrp_right = vrp_get_or_set_info(info, get_Or_right(node));
 
                new_bits_set = tarval_or(vrp_left->bits_set, vrp_right->bits_set);
                new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set);
@@ -174,7 +204,7 @@ static int vrp_update_node(ir_node *node)
                const vrp_attr *vrp_left;
                const ir_node *right = get_Rotl_right(node);
 
-               vrp_left = get_vrp_attr(get_Rotl_left(node));
+               vrp_left = vrp_get_or_set_info(info, get_Rotl_left(node));
 
                /* We can only compute this if the right value is a constant*/
                if (is_Const(right)) {
@@ -187,7 +217,7 @@ static int vrp_update_node(ir_node *node)
        case iro_Shl: {
                const vrp_attr *vrp_left;
                const ir_node *right = get_Shl_right(node);
-               vrp_left = get_vrp_attr(get_Shl_left(node));
+               vrp_left = vrp_get_or_set_info(info, get_Shl_left(node));
 
                /* We can only compute this if the right value is a constant*/
                if (is_Const(right)) {
@@ -201,7 +231,7 @@ static int vrp_update_node(ir_node *node)
                const vrp_attr *vrp_left;
                const ir_node *right = get_Shr_right(node);
 
-               vrp_left = get_vrp_attr(get_Shr_left(node));
+               vrp_left = vrp_get_or_set_info(info, get_Shr_left(node));
 
                /* We can only compute this if the right value is a constant*/
                if (is_Const(right)) {
@@ -215,7 +245,7 @@ static int vrp_update_node(ir_node *node)
                const vrp_attr *vrp_left;
                const ir_node *right = get_Shrs_right(node);
 
-               vrp_left = get_vrp_attr(get_Shrs_left(node));
+               vrp_left = vrp_get_or_set_info(info, get_Shrs_left(node));
 
                /* We can only compute this if the right value is a constant*/
                if (is_Const(right)) {
@@ -228,8 +258,8 @@ static int vrp_update_node(ir_node *node)
        case iro_Eor: {
                const vrp_attr *vrp_left, *vrp_right;
 
-               vrp_left = get_vrp_attr(get_Eor_left(node));
-               vrp_right = get_vrp_attr(get_Eor_right(node));
+               vrp_left = vrp_get_or_set_info(info, get_Eor_left(node));
+               vrp_right = vrp_get_or_set_info(info, get_Eor_right(node));
 
                new_bits_set = tarval_or(
                                                tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set)),
@@ -244,7 +274,7 @@ static int vrp_update_node(ir_node *node)
        }
 
        case iro_Id: {
-               const vrp_attr *vrp_pred = get_vrp_attr(get_Id_pred(node));
+               const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Id_pred(node));
                new_bits_set = vrp_pred->bits_set;
                new_bits_not_set = vrp_pred->bits_not_set;
                new_range_top = vrp_pred->range_top;
@@ -254,7 +284,7 @@ static int vrp_update_node(ir_node *node)
        }
 
        case iro_Not: {
-               const vrp_attr *vrp_pred = get_vrp_attr(get_Not_op(node));
+               const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Not_op(node));
                new_bits_set = tarval_not(vrp_pred->bits_not_set);
                new_bits_not_set = tarval_not(vrp_pred->bits_set);
                break;
@@ -263,13 +293,14 @@ static int vrp_update_node(ir_node *node)
        case iro_Conv: {
                const ir_node *pred = get_Conv_op(node);
                ir_mode *old_mode = get_irn_mode(pred);
-               const vrp_attr *vrp_pred = get_vrp_attr(pred);
+               const vrp_attr *vrp_pred;
 
                ir_mode *new_mode;
 
                if (!mode_is_int(old_mode))
                        return 0;
 
+               vrp_pred = vrp_get_or_set_info(info, pred);
                new_mode = get_irn_mode(node);
 
                /* The second and is needed if target type is smaller*/
@@ -320,7 +351,7 @@ static int vrp_update_node(ir_node *node)
                int i;
 
                const ir_node *pred = get_Phi_pred(node,0);
-               const vrp_attr *vrp_pred = get_vrp_attr(pred);
+               const vrp_attr *vrp_pred = vrp_get_or_set_info(info, pred);
                new_range_top = vrp_pred->range_top;
                new_range_bottom = vrp_pred->range_bottom;
                new_range_type = vrp_pred->range_type;
@@ -331,7 +362,7 @@ static int vrp_update_node(ir_node *node)
 
                for (i = 1; i < num; i++) {
                        pred = get_Phi_pred(node, i);
-                       vrp_pred = get_vrp_attr(pred);
+                       vrp_pred = vrp_get_or_set_info(info, pred);
                        if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
                                        VRP_RANGE) {
                                relation = tarval_cmp(new_range_top, vrp_pred->range_top);
@@ -482,7 +513,7 @@ static void vrp_first_pass(ir_node *n, void *e)
 
        bitset_set(env->visited, get_irn_idx(n));
 
-       vrp_update_node(n);
+       vrp_update_node(env->info, n);
 
        assure_irg_outs(get_current_ir_graph());
        for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
@@ -494,70 +525,26 @@ static void vrp_first_pass(ir_node *n, void *e)
        }
 }
 
-static void *vrp_init_node(ir_phase *phase, const ir_node *n)
-{
-       ir_mode *mode;
-       vrp_attr *vrp;
-
-       DBG((dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n)));
-       vrp = (vrp_attr*) phase_alloc(phase, sizeof(vrp_attr));
-
-       memset(vrp, 0, sizeof(vrp_attr));
-       /* Initialize the vrp information to default */
-
-       mode = get_irn_mode(n);
-
-       vrp->range_type = VRP_UNDEFINED;
-
-       /* TODO: We might be able to optimize space usage if we do not allocate
-        * vrp space for non-int nodes. (currently caught by vrp_update_node)
-        */
-       if (mode_is_int(mode)) {
-               /* We are assuming that 0 is always represented as this modes null */
-               vrp->valid = 1;
-               vrp->bits_set = get_mode_null(mode);
-               vrp->bits_not_set = get_mode_all_one(mode);
-               vrp->range_bottom = get_tarval_top();
-               vrp->range_top = get_tarval_top();
-       } else {
-               vrp->valid = 0;
-               vrp->bits_set = get_tarval_bad();
-               vrp->bits_not_set = get_tarval_bad();
-               vrp->range_bottom = get_tarval_bad();
-               vrp->range_top = get_tarval_bad();
-       }
-
-       /* TODO: We might be able to set better vrp info at this time, if this is
-        * a node which is newly created in an already initialized irg
-        *
-        * maybe just call vrp_update_node and if it returns one, iterate over
-        * successors
-        */
-       return vrp;
-}
-
 void set_vrp_data(ir_graph *irg)
 {
        ir_node *succ, *node;
        int i;
        vrp_env_t *env;
-       ir_phase *phase;
+       ir_vrp_info *info;
+
+       if (irg->vrp.infos.data != NULL)
+               free_vrp_data(irg);
 
        FIRM_DBG_REGISTER(dbg, "ir.ana.vrp");
 
        assure_irg_outs(irg); /* ensure that out edges are consistent*/
-       phase = irg_get_phase(irg, PHASE_VRP);
-       if (phase == NULL) {
-               /* this is our first run */
-               phase = new_phase(irg, vrp_init_node);
-               irg_register_phase(irg, PHASE_VRP, phase);
-               env = (vrp_env_t*) phase_alloc(phase, sizeof(*env));
-               phase->priv = env;
-       } else {
-               env = (vrp_env_t*) phase->priv;
-       }
+       ir_nodemap_init(&irg->vrp.infos, irg);
+       obstack_init(&irg->vrp.obst);
+       info = &irg->vrp;
 
+       env = obstack_alloc(&irg->vrp.obst, sizeof(*env));
        env->workqueue = new_waitq();
+       env->info      = info;
 
        env->visited = bitset_malloc(get_irg_last_idx(irg));
        irg_walk_graph(irg, NULL, vrp_first_pass, env);
@@ -567,7 +554,7 @@ void set_vrp_data(ir_graph *irg)
        while (!waitq_empty(env->workqueue)) {
                node = (ir_node*) waitq_get(env->workqueue);
 
-               if (vrp_update_node(node)) {
+               if (vrp_update_node(info, node)) {
                        /* if something changed, add successors to worklist*/
                        for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
                                succ =  get_irn_out(node, i);
@@ -578,6 +565,14 @@ void set_vrp_data(ir_graph *irg)
        del_waitq(env->workqueue);
 }
 
+void free_vrp_data(ir_graph *irg)
+{
+       if (irg->vrp.infos.data == NULL)
+               return;
+       obstack_free(&irg->vrp.obst, NULL);
+       ir_nodemap_destroy(&irg->vrp.infos);
+}
+
 ir_graph_pass_t *set_vrp_pass(const char *name)
 {
        return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
@@ -587,6 +582,9 @@ ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
 {
        vrp_attr *vrp_left, *vrp_right;
 
+       if (!mode_is_int(get_irn_mode(left)))
+               return ir_relation_true;
+
        vrp_left = vrp_get_info(left);
        vrp_right = vrp_get_info(right);
 
@@ -610,22 +608,3 @@ ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
        /* TODO: We can get way more information here*/
        return ir_relation_true;
 }
-
-vrp_attr *vrp_get_info(const ir_node *node)
-{
-       const ir_graph *irg   = get_irn_irg(node);
-       const ir_phase *phase = irg_get_phase(irg, PHASE_VRP);
-       vrp_attr       *vrp;
-
-       if (phase == NULL) {
-               /* phase has not yet been initialized */
-               return NULL;
-       }
-
-       vrp = (vrp_attr*) phase_get_irn_data(phase, node);
-       if (vrp && vrp->valid) {
-               return vrp;
-       }
-
-       return NULL;
-}
index b957609..4999cf9 100644 (file)
@@ -33,7 +33,8 @@
 #include "ircons.h"
 #include "iredges.h"
 #include "irgwalk.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
+#include "irtools.h"
 #include "heights.h"
 
 /**
@@ -599,11 +600,11 @@ static int cmp_call_dependency(const void *c1, const void *c2)
  */
 static void process_ops_in_block(ir_node *block, void *data)
 {
-       ir_phase *phase = (ir_phase*)data;
-       unsigned  n;
-       unsigned  n_nodes;
-       ir_node  *node;
-       ir_node **nodes;
+       ir_nodemap *map = (ir_nodemap*)data;
+       unsigned    n;
+       unsigned    n_nodes;
+       ir_node    *node;
+       ir_node   **nodes;
 
        n_nodes = 0;
        for (node = (ir_node*)get_irn_link(block); node != NULL;
@@ -630,7 +631,7 @@ static void process_ops_in_block(ir_node *block, void *data)
                ir_node *node = nodes[n];
                ir_node *pred = nodes[n-1];
 
-               phase_set_irn_data(phase, node, pred);
+               ir_nodemap_insert(map, node, pred);
        }
        xfree(nodes);
 }
@@ -638,7 +639,7 @@ static void process_ops_in_block(ir_node *block, void *data)
 
 
 struct be_stackorder_t {
-       ir_phase *stack_order; /**< a phase to handle stack dependencies. */
+       ir_nodemap stack_order; /**< a phase to handle stack dependencies. */
 };
 
 be_stackorder_t *be_collect_stacknodes(ir_graph *irg)
@@ -650,13 +651,12 @@ be_stackorder_t *be_collect_stacknodes(ir_graph *irg)
        /* collect all potential^stack accessing nodes */
        irg_walk_graph(irg, firm_clear_link, link_ops_in_block_walker, NULL);
 
-       assert(env->stack_order == NULL);
-       env->stack_order = new_phase(irg, phase_irn_init_default);
+       ir_nodemap_init(&env->stack_order, irg);
 
        /* use heights to create a total order for those nodes: this order is stored
         * in the created phase */
        heights = heights_new(irg);
-       irg_block_walk_graph(irg, NULL, process_ops_in_block, env->stack_order);
+       irg_block_walk_graph(irg, NULL, process_ops_in_block, &env->stack_order);
        heights_free(heights);
 
        ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
@@ -666,12 +666,12 @@ be_stackorder_t *be_collect_stacknodes(ir_graph *irg)
 
 ir_node *be_get_stack_pred(const be_stackorder_t *env, const ir_node *node)
 {
-       return (ir_node*)phase_get_irn_data(env->stack_order, node);
+       return (ir_node*)ir_nodemap_get(&env->stack_order, node);
 }
 
 void be_free_stackorder(be_stackorder_t *env)
 {
-       phase_free(env->stack_order);
+       ir_nodemap_destroy(&env->stack_order);
        free(env);
 }
 
index 6bb00d0..eda8931 100644 (file)
 #include "debug.h"
 #include "bitfiddle.h"
 
-#include "irphase_t.h"
 #include "irgraph_t.h"
 #include "irnode_t.h"
 #include "irprintf.h"
 #include "irtools.h"
+#include "irnodemap.h"
 
 #include "bemodule.h"
 #include "beabi.h"
@@ -107,7 +107,8 @@ typedef struct {
 } col_cost_pair_t;
 
 typedef struct {
-       ir_phase     ph;
+       ir_nodemap     map;
+       struct obstack obst;
        copy_opt_t *co;
        bitset_t   *allocatable_regs;
        co2_irn_t  *touched;
@@ -175,30 +176,42 @@ typedef struct {
 
 #define FRONT_BASE(ci,col)  ((ci)->fronts + col * (ci)->mst_n_childs)
 
-#define get_co2_irn(co2, irn)         ((co2_irn_t *)       phase_get_or_set_irn_data(&co2->ph, irn))
-#define get_co2_cloud_irn(co2, irn)   ((co2_cloud_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
+static co2_irn_t *get_co2_irn(co2_t *env, const ir_node *node)
+{
+       co2_irn_t *ci = ir_nodemap_get(&env->map, node);
+       if (ci == NULL) {
+               ci = OALLOCZ(&env->obst, co2_irn_t);
+
+               INIT_LIST_HEAD(&ci->changed_list);
+               ci->touched_next = env->touched;
+               ci->orig_col     = get_irn_col(node);
+               env->touched     = ci;
+               ci->irn          = node;
+               ci->aff          = NULL;
+
+               ir_nodemap_insert(&env->map, node, ci);
+       }
+       return ci;
+}
 
-static void *co2_irn_init(ir_phase *ph, const ir_node *irn)
+static co2_cloud_irn_t *get_co2_cloud_irn(co2_t *env, const ir_node *node)
 {
-       co2_t *env         = (co2_t *) ph;
-       affinity_node_t *a = get_affinity_info(env->co, irn);
-       size_t size        = a ? sizeof(co2_cloud_irn_t) : sizeof(co2_irn_t);
-       co2_irn_t *ci      = (co2_irn_t*)phase_alloc(ph, size);
-
-       memset(ci, 0, size);
-       INIT_LIST_HEAD(&ci->changed_list);
-       ci->touched_next = env->touched;
-       ci->orig_col     = get_irn_col(irn);
-       env->touched     = ci;
-       ci->irn          = irn;
-       ci->aff          = a;
+       co2_cloud_irn_t *ci = ir_nodemap_get(&env->map, node);
+       if (ci == NULL) {
+               ci = OALLOCZ(&env->obst, co2_cloud_irn_t);
 
-       if (a) {
-               co2_cloud_irn_t *cci = (co2_cloud_irn_t *) ci;
-               INIT_LIST_HEAD(&cci->cloud_list);
-               cci->mst_parent   = cci;
-       }
+               INIT_LIST_HEAD(&ci->inh.changed_list);
+               ci->inh.touched_next = env->touched;
+               ci->inh.orig_col     = get_irn_col(node);
+               env->touched         = &ci->inh;
+               ci->inh.irn          = node;
+               ci->inh.aff          = get_affinity_info(env->co, node);
 
+               INIT_LIST_HEAD(&ci->cloud_list);
+               ci->mst_parent = ci;
+
+               ir_nodemap_insert(&env->map, node, ci);
+       }
        return ci;
 }
 
@@ -249,7 +262,7 @@ static inline bitset_t *get_adm(co2_t *env, co2_irn_t *ci)
 {
        if (ci->adm_cache == NULL) {
                const arch_register_req_t *req;
-               ci->adm_cache = bitset_obstack_alloc(phase_obst(&env->ph), env->n_regs);
+               ci->adm_cache = bitset_obstack_alloc(&env->obst, env->n_regs);
                req = arch_get_irn_register_req(ci->irn);
 
                if (arch_register_req_is(req, limited)) {
@@ -810,7 +823,7 @@ static void populate_cloud(co2_t *env, co2_cloud_t *cloud, affinity_node_t *a, i
 
 static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
 {
-       co2_cloud_t *cloud = (co2_cloud_t*)phase_alloc(&env->ph, sizeof(cloud[0]));
+       co2_cloud_t *cloud = OALLOC(&env->obst, co2_cloud_t);
        co2_cloud_irn_t *ci;
        int i;
 
@@ -826,7 +839,7 @@ static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
        cloud->freedom = (cloud->n_memb * env->n_regs) / cloud->freedom;
 
        /* Also allocate space for the node sequence and compute that sequence. */
-       cloud->seq = (co2_cloud_irn_t**)phase_alloc(&env->ph, cloud->n_memb * sizeof(cloud->seq[0]));
+       cloud->seq = OALLOCN(&env->obst, co2_cloud_irn_t*, cloud->n_memb);
 
        i = 0;
        list_for_each_entry(co2_cloud_irn_t, ci, &cloud->members_head, cloud_list) {
@@ -1222,7 +1235,8 @@ int co_solve_heuristic_new(copy_opt_t *co)
        co2_t env;
        FILE  *f;
 
-       phase_init(&env.ph, co->cenv->irg, co2_irn_init);
+       ir_nodemap_init(&env.map, co->irg);
+       obstack_init(&env.obst);
        env.touched     = NULL;
        env.visited     = 0;
        env.co          = co;
@@ -1253,7 +1267,8 @@ int co_solve_heuristic_new(copy_opt_t *co)
        }
 
        writeback_colors(&env);
-       phase_deinit(&env.ph);
+       obstack_free(&env.obst, NULL);
+       ir_nodemap_destroy(&env.map);
        return 0;
 }
 
index bac5a04..bb3319e 100644 (file)
 #include "irnode_t.h"
 #include "bitset.h"
 #include "raw_bitset.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 #include "pqueue.h"
 #include "xmalloc.h"
 #include "pdeq.h"
 #include "irprintf.h"
 #include "irbitset.h"
+#include "irtools.h"
 #include "error.h"
 #include "list.h"
 #include "statev.h"
@@ -118,7 +119,8 @@ typedef struct co_mst_env_t {
        int              n_regs;         /**< number of regs in class */
        int              k;              /**< number of non-ignore registers in class */
        bitset_t         *allocatable_regs; /**< set containing all global ignore registers */
-       ir_phase         ph;             /**< phase object holding data for nodes */
+       ir_nodemap        map;           /**< phase object holding data for nodes */
+       struct obstack    obst;
        pqueue_t         *chunks;        /**< priority queue for chunks */
        list_head         chunklist;     /**< list holding all chunks */
        be_ifg_t         *ifg;           /**< the interference graph */
@@ -143,9 +145,71 @@ typedef struct co_mst_irn_t {
        real_t           constr_factor;
 } co_mst_irn_t;
 
+/**
+ * In case there is no phase information for irn, initialize it.
+ */
+static co_mst_irn_t *co_mst_irn_init(co_mst_env_t *env, const ir_node *irn)
+{
+       co_mst_irn_t *res = OALLOC(&env->obst, co_mst_irn_t);
+
+       const arch_register_req_t *req;
+       neighbours_iter_t nodes_it;
+       ir_node  *neigh;
+       unsigned len;
+
+       res->irn           = irn;
+       res->chunk         = NULL;
+       res->fixed         = 0;
+       res->tmp_col       = -1;
+       res->int_neighs    = NULL;
+       res->int_aff_neigh = 0;
+       res->col           = arch_register_get_index(arch_get_irn_register(irn));
+       res->init_col      = res->col;
+       INIT_LIST_HEAD(&res->list);
+
+       DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
+
+       /* set admissible registers */
+       res->adm_colors = bitset_obstack_alloc(&env->obst, env->n_regs);
+
+       /* Exclude colors not assignable to the irn */
+       req = arch_get_irn_register_req(irn);
+       if (arch_register_req_is(req, limited)) {
+               rbitset_copy_to_bitset(req->limited, res->adm_colors);
+       } else {
+               bitset_set_all(res->adm_colors);
+       }
+
+       /* exclude global ignore registers as well */
+       bitset_and(res->adm_colors, env->allocatable_regs);
+
+       /* compute the constraint factor */
+       res->constr_factor = (real_t) (1 + env->n_regs - bitset_popcount(res->adm_colors)) / env->n_regs;
+
+       /* set the number of interfering affinity neighbours to -1, they are calculated later */
+       res->int_aff_neigh = -1;
+
+       /* build list of interfering neighbours */
+       len = 0;
+       be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
+               if (!arch_irn_is_ignore(neigh)) {
+                       obstack_ptr_grow(&env->obst, neigh);
+                       ++len;
+               }
+       }
+       res->int_neighs = (ir_node**)obstack_finish(&env->obst);
+       res->n_neighs   = len;
+       return res;
+}
+
 static co_mst_irn_t *get_co_mst_irn(co_mst_env_t *env, const ir_node *node)
 {
-       return (co_mst_irn_t*)phase_get_or_set_irn_data(&env->ph, node);
+       co_mst_irn_t *res = (co_mst_irn_t*)ir_nodemap_get(&env->map, node);
+       if (res == NULL) {
+               res = co_mst_irn_init(env, node);
+               ir_nodemap_insert(&env->map, node, res);
+       }
+       return res;
 }
 
 typedef int decide_func_t(const co_mst_irn_t *node, int col);
@@ -372,63 +436,6 @@ static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
        }
 }
 
-/**
- * In case there is no phase information for irn, initialize it.
- */
-static void *co_mst_irn_init(ir_phase *ph, const ir_node *irn)
-{
-       co_mst_irn_t *res = (co_mst_irn_t*)phase_alloc(ph, sizeof(res[0]));
-       co_mst_env_t *env = (co_mst_env_t*)ph->priv;
-
-       const arch_register_req_t *req;
-       neighbours_iter_t nodes_it;
-       ir_node  *neigh;
-       unsigned len;
-
-       res->irn           = irn;
-       res->chunk         = NULL;
-       res->fixed         = 0;
-       res->tmp_col       = -1;
-       res->int_neighs    = NULL;
-       res->int_aff_neigh = 0;
-       res->col           = arch_register_get_index(arch_get_irn_register(irn));
-       res->init_col      = res->col;
-       INIT_LIST_HEAD(&res->list);
-
-       DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
-
-       /* set admissible registers */
-       res->adm_colors = bitset_obstack_alloc(phase_obst(ph), env->n_regs);
-
-       /* Exclude colors not assignable to the irn */
-       req = arch_get_irn_register_req(irn);
-       if (arch_register_req_is(req, limited))
-               rbitset_copy_to_bitset(req->limited, res->adm_colors);
-       else
-               bitset_set_all(res->adm_colors);
-
-       /* exclude global ignore registers as well */
-       bitset_and(res->adm_colors, env->allocatable_regs);
-
-       /* compute the constraint factor */
-       res->constr_factor = (real_t) (1 + env->n_regs - bitset_popcount(res->adm_colors)) / env->n_regs;
-
-       /* set the number of interfering affinity neighbours to -1, they are calculated later */
-       res->int_aff_neigh = -1;
-
-       /* build list of interfering neighbours */
-       len = 0;
-       be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
-               if (!arch_irn_is_ignore(neigh)) {
-                       obstack_ptr_grow(phase_obst(ph), neigh);
-                       ++len;
-               }
-       }
-       res->int_neighs = (ir_node**)obstack_finish(phase_obst(ph));
-       res->n_neighs   = len;
-       return res;
-}
-
 /**
  * Check if affinity chunk @p chunk interferes with node @p irn.
  */
@@ -641,6 +648,7 @@ static void build_affinity_chunks(co_mst_env_t *env)
        ir_node     *n;
        int         i, len;
        aff_chunk_t *curr_chunk;
+       size_t      pn;
 
        /* at first we create the affinity edge objects */
        be_ifg_foreach_node(env->ifg, &nodes_it, n) {
@@ -713,22 +721,24 @@ static void build_affinity_chunks(co_mst_env_t *env)
                pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
        }
 
-       foreach_phase_irn(&env->ph, n) {
-               co_mst_irn_t *mirn = get_co_mst_irn(env, n);
+       for (pn = 0; pn < ARR_LEN(env->map.data); ++pn) {
+               co_mst_irn_t *mirn = env->map.data[pn];
+               if (mirn == NULL)
+                       continue;
+               if (mirn->chunk != NULL)
+                       continue;
 
-               if (mirn->chunk == NULL) {
-                       /* no chunk is allocated so far, do it now */
-                       aff_chunk_t *curr_chunk = new_aff_chunk(env);
-                       aff_chunk_add_node(curr_chunk, mirn);
+               /* no chunk is allocated so far, do it now */
+               aff_chunk_t *curr_chunk = new_aff_chunk(env);
+               aff_chunk_add_node(curr_chunk, mirn);
 
-                       aff_chunk_assure_weight(env, curr_chunk);
+               aff_chunk_assure_weight(env, curr_chunk);
 
-                       DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
-                       DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
-                       DBG((dbg, LEVEL_1, "\n"));
+               DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
+               DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
+               DBG((dbg, LEVEL_1, "\n"));
 
-                       pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
-               }
+               pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
        }
 
        DEL_ARR_F(edges);
@@ -1427,6 +1437,7 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
        bitset_t     *allocatable_regs = bitset_alloca(n_regs);
        unsigned     i, j;
        size_t       k;
+       size_t       pn;
        ir_node      *irn;
        co_mst_env_t mst_env;
 
@@ -1435,8 +1446,8 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
        stat_ev_tim_push();
 
        /* init phase */
-       phase_init(&mst_env.ph, co->irg, co_mst_irn_init);
-       phase_set_private(&mst_env.ph, &mst_env);
+       ir_nodemap_init(&mst_env.map, co->irg);
+       obstack_init(&mst_env.obst);
 
        be_put_allocatable_regs(co->cenv->irg, co->cls, allocatable_regs);
        k = bitset_popcount(allocatable_regs);
@@ -1449,10 +1460,10 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
        mst_env.ifg              = co->cenv->ifg;
        INIT_LIST_HEAD(&mst_env.chunklist);
        mst_env.chunk_visited    = 0;
-       mst_env.single_cols      = (col_cost_t**)phase_alloc(&mst_env.ph, sizeof(*mst_env.single_cols) * n_regs);
+       mst_env.single_cols      = OALLOCN(&mst_env.obst, col_cost_t*, n_regs);
 
        for (i = 0; i < n_regs; ++i) {
-               col_cost_t *vec = (col_cost_t*)phase_alloc(&mst_env.ph, sizeof(*vec) * n_regs);
+               col_cost_t *vec = OALLOCN(&mst_env.obst, col_cost_t, n_regs);
 
                mst_env.single_cols[i] = vec;
                for (j = 0; j < n_regs; ++j) {
@@ -1481,16 +1492,15 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
        }
 
        /* apply coloring */
-       foreach_phase_irn(&mst_env.ph, irn) {
-               co_mst_irn_t          *mirn;
+       for (pn = 0; pn < ARR_LEN(mst_env.map.data); ++pn) {
+               co_mst_irn_t *mirn = mst_env.map.data[pn];
                const arch_register_t *reg;
-
+               if (mirn == NULL)
+                       continue;
+               irn = get_idx_irn(co->irg, pn);
                if (arch_irn_is_ignore(irn))
                        continue;
 
-               mirn = get_co_mst_irn(&mst_env, irn);
-               // assert(mirn->fixed && "Node should have fixed color");
-
                /* skip nodes where color hasn't changed */
                if (mirn->init_col == mirn->col)
                        continue;
@@ -1502,7 +1512,8 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
 
        /* free allocated memory */
        del_pqueue(mst_env.chunks);
-       phase_deinit(&mst_env.ph);
+       obstack_free(&mst_env.obst, NULL);
+       ir_nodemap_destroy(&mst_env.map);
 
        stat_ev_tim_pop("heur4_total");
 
index f90ec70..23064ac 100644 (file)
@@ -43,8 +43,8 @@
 #include "irloop_t.h"
 #include "iredges_t.h"
 #include "irbitset.h"
-#include "irphase_t.h"
 #include "irprintf_t.h"
+#include "irtools.h"
 
 #include "bemodule.h"
 #include "bearch.h"
index 50867f9..3ae28d7 100644 (file)
@@ -39,7 +39,6 @@
 #include "irtools.h"
 #include "irbitset.h"
 #include "beifg.h"
-#include "irphase_t.h"
 #include "error.h"
 #include "xmalloc.h"
 
index 9961b6e..1084fbc 100644 (file)
@@ -13,7 +13,6 @@
 #define _BELIVECHK_T_H
 
 #include "irgraph_t.h"
-#include "irphase_t.h"
 #include "iredges_t.h"
 
 #include "statev.h"
index 0595e2c..a610bd2 100644 (file)
@@ -69,7 +69,6 @@
 
 #include "ircons.h"
 #include "iredges_t.h"
-#include "irphase_t.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
@@ -77,9 +76,9 @@ static ir_node *search_def_end_of_block(be_ssa_construction_env_t *env,
                                         ir_node *block);
 
 struct constr_info {
-       bool is_definition;
-       bool is_use;
-       bool already_processed;
+       bool is_definition     : 1;
+       bool is_use            : 1;
+       bool already_processed : 1;
        union {
                /* Since we only consider scheduled nodes,
                 * this points to the real definition (e.g. a Proj). */
@@ -95,41 +94,53 @@ typedef struct constr_info constr_info;
 /**
  * @return Whether the block contains a definition.
  */
-static inline bool has_definition(be_ssa_construction_env_t *env, ir_node *block)
+static bool has_definition(const ir_node *block)
 {
-       (void)env;
-
        return irn_visited(block);
 }
 
+static constr_info *get_or_set_info(be_ssa_construction_env_t *env,
+                                    const ir_node *node)
+{
+       constr_info *info = ir_nodemap_get(&env->infos, node);
+       if (info == NULL) {
+               info = OALLOCZ(&env->obst, constr_info);
+               ir_nodemap_insert(&env->infos, node, info);
+       }
+       return info;
+}
+
+static constr_info *get_info(const be_ssa_construction_env_t *env,
+                             const ir_node *node)
+{
+       return (constr_info*)ir_nodemap_get(&env->infos, node);
+}
+
 /**
  * @return Whether the block contains a use.
  */
 static inline bool has_use(be_ssa_construction_env_t *env, ir_node *block)
 {
-       constr_info *info = phase_get_or_set_irn_data(env->phase, block);
-
+       constr_info *info = get_or_set_info(env, block);
        return info->is_use;
 }
 
 /**
  * @return Whether the node is a definition.
  */
-static inline bool is_definition(be_ssa_construction_env_t *env, ir_node *node)
+static bool is_definition(be_ssa_construction_env_t *env, ir_node *node)
 {
-       constr_info *info = phase_get_irn_data(env->phase, node);
-
-       return info && info->is_definition;
+       constr_info *info = get_info(env, node);
+       return info != NULL && info->is_definition;
 }
 
 /**
  * @return Whether the node is a use.
  */
-static inline bool is_use(const be_ssa_construction_env_t *env, ir_node *node)
+static bool is_use(const be_ssa_construction_env_t *env, ir_node *node)
 {
-       constr_info *info = phase_get_irn_data(env->phase, node);
-
-       return info && info->is_use;
+       constr_info *info = get_info(env, node);
+       return info != NULL && info->is_use;
 }
 
 /**
@@ -138,11 +149,10 @@ static inline bool is_use(const be_ssa_construction_env_t *env, ir_node *node)
 static void introduce_definition(be_ssa_construction_env_t *env, ir_node *def)
 {
        ir_node     *block      = get_nodes_block(def);
-       ir_phase    *phase      = env->phase;
-       constr_info *def_info   = phase_get_or_set_irn_data(phase, def);
+       constr_info *def_info   = get_or_set_info(env, def);
        ir_node     *skip       = skip_Proj(def);
-       constr_info *skip_info  = phase_get_or_set_irn_data(phase, skip);
-       constr_info *block_info = phase_get_or_set_irn_data(phase, block);
+       constr_info *skip_info  = get_or_set_info(env, skip);
+       constr_info *block_info = get_or_set_info(env, block);
 
        DBG((dbg, LEVEL_2, "\tintroducing definition %+F in %+F\n", def, block));
 
@@ -152,11 +162,10 @@ static void introduce_definition(be_ssa_construction_env_t *env, ir_node *def)
        skip_info->definition    = def;
 
        // Set the last definition if we only introduce one definition for the block
-       if (has_definition(env, block)) {
+       if (has_definition(block)) {
                assert(!block_info->already_processed);
                block_info->last_definition = NULL;
-       }
-       else {
+       } else {
                mark_irn_visited(block);
                block_info->last_definition = def;
        }
@@ -165,9 +174,8 @@ static void introduce_definition(be_ssa_construction_env_t *env, ir_node *def)
 static void introduce_use(be_ssa_construction_env_t *env, ir_node *use)
 {
        ir_node     *block      = get_nodes_block(use);
-       ir_phase    *phase      = env->phase;
-       constr_info *info       = phase_get_or_set_irn_data(phase, use);
-       constr_info *block_info = phase_get_or_set_irn_data(phase, block);
+       constr_info *info       = get_or_set_info(env, use);
+       constr_info *block_info = get_or_set_info(env, block);
 
        DBG((dbg, LEVEL_2, "\tintroducing use %+F in %+F\n", use, block));
 
@@ -183,7 +191,7 @@ static void introduce_use(be_ssa_construction_env_t *env, ir_node *use)
  * frontier to the block itself.
  */
 static void mark_iterated_dominance_frontiers(
-               const be_ssa_construction_env_t *env)
+                                           const be_ssa_construction_env_t *env)
 {
        stat_ev_cnt_decl(blocks);
        DBG((dbg, LEVEL_3, "Dominance Frontier:"));
@@ -269,7 +277,7 @@ static ir_node *get_def_at_idom(be_ssa_construction_env_t *env, ir_node *block)
  */
 static void set_operands(be_ssa_construction_env_t *env, ir_node *use, ir_node *def)
 {
-       constr_info *info  = phase_get_irn_data(env->phase, use);
+       constr_info *info  = get_info(env, use);
        int          arity = get_irn_arity(use);
        int          i;
 
@@ -292,9 +300,9 @@ static void process_block(be_ssa_construction_env_t *env, ir_node *block)
 {
        ir_node     *node;
        ir_node     *def        = NULL;
-       constr_info *block_info = phase_get_or_set_irn_data(env->phase, block);
+       constr_info *block_info = get_or_set_info(env, block);
 
-       assert(has_definition(env, block));
+       assert(has_definition(block));
        assert(!block_info->already_processed && "Block already processed");
 
        DBG((dbg, LEVEL_3, "\tprocessing block  %+F\n", block));
@@ -317,7 +325,7 @@ static void process_block(be_ssa_construction_env_t *env, ir_node *block)
                }
 
                if (is_definition(env, node)) {
-                       constr_info *info = phase_get_irn_data(env->phase, node);
+                       constr_info *info = get_info(env, node);
                        def = info->definition;
                        DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
                }
@@ -333,13 +341,13 @@ static void process_block(be_ssa_construction_env_t *env, ir_node *block)
 static ir_node *search_def_end_of_block(be_ssa_construction_env_t *env,
                                         ir_node *block)
 {
-       constr_info *block_info      = phase_get_or_set_irn_data(env->phase, block);
+       constr_info *block_info      = get_or_set_info(env, block);
        ir_node     *last_definition = block_info->last_definition;
 
        if (last_definition != NULL)
                return last_definition;
 
-       if (has_definition(env, block)) {
+       if (has_definition(block)) {
                if (has_use(env, block)) {
                        if (!block_info->already_processed) {
                                process_block(env, block);
@@ -351,7 +359,7 @@ static ir_node *search_def_end_of_block(be_ssa_construction_env_t *env,
                        /* Search the last definition of the block. */
                        sched_foreach_reverse(block, def) {
                                if (is_definition(env, def)) {
-                                       constr_info *info = phase_get_irn_data(env->phase, def);
+                                       constr_info *info = get_info(env, def);
                                        def = info->definition;
                                        DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
 
@@ -386,12 +394,12 @@ static ir_node *search_def_end_of_block(be_ssa_construction_env_t *env,
 static void search_def_at_block(be_ssa_construction_env_t *env, ir_node *use)
 {
        ir_node     *block      = get_nodes_block(use);
-       constr_info *block_info = phase_get_or_set_irn_data(env->phase, block);
+       constr_info *block_info = get_or_set_info(env, block);
 
        if (block_info->already_processed)
                return;
 
-       if (has_definition(env, block)) {
+       if (has_definition(block)) {
                process_block(env, block);
        } else if (Block_block_visited(block)) {
                ir_node *phi = insert_dummy_phi(env, block);
@@ -404,19 +412,6 @@ static void search_def_at_block(be_ssa_construction_env_t *env, ir_node *use)
        }
 }
 
-static void *init_constr_info(ir_phase *phase, const ir_node *node)
-{
-       constr_info *info = phase_alloc(phase, sizeof(constr_info));
-       (void)node;
-
-       info->is_definition     = false;
-       info->is_use            = false;
-       info->already_processed = false;
-       info->definition        = NULL;
-
-       return info;
-}
-
 void be_ssa_construction_init(be_ssa_construction_env_t *env, ir_graph *irg)
 {
        ir_node *sb   = get_irg_start_block(irg);
@@ -435,7 +430,8 @@ void be_ssa_construction_init(be_ssa_construction_env_t *env, ir_graph *irg)
        env->domfronts = be_get_irg_dom_front(irg);
        env->new_phis  = NEW_ARR_F(ir_node*, 0);
        env->worklist  = new_waitq();
-       env->phase     = new_phase(irg, init_constr_info);
+       ir_nodemap_init(&env->infos, irg);
+       obstack_init(&env->obst);
 
        ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED
                        | IR_RESOURCE_BLOCK_VISITED | IR_RESOURCE_IRN_LINK);
@@ -451,7 +447,8 @@ void be_ssa_construction_init(be_ssa_construction_env_t *env, ir_graph *irg)
 void be_ssa_construction_destroy(be_ssa_construction_env_t *env)
 {
        stat_ev_int("bessaconstr_phis", ARR_LEN(env->new_phis));
-       phase_free(env->phase);
+       obstack_free(&env->obst, NULL);
+       ir_nodemap_destroy(&env->infos);
        del_waitq(env->worklist);
        DEL_ARR_F(env->new_phis);
 
@@ -478,7 +475,7 @@ void be_ssa_construction_add_copy(be_ssa_construction_env_t *env,
 
        block = get_nodes_block(copy);
 
-       if (!has_definition(env, block)) {
+       if (!has_definition(block)) {
                waitq_put(env->worklist, block);
        }
        introduce_definition(env, copy);
@@ -501,7 +498,7 @@ void be_ssa_construction_add_copies(be_ssa_construction_env_t *env,
                ir_node *block = get_nodes_block(copy);
 
                assert(env->mode == get_irn_mode(copy));
-               if (!has_definition(env, block)) {
+               if (!has_definition(block)) {
                        waitq_put(env->worklist, block);
                }
                introduce_definition(env, copy);
@@ -526,7 +523,7 @@ ir_node **be_ssa_construction_get_new_phis(be_ssa_construction_env_t *env)
  */
 static void fix_phi_arguments(be_ssa_construction_env_t *env, ir_node *phi)
 {
-       constr_info *info    = phase_get_irn_data(env->phase, phi);
+       constr_info *info    = get_info(env, phi);
        ir_node     *block   = get_nodes_block(phi);
        int          i;
        int          n_preds = get_Block_n_cfgpreds(block);
@@ -591,7 +588,7 @@ void be_ssa_construction_fix_users_array(be_ssa_construction_env_t *env,
 
        while (!waitq_empty(env->worklist)) {
                ir_node     *use  = (ir_node *)waitq_get(env->worklist);
-               constr_info *info = phase_get_irn_data(env->phase, use);
+               constr_info *info = get_info(env, use);
 
                if (info->already_processed)
                        continue;
index f65cdfc..df0a3eb 100644 (file)
@@ -56,7 +56,8 @@
 #include "bitset.h"
 #include "beirg.h"
 #include "pdeq.h"
-#include "irphase.h"
+#include "irnodemap.h"
+#include "obst.h"
 
 typedef struct be_ssa_construction_env_t {
        ir_graph                    *irg;
@@ -67,7 +68,8 @@ typedef struct be_ssa_construction_env_t {
        const ir_nodeset_t          *ignore_uses;
        ir_node                    **new_phis;
        int                          iterated_domfront_calculated;
-       ir_phase                    *phase;
+       ir_nodemap                   infos;
+       struct obstack               obst;
 } be_ssa_construction_env_t;
 
 /**
index 678f361..52a5a95 100644 (file)
@@ -399,10 +399,7 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func)
        irg->obst = new_obst;
        irg->last_node_idx = 0;
 
-       /* invalidate phase info as (at least vrp info) is used inside the
-        * equivalent/compute_value functions and might replace our newly
-        * created nodes with middleend nodes */
-       irg_invalidate_phases(irg);
+       free_vrp_data(irg);
 
        /* create new value table for CSE */
        new_identities(irg);
index 729eca7..df1b36a 100644 (file)
@@ -46,7 +46,6 @@
 #include "iredges_t.h"
 #include "type_t.h"
 #include "irmemory.h"
-#include "irphase.h"
 
 #define INITIAL_IDX_IRN_MAP_SIZE 1024
 
@@ -782,26 +781,6 @@ void *get_irg_loc_description(ir_graph *irg, int n)
        return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
 }
 
-void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase)
-{
-       assert(id <= PHASE_LAST);
-       assert(irg->phases[id] == NULL);
-       irg->phases[id] = phase;
-}
-
-void irg_invalidate_phases(ir_graph *irg)
-{
-       int p;
-       for (p = 0; p <= PHASE_LAST; ++p) {
-               ir_phase *phase = irg->phases[p];
-               if (phase == NULL)
-                       continue;
-
-               phase_free(phase);
-               irg->phases[p] = NULL;
-       }
-}
-
 #ifndef NDEBUG
 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
 {
index 8b294e3..5454747 100644 (file)
@@ -423,32 +423,6 @@ static inline void set_irg_anchor(ir_graph *irg, int idx, ir_node *irn)
 }
 
 
-
-/**
- * Register a phase on an irg.
- * The phase will then be managed by the irg. This means you can easily
- * access the phase when you only have a graph handle, the memory will be
- * freed when the graph is freed and some care is taken that the phase data
- * will be invalidated/preserved on events like dead code elemination and
- * code selection.
- */
-void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase);
-
-/**
- * Frees all phase infos attached to an irg
- */
-void irg_invalidate_phases(ir_graph *irg);
-
-/**
- * return phase with given id
- */
-static inline ir_phase *irg_get_phase(const ir_graph *irg, ir_phase_id id)
-{
-       assert(id <= PHASE_LAST);
-       return irg->phases[id];
-}
-
-
 #define is_ir_graph(thing)                    _is_ir_graph(thing)
 #define get_irg_start_block(irg)              _get_irg_start_block(irg)
 #define set_irg_start_block(irg, node)        _set_irg_start_block(irg, node)
diff --git a/ir/ir/irnodemap.h b/ir/ir/irnodemap.h
new file mode 100644 (file)
index 0000000..e4ccbac
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * 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   A nodemap. This variant is a thin wrapper around an ARR_F which
+ *          uses node-indices for access. It is preferable over ir_nodehashmap
+ *          if the info is dense (i.e. something is mapped for most nodes in
+ *          the graph)
+ * @author  Matthias Braun
+ */
+#ifndef FIRM_IRNODEMAP_H
+#define FIRM_IRNODEMAP_H
+
+#include "firm_types.h"
+#include "irgraph_t.h"
+#include "array.h"
+
+typedef struct ir_nodemap ir_nodemap;
+
+/**
+ * Allocate and initialize a new nodemap object
+ *
+ * @param irg           The graph the nodemap will run on.
+ * @return              A new nodemap object.
+ */
+static inline void ir_nodemap_init(ir_nodemap *nodemap, const ir_graph *irg)
+{
+       unsigned max_idx = get_irg_last_idx(irg) + 32;
+       nodemap->data = NEW_ARR_F(void*, max_idx);
+       memset(nodemap->data, 0, max_idx * sizeof(nodemap->data[0]));
+}
+
+/**
+ * frees all internal memory used by the nodemap but does not free the
+ * nodemap struct itself.
+ */
+static inline void ir_nodemap_destroy(ir_nodemap *nodemap)
+{
+       DEL_ARR_F(nodemap->data);
+       nodemap->data = NULL;
+}
+
+/**
+ * Insert a mapping from @p node to @p data.
+ */
+static inline void ir_nodemap_insert(ir_nodemap *nodemap, const ir_node *node,
+                                     void *data)
+{
+       unsigned idx = get_irn_idx(node);
+       size_t   len = ARR_LEN(nodemap->data);
+       if (idx >= len) {
+               ARR_RESIZE(void*, nodemap->data, idx+1);
+               memset(nodemap->data + len, 0, (idx-len) * sizeof(nodemap->data[0]));
+       }
+       nodemap->data[idx] = data;
+}
+
+/**
+ * Insert a mapping from @p node to @p data (fast version).
+ *
+ * @attention You must only use this version if you can be sure that the nodemap
+ * already has enough space to store the mapping. This is the case if @p node
+ * already existed at nodemap_init() time or ir_nodemap_insert() has been used
+ * for this node)
+ */
+static inline void ir_nodemap_insert_fast(ir_nodemap *nodemap,
+                                          const ir_node *node, void *data)
+{
+       unsigned idx = get_irn_idx(node);
+       nodemap->data[idx] = data;
+}
+
+/**
+ * Removed mapping for @p node.
+ *
+ * This is really a shorthand form for ir_nodemap_insert(nodemap, node, NULL);
+ */
+static inline void ir_nodemap_remove(ir_nodemap *nodemap, const ir_node *node)
+{
+       ir_nodemap_insert(nodemap, node, NULL);
+}
+
+/**
+ * Get mapping for @p node. Returns NULL if nothing is mapped.
+ */
+static inline void *ir_nodemap_get(const ir_nodemap *nodemap,
+                                   const ir_node *node)
+{
+       unsigned idx = get_irn_idx(node);
+       if (idx >= ARR_LEN(nodemap->data))
+               return NULL;
+       return nodemap->data[idx];
+}
+
+/**
+ * Get mapping for @p node (fast version). Returns NULL if nothing is mapped.
+ *
+ * @attention You must only use this function if you can be sure that the
+ * nodemap has enough space to potentially contain the mapping. This is the
+ * case if @p node already existed at nodemap_init() time or ir_nodemap_insert()
+ * has been used for this node)
+ */
+static inline void *ir_nodemap_get_fast(const ir_nodemap *nodemap,
+                                        const ir_node *node)
+{
+       unsigned idx = get_irn_idx(node);
+       return nodemap->data[idx];
+}
+
+#endif
index 7823898..689430c 100644 (file)
@@ -696,9 +696,9 @@ static ir_tarval *computed_value_Proj(const ir_node *proj)
 ir_tarval *computed_value(const ir_node *n)
 {
        vrp_attr *vrp = vrp_get_info(n);
-       if (vrp && vrp->valid && tarval_cmp(vrp->bits_set, vrp->bits_not_set) == ir_relation_equal) {
+       if (vrp != NULL && vrp->bits_set == vrp->bits_not_set)
                return vrp->bits_set;
-       }
+
        if (n->op->ops.computed_value)
                return n->op->ops.computed_value(n);
        return tarval_bad;
@@ -3443,18 +3443,18 @@ static ir_node *transform_node_Eor(ir_node *n)
                return n;
        }
 
-       if (mode_is_int(mode)) {
-               vrp_attr *a_vrp = vrp_get_info(a);
-               vrp_attr *b_vrp = vrp_get_info(b);
-               if (a_vrp != NULL && b_vrp != NULL) {
-                       ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
-
-                       if (tarval_is_null(vrp_val)) {
-                               dbg_info *dbgi = get_irn_dbg_info(n);
-                               return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
-                       }
+       {
+       vrp_attr *a_vrp = vrp_get_info(a);
+       vrp_attr *b_vrp = vrp_get_info(b);
+       if (a_vrp != NULL && b_vrp != NULL) {
+               ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
+
+               if (tarval_is_null(vrp_val)) {
+                       dbg_info *dbgi = get_irn_dbg_info(n);
+                       return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
                }
        }
+       }
 
        n = transform_bitwise_distributive(n, transform_node_Eor);
        if (is_Eor(n))
@@ -5120,18 +5120,18 @@ static ir_node *transform_node_Or(ir_node *n)
        if (n != oldn)
                return n;
 
-       if (mode_is_int(mode)) {
-               vrp_attr *a_vrp = vrp_get_info(a);
-               vrp_attr *b_vrp = vrp_get_info(b);
-               if (a_vrp != NULL && b_vrp != NULL) {
-                       ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
-
-                       if (tarval_is_null(vrp_val)) {
-                               dbg_info *dbgi = get_irn_dbg_info(n);
-                               return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
-                       }
+       {
+       vrp_attr *a_vrp = vrp_get_info(a);
+       vrp_attr *b_vrp = vrp_get_info(b);
+       if (a_vrp != NULL && b_vrp != NULL) {
+               ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
+
+               if (tarval_is_null(vrp_val)) {
+                       dbg_info *dbgi = get_irn_dbg_info(n);
+                       return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
                }
        }
+       }
 
        return n;
 }  /* transform_node_Or */
diff --git a/ir/ir/irphase.c b/ir/ir/irphase.c
deleted file mode 100644 (file)
index 98c01db..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * 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    Phase information handling using node indexes.
- * @author   Sebastian Hack
- * @version  $Id$
- * @brief
- *  A phase contains a link to private data for each node in an ir graph.
- *  A phase is independent from the globally visible link field of ir nodes.
- */
-#include "config.h"
-
-#include "array.h"
-#include "util.h"
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irphase_t.h"
-
-void *phase_irn_init_default(ir_phase *ph, const ir_node *irn)
-{
-       (void) ph;
-       (void) irn;
-       return NULL;
-}
-
-void phase_init(ir_phase *phase, ir_graph *irg, phase_irn_init *data_init)
-{
-       memset(phase, 0, sizeof(*phase));
-
-       obstack_init(&phase->obst);
-       phase->data_init  = data_init;
-       phase->irg        = irg;
-       phase->n_data_ptr = 0;
-       phase->data_ptr   = NULL;
-}
-
-ir_phase *new_phase(ir_graph *irg, phase_irn_init *data_init)
-{
-       ir_phase *phase = XMALLOC(ir_phase);
-       phase_init(phase, irg, data_init);
-       return phase;
-}
-
-void phase_deinit(ir_phase *phase)
-{
-       obstack_free(&phase->obst, NULL);
-       if (phase->data_ptr)
-               xfree(phase->data_ptr);
-}
-
-void phase_free(ir_phase *phase)
-{
-       phase_deinit(phase);
-       xfree(phase);
-}
-
-phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat)
-{
-       size_t i, n;
-       memset(stat, 0, sizeof(stat[0]));
-
-       stat->node_map_bytes = phase->n_data_ptr * sizeof(phase->data_ptr[0]);
-       stat->node_slots     = phase->n_data_ptr;
-       for (i = 0, n = phase->n_data_ptr; i < n; ++i) {
-               if (phase->data_ptr[i] != NULL) {
-                       stat->node_slots_used++;
-               }
-       }
-       stat->overall_bytes = stat->node_map_bytes + obstack_memory_used(&((ir_phase *)phase)->obst);
-       return stat;
-}
-
-void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit)
-{
-       size_t i, n;
-       ir_graph *irg;
-
-       if (! phase->data_init)
-               return;
-
-       irg = phase->irg;
-       for (i = 0, n = phase->n_data_ptr; i < n; ++i) {
-               if (phase->data_ptr[i]) {
-                       ir_node *node = get_idx_irn(irg, i);
-                       phase->data_ptr[i] = data_reinit(phase, node, phase->data_ptr[i]);
-               }
-       }
-}
-
-ir_node *phase_get_first_node(const ir_phase *phase)
-{
-       unsigned i;
-
-       for (i = 0; i < phase->n_data_ptr;  ++i)
-               if (phase->data_ptr[i])
-                       return get_idx_irn(phase->irg, i);
-
-       return NULL;
-}
-
-ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start)
-{
-       unsigned i;
-
-       for (i = get_irn_idx(start) + 1; i < phase->n_data_ptr; ++i)
-               if (phase->data_ptr[i])
-                       return get_idx_irn(phase->irg, i);
-
-       return NULL;
-}
diff --git a/ir/ir/irphase.h b/ir/ir/irphase.h
deleted file mode 100644 (file)
index 965d9c7..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * 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   Phase information handling using node indexes.
- * @author  Sebastian Hack
- * @version $Id: irphase_t.h 27270 2010-03-07 22:20:43Z matze $
- */
-#ifndef FIRM_IR_PHASE_H
-#define FIRM_IR_PHASE_H
-
-#include "firm_types.h"
-
-typedef struct ir_phase ir_phase;
-typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn);
-typedef void *(phase_irn_reinit)(ir_phase *phase, const ir_node *irn,
-                                 void *old_data);
-
-/**
- * Allocate and initialize a new phase object
- *
- * @param irg           The graph the phase will run on.
- * @param irn_data_init A callback that is called to initialize newly created
- *                      node data. Must be non-null. You could use
- *                      phase_irn_init_default
- * @return              A new phase object.
- */
-ir_phase *new_phase(ir_graph *irg, phase_irn_init *data_init);
-
-/**
- * Variant for custom memory-management/classes. Just initialize given phase
- * structure (performs no allocation, you do not need to call this for phases
- * allocated with new_phase)
- */
-void phase_init(ir_phase *phase, ir_graph *irg, phase_irn_init *data_init);
-
-/**
- * frees all internal memory used by the phase but does not free the
- * phase struct itself.
- */
-void phase_deinit(ir_phase *phase);
-
-/**
- * free memory allocated by a phase
- */
-void phase_free(ir_phase *phase);
-
-/**
- * Re-initialize the irn data for all nodes in the node => data map using the
- * given callback.
- * This is mainly used for reusing already allocated memory which could speed
- * things up a little bit.
- *
- * @param phase   The phase.
- * @param called  to reinitialize phase data.
- */
-void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit);
-
-/**
- * A default node initializer.
- * It does nothing and returns NULL.
- */
-extern phase_irn_init phase_irn_init_default;
-
-#endif
diff --git a/ir/ir/irphase_t.h b/ir/ir/irphase_t.h
deleted file mode 100644 (file)
index 9a6e463..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * 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   Phase information handling using node indexes.
- * @author  Sebastian Hack
- * @version $Id$
- */
-#ifndef FIRM_IR_PHASE_T_H
-#define FIRM_IR_PHASE_T_H
-
-#include "firm_types.h"
-#include "obst.h"
-#include "irgraph_t.h"
-#include "irtools.h"
-#include "irphase.h"
-
-/**
- * A phase object.
- */
-struct ir_phase {
-       void           **data_ptr;      /**< Map node indexes to irn data on the obstack. */
-       ir_graph        *irg;           /**< The irg this phase will we applied to. */
-       phase_irn_init  *data_init;     /**< A callback that is called to initialize newly created node data. */
-       size_t           n_data_ptr;    /**< The length of the data_ptr array. */
-       struct obstack   obst;          /**< The obstack where the irn phase data will be stored on. */
-       void            *priv;          /**< Some pointer private to the user of the phase. */
-};
-
-/**
- * For statistics: A type containing statistic data of a phase object.
- */
-typedef struct {
-       size_t node_slots;       /**< The number of allocated node slots. */
-       size_t node_slots_used;  /**< The number of used node slots, i.e. nodes that have node data. */
-       size_t node_map_bytes;   /**< Number of used bytes for the node map. */
-       size_t overall_bytes;    /**< Overall number of used bytes for the phase. */
-} phase_stat_t;
-
-/**
- * Collect Phase statistics.
- *
- * @param phase  The phase.
- * @param stat   Will be filled with the statistical data.
- */
-phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat);
-
-
-/**
- * Re-initialize the irn data for the given node.
- *
- * @param phase  The phase.
- * @param irn    The irn.
- */
-static inline void phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn,
-                                                phase_irn_reinit *reinit)
-{
-       int idx;
-
-       if (! phase->data_init)
-               return;
-
-       idx = get_irn_idx(irn);
-       if (phase->data_ptr[idx])
-               phase->data_ptr[idx] = reinit(phase, irn, phase->data_ptr[idx]);
-}
-
-/**
- * Returns the first node of the phase having some data assigned.
- *
- * @param phase  The phase.
- *
- * @return The first irn having some data assigned, NULL otherwise
- */
-ir_node *phase_get_first_node(const ir_phase *phase);
-
-/**
- * Returns the next node after @p start having some data assigned.
- *
- * @param phase  The phase.
- * @param start  The node to start from
- *
- * @return The next node after start having some data assigned, NULL otherwise
- */
-ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start);
-
-/**
- * Convenience macro to iterate over all nodes of a phase
- * having some data assigned.
- *
- * @param phase  The phase.
- * @param irn    A local variable that will hold the current node inside the loop.
- */
-#define foreach_phase_irn(phase, irn) \
-       for (irn = phase_get_first_node(phase); irn; irn = phase_get_next_node(phase, irn))
-
-/**
- * Get the irg the phase runs on.
- *
- * @param phase  The phase.
- */
-static inline ir_graph *phase_get_irg(const ir_phase *phase)
-{
-       return phase->irg;
-}
-
-/**
- * Get private data pointer as passed on creating the phase.
- *
- * @param phase  The phase.
- */
-static inline void *phase_get_private(const ir_phase *phase)
-{
-       return phase->priv;
-}
-
-/**
- * Attach pointer with private data to phase
- */
-static inline void phase_set_private(ir_phase *phase, void *priv)
-{
-       phase->priv = priv;
-}
-
-static inline void *phase_alloc(ir_phase *phase, size_t size)
-{
-       return obstack_alloc(&phase->obst, size);
-}
-
-/**
- * Get the obstack of a phase.
- *
- * @param phase  The phase.
- */
-static inline struct obstack *phase_obst(ir_phase *phase)
-{
-       return &phase->obst;
-}
-
-/**
- * Get the phase node data for an irn.
- *
- * @param phase   The phase.
- * @param irn     The irn to get data for.
- *
- * @return A pointer to the node data or NULL if the irn has no phase data allocated yet.
- */
-static inline void *phase_get_irn_data(const ir_phase *ph, const ir_node *irn)
-{
-       unsigned idx = get_irn_idx(irn);
-       return idx < ph->n_data_ptr ? ph->data_ptr[idx] : NULL;
-}
-
-/**
- * This is private and just here for performance reasons.
- */
-static inline void private_phase_enlarge(ir_phase *phase, unsigned max_idx)
-{
-       unsigned last_irg_idx = get_irg_last_idx(phase->irg);
-       size_t old_cap        = phase->n_data_ptr;
-       size_t new_cap;
-
-       /* make the maximum index at least as big as the largest index in the graph. */
-       max_idx = MAX(max_idx, last_irg_idx);
-       new_cap = (size_t) (max_idx + 256);
-
-       phase->data_ptr = XREALLOC(phase->data_ptr, void*, new_cap);
-
-       /* initialize the newly allocated memory. */
-       memset(phase->data_ptr + old_cap, 0, (new_cap - old_cap) * sizeof(phase->data_ptr[0]));
-       phase->n_data_ptr = new_cap;
-}
-
-/*
- * This is private and only here for performance reasons.
- */
-static inline void private_phase_assure_capacity(ir_phase *ph, unsigned max_idx)
-{
-       if (max_idx >= ph->n_data_ptr)
-               private_phase_enlarge(ph, max_idx);
-}
-
-
-/**
- * Get or set phase data for an irn.
- *
- * @param phase  The phase.
- * @param irn    The irn to get (or set) node data for.
- *
- * @return A (non-NULL) pointer to phase data for the irn. Either existent one or newly allocated one.
- */
-static inline void *phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn)
-{
-       unsigned idx = get_irn_idx(irn);
-       void *res;
-
-       /* Assure that there's a sufficient amount of slots. */
-       private_phase_assure_capacity(ph, idx + 1);
-
-       res = ph->data_ptr[idx];
-
-       /* If there has no irn data allocated yet, do that now. */
-       if(!res) {
-               phase_irn_init *data_init = ph->data_init;
-
-               /* call the node data structure allocator/constructor. */
-               res = ph->data_ptr[idx] = data_init(ph, irn);
-       }
-       return res;
-}
-
-/**
- * Set the node data for an irn.
- *
- * @param phase  The phase.
- * @param irn    The node.
- * @param data   The node data.
- *
- * @return The old data or NULL if there was none.
- */
-static inline void *phase_set_irn_data(ir_phase *ph, const ir_node *irn,
-                                       void *data)
-{
-       unsigned idx = get_irn_idx(irn);
-       void *res;
-
-       /* Assure that there's a sufficient amount of slots. */
-       private_phase_assure_capacity(ph, idx + 1);
-
-       res = ph->data_ptr[idx];
-       ph->data_ptr[idx] = data;
-
-       return res;
-}
-
-/**
- * convenience function that returns phase information attached to a node
- */
-static inline void *get_irn_phase_info(const ir_node *irn, ir_phase_id id)
-{
-       const ir_graph *irg = get_irn_irg(irn);
-       const ir_phase *ph  = irg_get_phase(irg, id);
-       return phase_get_irn_data(ph, irn);
-}
-
-/**
- * Get or set information a phase holds about a node.
- * If the given phase does not hold information of the node,
- * the information structure will be created, initialized (see the data_init
- * function of ir_phase), and returned.
- * @param irn The node.
- * @param id  The ID of the phase.
- */
-static inline void *get_or_set_irn_phase_info(const ir_node *irn, ir_phase_id id)
-{
-       const ir_graph *irg = get_irn_irg(irn);
-       ir_phase *ph  = irg_get_phase(irg, id);
-       return phase_get_or_set_irn_data(ph, irn);
-}
-
-static inline void *set_irn_phase_info(const ir_node *irn, ir_phase_id id,
-                                       void *data)
-{
-       const ir_graph *irg = get_irn_irg(irn);
-       ir_phase *ph  = irg_get_phase(irg, id);
-       return phase_set_irn_data(ph, irn, data);
-}
-
-#endif
index 73b44cb..7d5009e 100644 (file)
@@ -37,7 +37,6 @@
 #include "irmemory.h"
 #include "callgraph.h"
 #include "irprog.h"
-#include "irphase.h"
 #include "bitset.h"
 
 #include "pset.h"
 #include "obst.h"
 #include "vrp.h"
 
-/**
- * List of phases. (We will add a register/unregister interface if managing
- * this gets too tedious)
- */
-typedef enum ir_phase_id {
-       PHASE_FIRST,
-       PHASE_VRP = PHASE_FIRST,
-       PHASE_LAST = PHASE_VRP
-} ir_phase_id;
-ENUM_COUNTABLE(ir_phase_id)
+struct ir_nodemap {
+       void **data;  /**< maps node indices to void* */
+};
 
 /** The type of an ir_op. */
 struct ir_op {
@@ -451,6 +443,11 @@ typedef struct cg_callee_entry {
        size_t     max_depth;  /**< Maximum depth of all Call nodes to irg. */
 } cg_callee_entry;
 
+typedef struct ir_vrp_info {
+       struct ir_nodemap infos;
+       struct obstack    obst;
+} ir_vrp_info;
+
 /**
  * An ir_graph holds all information for a procedure.
  */
@@ -491,6 +488,7 @@ struct ir_graph {
        pset *value_table;                 /**< Hash table for global value numbering (cse)
                                                for optimizing use in iropt.c */
        ir_def_use_edge *outs;             /**< Space for the Def-Use arrays. */
+       ir_vrp_info      vrp;              /**< vrp info */
 
        ir_loop *loop;                     /**< The outermost loop for this graph. */
        void *link;                        /**< A void* field to link any information to
@@ -521,7 +519,7 @@ struct ir_graph {
        ir_node **idx_irn_map;             /**< Array mapping node indexes to nodes. */
 
        size_t index;                      /**< a unique number for each graph */
-       ir_phase *phases[PHASE_LAST+1];    /**< Phase information. */
+       /** extra info which should survive accross multiple passes */
        void     *be_data;                 /**< backend can put in private data here */
 
        unsigned  dump_nr;                 /**< number of graph dumps */
index e0ab3b5..eb045e9 100644 (file)
@@ -299,16 +299,7 @@ static void conv_opt_walker(ir_node *node, void *data)
 
        transformed = conv_transform(pred, mode);
        if (node != transformed) {
-               vrp_attr *vrp;
-
                exchange(node, transformed);
-               vrp = vrp_get_info(transformed);
-               if (vrp && vrp->valid) {
-                       vrp->range_type = VRP_VARYING;
-                       vrp->bits_set = tarval_convert_to(vrp->bits_set, mode);
-                       vrp->bits_not_set = tarval_convert_to(vrp->bits_not_set, mode);
-               }
-
                *changed = true;
        }
 }
index 00e698d..d2149b3 100644 (file)
@@ -34,7 +34,6 @@
 #include "iroptimize.h"
 #include "irnode_t.h"
 #include "irgraph_t.h"
-#include "irphase_t.h"
 #include "iredges_t.h"
 #include "irhooks.h"
 #include "irtools.h"
@@ -46,9 +45,6 @@
 #include "irpass.h"
 #include "pmap.h"
 
-/** a pointer to the new phases */
-static ir_phase *new_phases[PHASE_LAST + 1];
-
 /**
  * Reroute the inputs of a node from nodes in the old graph to copied nodes in
  * the new graph
@@ -61,25 +57,13 @@ static void rewire_inputs(ir_node *node, void *env)
 
 static void copy_node_dce(ir_node *node, void *env)
 {
-       ir_phase_id i;
-       ir_node    *new_node = exact_copy(node);
-       ir_graph   *irg      = get_irn_irg(new_node);
+       ir_node  *new_node = exact_copy(node);
+       ir_graph *irg      = get_irn_irg(new_node);
        (void) env;
 
        /* preserve the node numbers for easier debugging */
        new_node->node_nr = node->node_nr;
 
-       /* copy phase information for this node */
-       for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
-               ir_phase *phase = irg_get_phase(irg, i);
-               if (phase == NULL)
-                       continue;
-               if (!phase_get_irn_data(phase, node))
-                       continue;
-               phase_set_irn_data(new_phases[i], new_node,
-                                  phase_get_irn_data(phase, node));
-       }
-
        set_irn_link(node, new_node);
        hook_dead_node_elim_subst(irg, node, new_node);
 }
@@ -92,21 +76,7 @@ static void copy_node_dce(ir_node *node, void *env)
  */
 static void copy_graph_env(ir_graph *irg)
 {
-       ir_node    *new_anchor;
-       ir_phase_id i;
-
-       /* init the new_phases array */
-       /* TODO: this is wrong, it should only allocate a new data_ptr inside
-        * the phase! */
-       for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
-               ir_phase *old_ph = irg_get_phase(irg, i);
-               if (old_ph == NULL) {
-                       new_phases[i] = NULL;
-               } else {
-                       new_phases[i] = new_phase(irg, old_ph->data_init);
-                       new_phases[i]->priv = old_ph->priv;
-               }
-       }
+       ir_node *new_anchor;
 
        /* copy nodes */
        irg_walk_anchors(irg, copy_node_dce, rewire_inputs, NULL);
@@ -115,19 +85,6 @@ static void copy_graph_env(ir_graph *irg)
        new_anchor = (ir_node*)get_irn_link(irg->anchor);
        assert(new_anchor != NULL);
        irg->anchor = new_anchor;
-
-       /* copy the new phases into the irg */
-       for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
-               ir_phase *old_ph = irg_get_phase(irg, i);
-               if (old_ph == NULL)
-                       continue;
-
-               /* Matze: commented out for now: This is a memory leak, but for a real
-                * fix we must not create new phases here, but reuse the old phases
-                * and just create a new data array */
-               /* phase_free(old_ph); */
-               irg->phases[i] = new_phases[i];
-       }
 }
 
 /**
@@ -155,6 +112,7 @@ void dead_node_elimination(ir_graph *irg)
        free_irg_outs(irg);
        free_trouts();
        free_loop_information(irg);
+       free_vrp_data(irg);
        clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE);
 
        /* A quiet place, where the old obstack can rest in peace,
index 1a20d9f..27810dd 100644 (file)
@@ -35,6 +35,7 @@
 #include "ircons_t.h"
 #include "irgmod.h"
 #include "irgwalk.h"
+#include "irtools.h"
 #include "tv_t.h"
 #include "dbginfo_t.h"
 #include "iropt_dbg.h"
@@ -45,7 +46,7 @@
 #include "irpass.h"
 #include "opt_polymorphy.h"
 #include "irmemory.h"
-#include "irphase_t.h"
+#include "irnodehashmap.h"
 #include "irgopt.h"
 #include "set.h"
 #include "be.h"
@@ -1713,13 +1714,14 @@ typedef struct node_entry {
 
 /** A loop entry. */
 typedef struct loop_env {
-       ir_phase ph;           /**< the phase object */
-       ir_node  **stack;      /**< the node stack */
-       size_t   tos;          /**< tos index */
-       unsigned nextDFSnum;   /**< the current DFS number */
-       unsigned POnum;        /**< current post order number */
-
-       unsigned changes;      /**< a bitmask of graph changes */
+       ir_nodehashmap_t map;
+       struct obstack   obst;
+       ir_node          **stack;      /**< the node stack */
+       size_t           tos;          /**< tos index */
+       unsigned         nextDFSnum;   /**< the current DFS number */
+       unsigned         POnum;        /**< current post order number */
+
+       unsigned         changes;      /**< a bitmask of graph changes */
 } loop_env;
 
 /**
@@ -1727,13 +1729,12 @@ typedef struct loop_env {
 */
 static node_entry *get_irn_ne(ir_node *irn, loop_env *env)
 {
-       ir_phase   *ph = &env->ph;
-       node_entry *e  = (node_entry*)phase_get_irn_data(&env->ph, irn);
+       node_entry *e = (node_entry*)ir_nodehashmap_get(&env->map, irn);
 
-       if (! e) {
-               e = (node_entry*)phase_alloc(ph, sizeof(*e));
+       if (e == NULL) {
+               e = OALLOC(&env->obst, node_entry);
                memset(e, 0, sizeof(*e));
-               phase_set_irn_data(ph, irn, e);
+               ir_nodehashmap_insert(&env->map, irn, e);
        }
        return e;
 }  /* get_irn_ne */
@@ -1856,7 +1857,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
 
                        if (pe->pscc != ne->pscc) {
                                /* not in the same SCC, is region const */
-                               phi_entry *pe = (phi_entry*)phase_alloc(&env->ph, sizeof(*pe));
+                               phi_entry *pe = OALLOC(&env->obst, phi_entry);
 
                                pe->phi  = phi;
                                pe->pos  = j;
@@ -1933,7 +1934,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
                                                DB((dbg, LEVEL_1, "  Created %+F in %+F\n", irn, pred));
                                        }
                                        pe->load = irn;
-                                       ninfo = get_ldst_info(irn, phase_obst(&env->ph));
+                                       ninfo = get_ldst_info(irn, &env->obst);
 
                                        ninfo->projs[pn_Load_M] = mem = new_r_Proj(irn, mode_M, pn_Load_M);
                                        if (res == NULL) {
@@ -2173,7 +2174,7 @@ static void dfs(ir_node *irn, loop_env *env)
        }
 
        if (node->low == node->DFSnum) {
-               scc *pscc = (scc*)phase_alloc(&env->ph, sizeof(*pscc));
+               scc *pscc = OALLOC(&env->obst, scc);
                ir_node *x;
 
                pscc->head = NULL;
@@ -2247,13 +2248,15 @@ static int optimize_loops(ir_graph *irg)
        env.nextDFSnum    = 0;
        env.POnum         = 0;
        env.changes       = 0;
-       phase_init(&env.ph, irg, phase_irn_init_default);
+       ir_nodehashmap_init(&env.map);
+       obstack_init(&env.obst);
 
        /* calculate the SCC's and drive loop optimization. */
        do_dfs(irg, &env);
 
        DEL_ARR_F(env.stack);
-       phase_deinit(&env.ph);
+       obstack_free(&env.obst, NULL);
+       ir_nodehashmap_destroy(&env.map);
 
        return env.changes;
 }  /* optimize_loops */
index 9da79e4..46665db 100644 (file)
 
 #include <math.h>
 #include "irbackedge_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 #include "irloop_t.h"
 
-
 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
 /**
@@ -212,7 +211,8 @@ static entry_edge *loop_entries;
 /* Number of unrolls to perform */
 static int unroll_nr;
 /* Phase is used to keep copies of nodes. */
-static ir_phase *phase;
+static ir_nodemap     map;
+static struct obstack obst;
 
 /* Loop operations.  */
 typedef enum loop_op_t {
@@ -496,16 +496,14 @@ static void set_unroll_copy(ir_node *n, int nr, ir_node *cp)
        unrolling_node_info *info;
        assert(nr != 0 && "0 reserved");
 
-       info = (unrolling_node_info *)phase_get_irn_data(phase, n);
+       info = (unrolling_node_info*)ir_nodemap_get(&map, n);
        if (! info) {
-               ir_node **arr;
+               ir_node **arr = NEW_ARR_D(ir_node*, &obst, unroll_nr);
+               memset(arr, 0, unroll_nr * sizeof(ir_node*));
 
-               info = XMALLOCZ(unrolling_node_info);
-               arr = NEW_ARR_F(ir_node *, unroll_nr);
+               info = OALLOCZ(&obst, unrolling_node_info);
                info->copies = arr;
-               memset(info->copies, 0, (unroll_nr) * sizeof(ir_node *));
-
-               phase_set_irn_data(phase, n, info);
+               ir_nodemap_insert(&map, n, info);
        }
        /* Original node */
        info->copies[0] = n;
@@ -517,7 +515,7 @@ static void set_unroll_copy(ir_node *n, int nr, ir_node *cp)
 static ir_node *get_unroll_copy(ir_node *n, int nr)
 {
        ir_node             *cp;
-       unrolling_node_info *info = (unrolling_node_info *)phase_get_irn_data(phase, n);
+       unrolling_node_info *info = (unrolling_node_info *)ir_nodemap_get(&map, n);
        if (! info)
                return NULL;
 
@@ -531,13 +529,13 @@ static ir_node *get_unroll_copy(ir_node *n, int nr)
 /* Sets copy cp of node n. */
 static void set_inversion_copy(ir_node *n, ir_node *cp)
 {
-       phase_set_irn_data(phase, n, cp);
+       ir_nodemap_insert(&map, n, cp);
 }
 
 /* Getter of copy of n for inversion */
 static ir_node *get_inversion_copy(ir_node *n)
 {
-       ir_node *cp = (ir_node *)phase_get_irn_data(phase, n);
+       ir_node *cp = (ir_node *)ir_nodemap_get(&map, n);
        return cp;
 }
 
@@ -1310,7 +1308,8 @@ static void loop_inversion(ir_graph *irg)
        inversion_blocks_in_cc = 0;
 
        /* Use phase to keep copy of nodes from the condition chain. */
-       phase = new_phase(irg, phase_irn_init_default);
+       ir_nodemap_init(&map, irg);
+       obstack_init(&obst);
 
        /* Search for condition chains and temporarily save the blocks in an array. */
        cc_blocks = NEW_ARR_F(ir_node *, 0);
@@ -1362,7 +1361,8 @@ static void loop_inversion(ir_graph *irg)
        }
 
        /* free */
-       phase_free(phase);
+       obstack_free(&obst, NULL);
+       ir_nodemap_destroy(&map);
        DEL_ARR_F(cond_chain_entries);
        DEL_ARR_F(head_df_loop);
 
@@ -2555,7 +2555,8 @@ static void unroll_loop(void)
                }
 
                /* Use phase to keep copy of nodes from the condition chain. */
-               phase = new_phase(current_ir_graph, phase_irn_init_default);
+               ir_nodemap_init(&map, current_ir_graph);
+               obstack_init(&obst);
 
                /* Copies the loop */
                copy_loop(loop_entries, unroll_nr - 1);
@@ -2577,6 +2578,8 @@ static void unroll_loop(void)
                clear_irg_state(current_ir_graph, IR_GRAPH_STATE_CONSISTENT_DOMINANCE);
 
                DEL_ARR_F(loop_entries);
+               obstack_free(&obst, NULL);
+               ir_nodemap_destroy(&map);
        }
 
 }
index 6792f2c..b100d62 100644 (file)
@@ -63,7 +63,7 @@
 #include "irtools.h"
 #include "iropt_dbg.h"
 #include "irpass_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg;)