X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fjumpthreading.c;h=3f9e42e6d4ed7a6bb0a9ccef42660140ee7f7632;hb=01ddc5c06877693df7d5f286d43e433fedd87103;hp=1412eb8af2bebaa769224c34a86e6d652cc85eea;hpb=7213344d377bb242491dfb0c291b43157c3c81d6;p=libfirm diff --git a/ir/opt/jumpthreading.c b/ir/opt/jumpthreading.c index 1412eb8af..3f9e42e6d 100644 --- a/ir/opt/jumpthreading.c +++ b/ir/opt/jumpthreading.c @@ -44,6 +44,8 @@ #include "tv.h" #include "opt_confirms.h" #include "iropt_dbg.h" +#include "irpass.h" +#include "vrp.h" #undef AVOID_PHIB @@ -115,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); @@ -123,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); @@ -188,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; @@ -234,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; @@ -370,6 +373,30 @@ 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) { + if ((cmp_result & pnc) != 0) { + return -1; + } + 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 @@ -454,7 +481,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); @@ -518,7 +545,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); @@ -640,8 +667,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)) { @@ -741,3 +775,9 @@ void opt_jumpthreading(ir_graph* irg) optimize_cf(irg); } } + +/* Creates an ir_graph pass for opt_jumpthreading. */ +ir_graph_pass_t *opt_jumpthreading_pass(const char *name) +{ + return def_graph_pass(name ? name : "jumpthreading", opt_jumpthreading); +} /* opt_jumpthreading_pass */