X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fjumpthreading.c;h=c6120eebb4f3b16ecadc8532db7f9d9c63ddbc70;hb=3398ae4a8b3cbf66cb0b274ddcd85a2ea863ece1;hp=3e53ddb6901b8d2d073b0786794ba2a5ceda8c2e;hpb=285b86f3385d400ffe803633f994380d8adb3b38;p=libfirm diff --git a/ir/opt/jumpthreading.c b/ir/opt/jumpthreading.c index 3e53ddb69..c6120eebb 100644 --- a/ir/opt/jumpthreading.c +++ b/ir/opt/jumpthreading.c @@ -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); @@ -190,7 +194,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; @@ -207,7 +212,7 @@ typedef struct jumpthreading_env_t { ir_node *cmp; /**< The Compare node that might be partial evaluated */ pn_Cmp pnc; /**< 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 */ @@ -227,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); @@ -236,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; @@ -244,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); } @@ -270,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)) @@ -305,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; @@ -318,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); } @@ -330,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; @@ -346,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); } } @@ -359,7 +352,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, * @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(pn_Cmp pnc, ir_tarval *tv_left, ir_tarval *tv_right) { pn_Cmp cmp_result = tarval_cmp(tv_left, tv_right); @@ -384,13 +377,16 @@ static int eval_cmp_tv(pn_Cmp pnc, tarval *tv_left, tarval *tv_right) 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) + if (cmp_result == pn_Cmp_False) { return -1; - if ((cmp_result & pnc) != cmp_result) + } + if ((cmp_result & pnc) != cmp_result) { + if ((cmp_result & pnc) != 0) { + return -1; + } return 0; - + } return 1; } /** @@ -403,12 +399,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); } 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->pnc); if (res == tarval_bad) return -1; @@ -429,7 +425,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)) @@ -477,7 +473,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); @@ -512,7 +508,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; @@ -541,7 +537,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); @@ -565,14 +561,14 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump, if (is_Proj(value)) { ir_node *left; ir_node *right; - int pnc; + pn_Cmp 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); + pnc = get_Proj_pn_cmp(value); /* we assume that the constant is on the right side, swap left/right * if needed */ @@ -623,15 +619,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; @@ -658,9 +655,9 @@ static void thread_jumps(ir_node* block, void* data) 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); + pn_Cmp pnc = get_Proj_pn_cmp(selector); + ir_tarval *tv_left = get_Const_tarval(left); + ir_tarval *tv_right = get_Const_tarval(right); selector_evaluated = eval_cmp_tv(pnc, tv_left, tv_right); } @@ -669,13 +666,13 @@ static void thread_jumps(ir_node* block, void* data) * constant or the comparison could not be evaluated. * Try with VRP information now. */ - int pnc = get_Proj_proj(selector); + pn_Cmp pnc = get_Proj_pn_cmp(selector); selector_evaluated = eval_cmp_vrp(pnc, left, right); } } } 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 { @@ -694,7 +691,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; @@ -709,8 +707,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) @@ -719,7 +718,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 */