Probably compute_Cmp() can ge removed at all, compute_Proj_Cmp() does the interesting...
[libfirm] / ir / opt / gvn_pre.c
index 9243bbe..5ee666b 100644 (file)
  *          (VanDrunen Hosking 2004)
  * @author  Michael Beck
  * @version $Id$
- * @summary
+ * @brief
  */
 #include "config.h"
 
+#include "iroptimize.h"
 #include "irflag.h"
 #include "irdom.h"
 #include "irouts.h"
@@ -40,6 +41,7 @@
 #include "iredges.h"
 #include "iropt_dbg.h"
 #include "debug.h"
+#include "irpass.h"
 
 #include "irgraph_t.h"
 #include "irnode_t.h"
@@ -74,7 +76,7 @@ typedef struct pre_env {
        struct obstack *obst;   /**< The obstack to allocate on. */
        ir_node *start_block;   /**< The start block of the current graph. */
        ir_node *end_block;     /**< The end block of the current graph */
-       block_info *list;       /**< Links all block info entires for easier recovery. */
+       block_info *list;       /**< Links all block info entries for easier recovery. */
        elim_pair *pairs;       /**< A list of node pairs that must be eliminated. */
        unsigned last_idx;      /**< last node index of "old" nodes, all higher indexes are newly created once. */
        char changes;           /**< Non-zero, if calculation of Antic_in has changed. */
@@ -119,7 +121,7 @@ static ir_node *add(ir_node *e, ir_node *v)
 
                if (v_pred != pred) {
                        /* must create a new value here */
-                       v = new_r_Proj(current_ir_graph, get_nodes_block(v_pred), v_pred, get_irn_mode(v), get_Proj_proj(v));
+                       v = new_r_Proj(v_pred, get_irn_mode(v), get_Proj_proj(v));
                }
        }
        v = identify_remember(value_table, v);
@@ -148,7 +150,8 @@ static ir_node *lookup(ir_node *e)
  *
  * @param block  the block
  */
-static block_info *get_block_info(ir_node *block) {
+static block_info *get_block_info(ir_node *block)
+{
        return get_irn_link(block);
 }  /* get_block_info */
 
@@ -158,8 +161,9 @@ static block_info *get_block_info(ir_node *block) {
  * @param block   the block
  * @param env     the environment
  */
-static void alloc_blk_info(ir_node *block, pre_env *env) {
-       block_info *info = obstack_alloc(env->obst, sizeof(*info));
+static void alloc_blk_info(ir_node *block, pre_env *env)
+{
+       block_info *info = OALLOC(env->obst, block_info);
 
        set_irn_link(block, info);
        info->exp_gen   = ir_valueset_new(16);
@@ -178,7 +182,8 @@ static void alloc_blk_info(ir_node *block, pre_env *env) {
  *
  * @param n  the node
  */
-static int is_nice_value(ir_node *n) {
+static int is_nice_value(ir_node *n)
+{
        ir_mode *mode;
 
        while (is_Proj(n))
@@ -203,7 +208,8 @@ 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, char *txt, ir_node *block)
+{
        ir_valueset_iterator_t iter;
        ir_node *value, *expr;
        int i;
@@ -230,7 +236,8 @@ static void dump_value_set(ir_valueset_t *set, char *txt, ir_node *block) {
  * 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) {
+static void topo_walker(ir_node *irn, void *ctx)
+{
        pre_env    *env = ctx;
        ir_node    *block;
        block_info *info;
@@ -310,7 +317,8 @@ static void compute_avail_top_down(ir_node *block, void *ctx)
  * @param block  the block
  * @param set    a value set, containing the already processed predecessors
  */
-static int is_clean_in_block(ir_node *n, ir_node *block, ir_valueset_t *set) {
+static int is_clean_in_block(ir_node *n, ir_node *block, ir_valueset_t *set)
+{
        int i;
 
        if (is_Phi(n))
@@ -394,7 +402,7 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
                get_irn_in(node));
        /* We need the attribute copy here, because the Hash value of a
           node might depend on that. */
-       copy_node_attr(node, nn);
+       copy_node_attr(current_ir_graph, node, nn);
 
        set_nodes_block(nn, get_nodes_block(node));
        for (i = 0; i < arity; ++i) {
@@ -407,10 +415,9 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
                if (trans == NULL)
                        trans = leader;
 
-               if (is_Phi(trans) && get_nodes_block(trans) == block) {
-                       ir_node *trans_pred = get_Phi_pred(trans, pos);
-                       set_irn_n(nn, i, trans_pred);
-               } else
+               if (is_Phi(trans) && get_nodes_block(trans) == block)
+                       set_irn_n(nn, i, get_Phi_pred(trans, pos));
+               else
                        set_irn_n(nn, i, trans);
        }
        nn = optimize_node(nn);
@@ -423,7 +430,8 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
  * @param block  the block
  * @param ctx    the walker environment
  */
-static void compute_antic(ir_node *block, void *ctx) {
+static void compute_antic(ir_node *block, void *ctx)
+{
        pre_env    *env = ctx;
        block_info *succ_info;
        block_info *info = get_block_info(block);
@@ -455,16 +463,11 @@ static void compute_antic(ir_node *block, void *ctx) {
 
                n_succ = get_Block_n_cfg_outs(block);
                if (n_succ == 1) {
-                       int i, pos = -1;
+                       int pos = -1;
 
                        /* find blocks position in succ's block predecessors */
                        succ = get_Block_cfg_out(block, 0);
-                       for (i = get_Block_n_cfgpreds(succ) - 1; i >= 0; --i) {
-                               if (get_Block_cfgpred_block(succ, i) == block) {
-                                       pos = i;
-                                       break;
-                               }
-                       }
+                       pos  = get_Block_cfgpred_pos(succ, block);
                        assert(pos >= 0);
 
                        succ_info = get_block_info(succ);
@@ -658,7 +661,7 @@ static void insert_nodes(ir_node *block, void *ctx)
                                                                mode,
                                                                get_irn_arity(pred),
                                                                get_irn_in(pred) + 1);
-                                                       copy_node_attr(pred, nn);
+                                                       copy_node_attr(current_ir_graph, pred, nn);
 
                                                        DB((dbg, LEVEL_1, "New node %+F in block %+F created\n", nn, pred_blk));
                                                        proj_pred = nn;
@@ -671,7 +674,7 @@ static void insert_nodes(ir_node *block, void *ctx)
                                                        mode,
                                                        get_irn_arity(e_prime),
                                                        get_irn_in(e_prime) + 1);
-                                               copy_node_attr(e_prime, nn);
+                                               copy_node_attr(current_ir_graph, e_prime, nn);
                                                if (proj_pred != NULL) {
                                                        set_Proj_pred(nn, proj_pred);
                                                }
@@ -687,7 +690,7 @@ static void insert_nodes(ir_node *block, void *ctx)
                                }
                                in[pos] = pred_info->avail;
                        }  /* for */
-                       phi = new_r_Phi(current_ir_graph, block, arity, in, mode);
+                       phi = new_r_Phi(block, arity, in, mode);
                        l = lookup(expr);
                        if (l == NULL) {
                                l = add(expr, value);
@@ -712,7 +715,8 @@ static void insert_nodes(ir_node *block, void *ctx)
  * @param irn  the node
  * @param ctx  the walker environment
  */
-static void eliminate(ir_node *irn, void *ctx) {
+static void eliminate(ir_node *irn, void *ctx)
+{
        pre_env *env = ctx;
 
        if (is_no_Block(irn)) {
@@ -724,7 +728,7 @@ static void eliminate(ir_node *irn, void *ctx) {
                        ir_node *expr = ir_valueset_lookup(bl->avail_out, value);
 
                        if (expr != NULL && expr != irn) {
-                               elim_pair *p = obstack_alloc(env->obst, sizeof(*p));
+                               elim_pair *p = OALLOC(env->obst, elim_pair);
 
                                p->old_node = irn;
                                p->new_node = expr;
@@ -742,7 +746,8 @@ static void eliminate(ir_node *irn, void *ctx) {
  *
  * @param pairs  list of elimination pairs
  */
-static void eliminate_nodes(elim_pair *pairs) {
+static void eliminate_nodes(elim_pair *pairs)
+{
        elim_pair *p;
 
        for (p = pairs; p != NULL; p = p->next) {
@@ -785,7 +790,7 @@ static void eliminate_nodes(elim_pair *pairs) {
  * references the origin. These nodes are translated again and again...
  *
  * The current fix is to use post-dominance. This simple ignores
- * endless loops, ie we cannot optimize them.
+ * endless loops, i.e. we cannot optimize them.
  */
 void do_gvn_pre(ir_graph *irg)
 {
@@ -798,7 +803,6 @@ void do_gvn_pre(ir_graph *irg)
 
        /* register a debug mask */
        FIRM_DBG_REGISTER(dbg, "firm.opt.gvn_pre");
-       firm_dbg_set_mask(dbg, 3);
 
        /* edges will crash if enabled due to our allocate on other obstack trick */
        edges_deactivate(irg);
@@ -901,3 +905,9 @@ void do_gvn_pre(ir_graph *irg)
                set_irg_loopinfo_inconsistent(irg);
        }
 }  /* do_gvn_pre */
+
+/* Creates an ir_graph pass for do_gvn_pre. */
+ir_graph_pass_t *do_gvn_pre_pass(const char *name)
+{
+       return def_graph_pass(name ? name : "gvn_pre", do_gvn_pre);
+}  /* do_gvn_pre_pass */