correctly implement memop handling
[libfirm] / ir / opt / gvn_pre.c
index e8123ab..56229ef 100644 (file)
@@ -22,7 +22,6 @@
  * @brief   Global Value Numbering Partial Redundancy Elimination
  *          (VanDrunen Hosking 2004)
  * @author  Michael Beck
- * @version $Id$
  * @brief
  */
 #include "config.h"
@@ -36,7 +35,7 @@
 #include "ircons.h"
 #include "irgmod.h"
 #include "valueset.h"
-#include "irnodemap.h"
+#include "irnodehashmap.h"
 #include "irnodeset.h"
 #include "iredges.h"
 #include "iropt_dbg.h"
@@ -83,8 +82,7 @@ typedef struct pre_env {
        char first_iter;        /**< non-zero for first iteration */
 } pre_env;
 
-static pset         *value_table;
-static ir_nodemap_t value_map;
+static ir_nodehashmap_t value_map;
 
 /** The debug module handle. */
 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
@@ -117,15 +115,15 @@ static ir_node *add(ir_node *e, ir_node *v)
 {
        if (is_Proj(v)) {
                ir_node *pred = get_Proj_pred(v);
-               ir_node *v_pred = identify_remember(value_table, pred);
+               ir_node *v_pred = identify_remember(pred);
 
                if (v_pred != pred) {
                        /* must create a new value here */
                        v = new_r_Proj(v_pred, get_irn_mode(v), get_Proj_proj(v));
                }
        }
-       v = identify_remember(value_table, v);
-       ir_nodemap_insert(&value_map, e, v);
+       v = identify_remember(v);
+       ir_nodehashmap_insert(&value_map, e, v);
        return v;
 }  /* add */
 
@@ -139,11 +137,11 @@ static ir_node *add(ir_node *e, ir_node *v)
  */
 static ir_node *lookup(ir_node *e)
 {
-       ir_node *value = ir_nodemap_get(&value_map, e);
+       ir_node *value = (ir_node*)ir_nodehashmap_get(&value_map, e);
        if (value != NULL)
-               return identify_remember(value_table, value);
+               return identify_remember(value);
        return NULL;
-}  /* lookup */
+}
 
 /**
  * Return the block info of a block.
@@ -152,8 +150,8 @@ static ir_node *lookup(ir_node *e)
  */
 static block_info *get_block_info(ir_node *block)
 {
-       return get_irn_link(block);
-}  /* get_block_info */
+       return (block_info*)get_irn_link(block);
+}
 
 /**
  * Allocate a block info for a block.
@@ -192,9 +190,9 @@ static int is_nice_value(ir_node *n)
                return 0;
        mode = get_irn_mode(n);
        if (!mode_is_data(mode)) {
-               if (! is_Div(n) && ! is_Mod(n) && ! is_DivMod(n))
+               if (! is_Div(n) && ! is_Mod(n))
                        return 0;
-               if (! is_NoMem(get_fragile_op_mem(n)))
+               if (! is_NoMem(get_memop_mem(n)))
                        return 0;
        }
        return 1;
@@ -208,7 +206,7 @@ static int is_nice_value(ir_node *n)
  * @param txt    a text to describe the set
  * @param block  the owner block of the set
  */
-static void dump_value_set(ir_valueset_t *set, char *txt, ir_node *block)
+static void dump_value_set(ir_valueset_t *set, const char *txt, ir_node *block)
 {
        ir_valueset_iterator_t iter;
        ir_node *value, *expr;
@@ -233,12 +231,12 @@ static void dump_value_set(ir_valueset_t *set, char *txt, ir_node *block)
 #endif /* DEBUG_libfirm */
 
 /**
- * Topological walker. Allocates block info for every block and place nodes in topological
- * order into the nodes set.
+ * Topological walker. Allocates block info for every block and place nodes in
+ * topological order into the nodes set.
  */
 static void topo_walker(ir_node *irn, void *ctx)
 {
-       pre_env    *env = ctx;
+       pre_env    *env = (pre_env*)ctx;
        ir_node    *block;
        block_info *info;
        ir_node    *value;
@@ -265,7 +263,7 @@ static void topo_walker(ir_node *irn, void *ctx)
        info  = get_block_info(block);
 
        ir_valueset_insert(info->exp_gen, value, irn);
-}  /* topo_walker */
+}
 
 /**
  * Computes Avail_out(block):
@@ -282,7 +280,7 @@ static void topo_walker(ir_node *irn, void *ctx)
  */
 static void compute_avail_top_down(ir_node *block, void *ctx)
 {
-       pre_env    *env = ctx;
+       pre_env    *env = (pre_env*)ctx;
        block_info *dom_info;
        block_info *info = get_block_info(block);
        ir_node    *dom_blk;
@@ -308,7 +306,7 @@ static void compute_avail_top_down(ir_node *block, void *ctx)
        value_union(info->avail_out, info->exp_gen);
 
        dump_value_set(info->avail_out, "Avail_out", block);
-}  /* compute_avail_top_down */
+}
 
 /**
  * check if a node n is clean in block block.
@@ -382,7 +380,7 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
                ir_node *trans;
 
                leader = leader != NULL ? leader : pred;
-               trans  = ir_valueset_lookup(translated, leader);
+               trans  = (ir_node*)ir_valueset_lookup(translated, leader);
 
                if ((trans != NULL && trans != leader) || (is_Phi(leader) && get_nodes_block(leader) == block))
                        break;
@@ -395,7 +393,7 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
        nn = new_ir_node(
                get_irn_dbg_info(node),
                current_ir_graph,
-               NULL,
+               get_nodes_block(node),
                get_irn_op(node),
                get_irn_mode(node),
                arity,
@@ -404,14 +402,13 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
           node might depend on that. */
        copy_node_attr(current_ir_graph, node, nn);
 
-       set_nodes_block(nn, get_nodes_block(node));
        for (i = 0; i < arity; ++i) {
                ir_node *pred    = get_irn_n(node, i);
                ir_node *leader  = lookup(pred);
                ir_node *trans;
 
                leader = leader != NULL ? leader : pred;
-               trans  = ir_valueset_lookup(translated, leader);
+               trans  = (ir_node*)ir_valueset_lookup(translated, leader);
                if (trans == NULL)
                        trans = leader;
 
@@ -432,7 +429,7 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
  */
 static void compute_antic(ir_node *block, void *ctx)
 {
-       pre_env    *env = ctx;
+       pre_env    *env = (pre_env*)ctx;
        block_info *succ_info;
        block_info *info = get_block_info(block);
        ir_node    *succ, *value, *expr;
@@ -538,8 +535,8 @@ static void compute_antic(ir_node *block, void *ctx)
  */
 static void insert_nodes(ir_node *block, void *ctx)
 {
-       pre_env    *env = ctx;
-       ir_node    *value, *expr, *idom, *first_s, *worklist;
+       pre_env    *env = (pre_env*)ctx;
+       ir_node    *value, *expr, *idom, *first_s;
        block_info *curr_info, *idom_info;
        int        pos, arity = get_irn_arity(block);
        int        all_same, by_some, updated;
@@ -573,7 +570,6 @@ static void insert_nodes(ir_node *block, void *ctx)
 
        /* convert the set into a list. This allows the removal of
         * elements from the set */
-       worklist = NULL;
        foreach_valueset(curr_info->antic_in, value, expr, iter) {
                ir_mode *mode;
 
@@ -605,7 +601,7 @@ static void insert_nodes(ir_node *block, void *ctx)
                                v_prime = value;
 
                        pred_info = get_block_info(pred_blk);
-                       e_dprime  = ir_valueset_lookup(pred_info->avail_out, v_prime);
+                       e_dprime  = (ir_node*)ir_valueset_lookup(pred_info->avail_out, v_prime);
 
                        if (e_dprime == NULL) {
                                pred_info->avail     = e_prime;
@@ -641,7 +637,8 @@ static void insert_nodes(ir_node *block, void *ctx)
 
                                /* ignore bad blocks. */
                                if (is_Bad(pred_blk)) {
-                                       in[pos] = new_Bad();
+                                       ir_graph *irg = get_irn_irg(pred_blk);
+                                       in[pos] = new_r_Bad(irg, mode_X);
                                        continue;
                                }
 
@@ -717,7 +714,7 @@ static void insert_nodes(ir_node *block, void *ctx)
  */
 static void eliminate(ir_node *irn, void *ctx)
 {
-       pre_env *env = ctx;
+       pre_env *env = (pre_env*)ctx;
 
        if (!is_Block(irn)) {
                ir_node *block = get_nodes_block(irn);
@@ -725,7 +722,7 @@ static void eliminate(ir_node *irn, void *ctx)
                ir_node *value = lookup(irn);
 
                if (value != NULL) {
-                       ir_node *expr = ir_valueset_lookup(bl->avail_out, value);
+                       ir_node *expr = (ir_node*)ir_valueset_lookup(bl->avail_out, value);
 
                        if (expr != NULL && expr != irn) {
                                elim_pair *p = OALLOC(env->obst, elim_pair);
@@ -807,8 +804,8 @@ void do_gvn_pre(ir_graph *irg)
        /* edges will crash if enabled due to our allocate on other obstack trick */
        edges_deactivate(irg);
 
-       value_table = new_identities();
-       ir_nodemap_init(&value_map);
+       new_identities(irg);
+       ir_nodehashmap_init(&value_map);
 
        obstack_init(&obst);
        a_env.obst        = &obst;
@@ -817,10 +814,6 @@ void do_gvn_pre(ir_graph *irg)
        a_env.end_block   = get_irg_end_block(irg);
        a_env.pairs       = NULL;
 
-       /* Move Proj's into the same block as their args,
-          else we would assign the result to wrong blocks */
-       normalize_proj_nodes(irg);
-
        /* critical edges MUST be removed */
        remove_critical_cf_edges(irg);
 
@@ -891,19 +884,12 @@ void do_gvn_pre(ir_graph *irg)
                if (bl_info->new_set)
                        ir_valueset_del(bl_info->new_set);
        }
-       del_identities(value_table);
-       ir_nodemap_destroy(&value_map);
+       ir_nodehashmap_destroy(&value_map);
        obstack_free(&obst, NULL);
-       value_table = NULL;
 
        /* pin the graph again: This is needed due to the use of set_opt_global_cse(1) */
        set_irg_pinned(irg, op_pin_state_pinned);
        restore_optimization_state(&state);
-
-       if (a_env.pairs) {
-               set_irg_outs_inconsistent(irg);
-               set_irg_loopinfo_inconsistent(irg);
-       }
 }  /* do_gvn_pre */
 
 /* Creates an ir_graph pass for do_gvn_pre. */