X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fjumpthreading.c;h=945ca526b8cf1665600a39b9ee8d00c7c2c8d035;hb=8c82c6f54cb32864dd266bc1066a50db7bc8c073;hp=57b53acd5d8e16816fa836ccde5e5f5dadc9352a;hpb=ddfcdcb1227bd6fb6720f8485dc62995f7bfd98f;p=libfirm diff --git a/ir/opt/jumpthreading.c b/ir/opt/jumpthreading.c index 57b53acd5..945ca526b 100644 --- a/ir/opt/jumpthreading.c +++ b/ir/opt/jumpthreading.c @@ -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)) {