bestabs: move stabs but not backend specific text0: code into stabs
[libfirm] / ir / opt / jumpthreading.c
index f4cd388..f8b3cfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -42,7 +42,7 @@
 #include "irtools.h"
 #include "irgraph.h"
 #include "tv.h"
-#include "opt_confirms.h"
+#include "iroptimize.h"
 #include "iropt_dbg.h"
 #include "irpass.h"
 #include "vrp.h"
@@ -81,15 +81,18 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
        ir_graph *irg;
        ir_node *phi;
        ir_node **in;
+       ir_node *dummy;
 
        /* This is needed because we create bads sometimes */
-       if (is_Bad(block))
-               return new_Bad();
+       if (is_Bad(block)) {
+               ir_graph *irg = get_irn_irg(block);
+               return new_r_Bad(irg);
+       }
 
        /* the other defs can't be marked for cases where a user of the original
         * value is in the same block as the alternative definition.
         * In this case we mustn't use the alternative definition.
-        * So we keep a flag that indicated wether we walked at least 1 block
+        * So we keep a flag that indicated whether we walked at least 1 block
         * away and may use the alternative definition */
        if (block == ssa_second_def_block && !first) {
                return ssa_second_def;
@@ -117,15 +120,16 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
 
        /* create a new Phi */
        NEW_ARR_A(ir_node*, in, n_cfgpreds);
-       for(i = 0; i < n_cfgpreds; ++i)
-               in[i] = new_Unknown(mode);
+       dummy = new_r_Dummy(irg, mode);
+       for (i = 0; i < n_cfgpreds; ++i)
+               in[i] = dummy;
 
        phi = new_r_Phi(block, n_cfgpreds, in, mode);
        set_irn_link(block, phi);
        mark_irn_visited(block);
 
        /* set Phi predecessors */
-       for(i = 0; i < n_cfgpreds; ++i) {
+       for (i = 0; i < n_cfgpreds; ++i) {
                ir_node *pred_block = get_Block_cfgpred_block(block, i);
                ir_node *pred_val   = search_def_and_create_phis(pred_block, mode, 0);
 
@@ -206,9 +210,9 @@ static void split_critical_edge(ir_node *block, int pos)
 typedef struct jumpthreading_env_t {
        ir_node       *true_block;
        ir_node       *cmp;        /**< The Compare node that might be partial evaluated */
-       pn_Cmp         pnc;        /**< The Compare mode of the Compare node. */
+       ir_relation    relation;   /**< The Compare mode of the Compare node. */
        ir_node       *cnst;
-       tarval        *tv;
+       ir_tarval     *tv;
        ir_visited_t   visited_nr;
 
        ir_node       *cnst_pred;   /**< the block before the constant */
@@ -228,7 +232,7 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
                copy = get_Phi_pred(node, j);
                /* we might have to evaluate a Phi-cascade */
                if (get_irn_visited(copy) >= env->visited_nr) {
-                       copy = get_irn_link(copy);
+                       copy = (ir_node*)get_irn_link(copy);
                }
        } else {
                copy = exact_copy(node);
@@ -237,7 +241,7 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
                assert(get_irn_mode(copy) != mode_X);
 
                arity = get_irn_arity(copy);
-               for(i = 0; i < arity; ++i) {
+               for (i = 0; i < arity; ++i) {
                        ir_node *pred     = get_irn_n(copy, i);
                        ir_node *new_pred;
 
@@ -245,7 +249,7 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
                                continue;
 
                        if (get_irn_visited(pred) >= env->visited_nr) {
-                               new_pred = get_irn_link(pred);
+                               new_pred = (ir_node*)get_irn_link(pred);
                        } else {
                                new_pred = copy_and_fix_node(env, block, copy_block, j, pred);
                        }
@@ -271,12 +275,6 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
                ir_node *copy;
                ir_mode *mode;
 
-               if (is_Block(node)) {
-                       /* Block->Block edge, should be the MacroBlock edge */
-                       assert(get_Block_MacroBlock(node) == block && "Block->Block edge found");
-                       continue;
-               }
-
                /* ignore control flow */
                mode = get_irn_mode(node);
                if (mode == mode_X || is_Cond(node))
@@ -306,7 +304,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
 
                                cmp_copy = exact_copy(pred);
                                set_nodes_block(cmp_copy, user_block);
-                               copy = new_r_Proj(current_ir_graph, user_block, cmp_copy, mode_b, pn);
+                               copy = new_r_Proj(cmp_copy, mode_b, pn);
                                set_irn_n(user, pos, copy);
                        }
                        continue;
@@ -319,7 +317,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
                 * recursive find_phi_with_const() call */
                assert(get_irn_visited(copy) <= env->visited_nr);
                if (get_irn_visited(copy) >= env->visited_nr) {
-                       ir_node *prev_copy = get_irn_link(copy);
+                       ir_node *prev_copy = (ir_node*)get_irn_link(copy);
                        if (prev_copy != NULL)
                                set_irn_link(node, prev_copy);
                }
@@ -331,12 +329,6 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
                ir_node *copy_node;
                ir_mode *mode;
 
-               if (is_Block(node)) {
-                       /* Block->Block edge, should be the MacroBlock edge */
-                       assert(get_Block_MacroBlock(node) == block && "Block->Block edge found");
-                       continue;
-               }
-
                mode = get_irn_mode(node);
                if (mode == mode_X || is_Cond(node))
                        continue;
@@ -347,7 +339,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
 
                DB((dbg, LEVEL_2, ">> Fixing users of %+F\n", node));
 
-               copy_node = get_irn_link(node);
+               copy_node = (ir_node*)get_irn_link(node);
                construct_ssa(block, node, copy_block, copy_node);
        }
 }
@@ -356,44 +348,53 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
  * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
  *
- * @param pnc       the compare mode of the Compare
+ * @param relation  the compare mode of the Compare
  * @param tv_left   the left tarval
  * @param tv_right  the right tarval
  */
-static int eval_cmp_tv(pn_Cmp pnc, tarval *tv_left, tarval *tv_right)
+static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
+                       ir_tarval *tv_right)
 {
-       pn_Cmp cmp_result = tarval_cmp(tv_left, tv_right);
+       ir_relation cmp_result = tarval_cmp(tv_left, tv_right);
 
        /* does the compare evaluate to true? */
-       if (cmp_result == pn_Cmp_False)
+       if (cmp_result == ir_relation_false)
                return -1;
-       if ((cmp_result & pnc) != cmp_result)
-               return 0;
+       if ((cmp_result & relation) != 0)
+               return 1;
 
-       return 1;
+       return 0;
 }
 
+#if 0
+/* Matze: disabled, check first if the compare still is correct */
+
 /**
  * returns whether the cmp evaluates to true or false according to vrp
  * information , or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
  *
- * @param pnc       the compare mode of the Compare
- * @param left   the left node
- * @param right  the right node
+ * @param relation  the compare mode of the Compare
+ * @param left      the left node
+ * @param right     the right node
  */
-static int eval_cmp_vrp(pn_Cmp pnc, ir_node *left, ir_node *right)
+static int eval_cmp_vrp(ir_relation relation, ir_node *left, ir_node *right)
 {
-       pn_Cmp cmp_result = vrp_cmp(left, right);
-
+       ir_relation cmp_result = vrp_cmp(left, right);
        /* does the compare evaluate to true? */
-       if (cmp_result == pn_Cmp_False)
+       if (cmp_result == ir_relation_false)
                return -1;
-       if ((cmp_result & pnc) != cmp_result)
-               return 0;
 
+       if ((cmp_result & relation) != cmp_result) {
+               if ((cmp_result & relation) != 0) {
+                       return -1;
+               }
+               return 0;
+       }
        return 1;
 }
+#endif
+
 /**
  * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
@@ -404,12 +405,12 @@ static int eval_cmp_vrp(pn_Cmp pnc, ir_node *left, ir_node *right)
 static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
 {
        if (is_Const(cand)) {
-               tarval *tv_cand   = get_Const_tarval(cand);
-               tarval *tv_cmp    = get_Const_tarval(env->cnst);
+               ir_tarval *tv_cand = get_Const_tarval(cand);
+               ir_tarval *tv_cmp  = get_Const_tarval(env->cnst);
 
-               return eval_cmp_tv(env->pnc, tv_cand, tv_cmp);
+               return eval_cmp_tv(env->relation, tv_cand, tv_cmp);
        } else { /* a Confirm */
-               tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->pnc);
+               ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->relation);
 
                if (res == tarval_bad)
                        return -1;
@@ -430,7 +431,7 @@ static int is_Const_or_Confirm(const ir_node *node)
 /**
  * get the tarval of a Const or Confirm with
  */
-static tarval *get_Const_or_Confirm_tarval(const ir_node *node)
+static ir_tarval *get_Const_or_Confirm_tarval(const ir_node *node)
 {
        if (is_Confirm(node)) {
                if (get_Confirm_bound(node))
@@ -448,9 +449,8 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                return NULL;
 
        if (is_Const_or_Confirm(value)) {
-               if (eval_cmp(env, value) <= 0) {
+               if (eval_cmp(env, value) <= 0)
                        return NULL;
-               }
 
                DB((
                        dbg, LEVEL_1,
@@ -473,12 +473,11 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                int i, arity;
 
                /* the Phi has to be in the same Block as the Jmp */
-               if (get_nodes_block(value) != block) {
+               if (get_nodes_block(value) != block)
                        return NULL;
-               }
 
                arity = get_irn_arity(value);
-               for(i = 0; i < arity; ++i) {
+               for (i = 0; i < arity; ++i) {
                        ir_node *copy_block;
                        ir_node *phi_pred = get_Phi_pred(value, i);
                        ir_node *cfgpred  = get_Block_cfgpred(block, i);
@@ -513,7 +512,7 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
        }
 
        if (is_Const_or_Confirm(value)) {
-               tarval *tv = get_Const_or_Confirm_tarval(value);
+               ir_tarval *tv = get_Const_or_Confirm_tarval(value);
 
                if (tv != env->tv)
                        return NULL;
@@ -542,7 +541,7 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                        return NULL;
 
                arity = get_irn_arity(value);
-               for(i = 0; i < arity; ++i) {
+               for (i = 0; i < arity; ++i) {
                        ir_node *copy_block;
                        ir_node *phi_pred = get_Phi_pred(value, i);
                        ir_node *cfgpred  = get_Block_cfgpred(block, i);
@@ -563,17 +562,11 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                        return copy_block;
                }
        }
-       if (is_Proj(value)) {
-               ir_node *left;
-               ir_node *right;
-               int      pnc;
-               ir_node *cmp = get_Proj_pred(value);
-               if (!is_Cmp(cmp))
-                       return NULL;
-
-               left  = get_Cmp_left(cmp);
-               right = get_Cmp_right(cmp);
-               pnc   = get_Proj_proj(value);
+       if (is_Cmp(value)) {
+               ir_node    *cmp      = value;
+               ir_node    *left     = get_Cmp_left(cmp);
+               ir_node    *right    = get_Cmp_right(cmp);
+               ir_relation relation = get_Cmp_relation(cmp);
 
                /* we assume that the constant is on the right side, swap left/right
                 * if needed */
@@ -582,25 +575,24 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                        left       = right;
                        right      = t;
 
-                       pnc        = get_inversed_pnc(pnc);
+                       relation   = get_inversed_relation(relation);
                }
 
                if (!is_Const(right))
-                       return 0;
+                       return NULL;
 
-               if (get_nodes_block(left) != block) {
-                       return 0;
-               }
+               if (get_nodes_block(left) != block)
+                       return NULL;
 
                /* negate condition when we're looking for the false block */
                if (env->tv == tarval_b_false) {
-                       pnc = get_negated_pnc(pnc, get_irn_mode(right));
+                       relation = get_negated_relation(relation);
                }
 
                /* (recursively) look if a pred of a Phi is a constant or a Confirm */
-               env->cmp  = cmp;
-               env->pnc  = pnc;
-               env->cnst = right;
+               env->cmp      = cmp;
+               env->relation = relation;
+               env->cnst     = right;
 
                return find_const_or_confirm(env, jump, left);
        }
@@ -624,15 +616,16 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
 static void thread_jumps(ir_node* block, void* data)
 {
        jumpthreading_env_t env;
-       int *changed = data;
+       int *changed = (int*)data;
        ir_node *selector;
        ir_node *projx;
        ir_node *cond;
        ir_node *copy_block;
        int      selector_evaluated;
        const ir_edge_t *edge, *next;
+       ir_graph *irg;
        ir_node *bad;
-       size_t   cnst_pos;
+       int      cnst_pos;
 
        if (get_Block_n_cfgpreds(block) != 1)
                return;
@@ -653,30 +646,27 @@ static void thread_jumps(ir_node* block, void* data)
 
        /* handle cases that can be immediately evaluated */
        selector_evaluated = -1;
-       if (is_Proj(selector)) {
-               ir_node *cmp = get_Proj_pred(selector);
-               if (is_Cmp(cmp)) {
-                       ir_node *left  = get_Cmp_left(cmp);
-                       ir_node *right = get_Cmp_right(cmp);
-                       if (is_Const(left) && is_Const(right)) {
-                               int     pnc      = get_Proj_proj(selector);
-                               tarval *tv_left  = get_Const_tarval(left);
-                               tarval *tv_right = get_Const_tarval(right);
-
-                               selector_evaluated = eval_cmp_tv(pnc, tv_left, tv_right);
-                       }
-                       if (selector_evaluated < 0) {
-                               /* This is only the case if the predecessor nodes are not
-                                * constant or the comparison could not be evaluated.
-                                * Try with VRP information now.
-                                */
-                               int pnc = get_Proj_proj(selector);
-
-                               selector_evaluated = eval_cmp_vrp(pnc, left, right);
-                       }
+       if (is_Cmp(selector)) {
+               ir_node *left  = get_Cmp_left(selector);
+               ir_node *right = get_Cmp_right(selector);
+               if (is_Const(left) && is_Const(right)) {
+                       ir_relation relation = get_Cmp_relation(selector);
+                       ir_tarval  *tv_left  = get_Const_tarval(left);
+                       ir_tarval  *tv_right = get_Const_tarval(right);
+
+                       selector_evaluated = eval_cmp_tv(relation, tv_left, tv_right);
                }
+#if 0
+               if (selector_evaluated < 0) {
+                       /* This is only the case if the predecessor nodes are not
+                        * constant or the comparison could not be evaluated.
+                        * Try with VRP information now.
+                        */
+                       selector_evaluated = eval_cmp_vrp(relation, left, right);
+               }
+#endif
        } else if (is_Const_or_Confirm(selector)) {
-               tarval *tv = get_Const_or_Confirm_tarval(selector);
+               ir_tarval *tv = get_Const_or_Confirm_tarval(selector);
                if (tv == tarval_b_true) {
                        selector_evaluated = 1;
                } else {
@@ -695,7 +685,8 @@ static void thread_jumps(ir_node* block, void* data)
        }
 
        if (selector_evaluated == 0) {
-               bad = new_Bad();
+               ir_graph *irg = get_irn_irg(block);
+               bad = new_r_Bad(irg);
                exchange(projx, bad);
                *changed = 1;
                return;
@@ -710,8 +701,9 @@ static void thread_jumps(ir_node* block, void* data)
 
        /* (recursively) look if a pred of a Phi is a constant or a Confirm */
        env.true_block = block;
-       inc_irg_visited(current_ir_graph);
-       env.visited_nr = get_irg_visited(current_ir_graph);
+       irg = get_irn_irg(block);
+       inc_irg_visited(irg);
+       env.visited_nr = get_irg_visited(irg);
 
        copy_block = find_candidate(&env, projx, selector);
        if (copy_block == NULL)
@@ -720,7 +712,7 @@ static void thread_jumps(ir_node* block, void* data)
        /* we have to remove the edge towards the pred as the pred now
         * jumps into the true_block. We also have to shorten Phis
         * in our block because of this */
-       bad      = new_Bad();
+       bad      = new_r_Bad(irg);
        cnst_pos = env.cnst_pos;
 
        /* shorten Phis */