Loop unrolling implemented. Unrolling passes every test of the testsuite.
[libfirm] / ir / opt / jumpthreading.c
index 0552820..945ca52 100644 (file)
@@ -44,7 +44,8 @@
 #include "tv.h"
 #include "opt_confirms.h"
 #include "iropt_dbg.h"
-#include "irtools.h"
+#include "irpass.h"
+#include "vrp.h"
 
 #undef AVOID_PHIB
 
@@ -116,7 +117,7 @@ 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)
+       for (i = 0; i < n_cfgpreds; ++i)
                in[i] = new_Unknown(mode);
 
        phi = new_r_Phi(block, n_cfgpreds, in, mode);
@@ -124,7 +125,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
        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);
 
@@ -189,7 +190,8 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
        }
 }
 
-static void split_critical_edge(ir_node *block, int pos) {
+static void split_critical_edge(ir_node *block, int pos)
+{
        ir_graph *irg = get_irn_irg(block);
        ir_node *in[1];
        ir_node *new_block;
@@ -235,7 +237,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;
 
@@ -371,6 +373,27 @@ static int eval_cmp_tv(pn_Cmp pnc, tarval *tv_left, tarval *tv_right)
        return 1;
 }
 
+/**
+ * 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
+ */
+static int eval_cmp_vrp(pn_Cmp pnc, ir_node *left, ir_node *right)
+{
+       pn_Cmp cmp_result = vrp_cmp(left, right);
+
+       /* does the compare evaluate to true? */
+       if (cmp_result == pn_Cmp_False)
+               return -1;
+       if ((cmp_result & pnc) != cmp_result)
+               return 0;
+
+       return 1;
+}
 /**
  * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
@@ -455,7 +478,7 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                }
 
                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);
@@ -519,7 +542,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);
@@ -641,8 +664,15 @@ static void thread_jumps(ir_node* block, void* data)
                                tarval *tv_right = get_Const_tarval(right);
 
                                selector_evaluated = eval_cmp_tv(pnc, tv_left, tv_right);
-                               if (selector_evaluated < 0)
-                                       return;
+                       }
+                       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);
                        }
                }
        } else if (is_Const_or_Confirm(selector)) {
@@ -744,7 +774,7 @@ void opt_jumpthreading(ir_graph* irg)
 }
 
 /* Creates an ir_graph pass for opt_jumpthreading. */
-ir_graph_pass_t *opt_jumpthreading_pass(const char *name, int verify, int dump)
+ir_graph_pass_t *opt_jumpthreading_pass(const char *name)
 {
-       return def_graph_pass(name ? name : "jumpthreading", verify, dump, opt_jumpthreading);
+       return def_graph_pass(name ? name : "jumpthreading", opt_jumpthreading);
 }  /* opt_jumpthreading_pass */