X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Floop.c;h=8bc39fa52ecf74aec810f468a74b5026c41d9156;hb=4db6c5b3708319ba7eff5489e1fe1c7a01fdd866;hp=2635ced1131f8618b3cc912d28013bf56407ef9b;hpb=9d4e23060441530a20af5d331268435bfe18f305;p=libfirm diff --git a/ir/opt/loop.c b/ir/opt/loop.c index 2635ced11..8bc39fa52 100644 --- a/ir/opt/loop.c +++ b/ir/opt/loop.c @@ -378,7 +378,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi { int i; int n_cfgpreds; - ir_graph *irg; + ir_graph *irg = get_irn_irg(block); ir_node *phi; ir_node **in; @@ -388,7 +388,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi * Dead and bad blocks. */ if (get_irn_arity(block) < 1 || is_Bad(block)) { DB((dbg, LEVEL_5, "ssa bad %N\n", block)); - return new_Bad(); + return new_r_Bad(irg, mode); } if (block == ssa_second_def_block && !first) { @@ -403,7 +403,6 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi return value; } - irg = get_irn_irg(block); assert(block != get_irg_start_block(irg)); /* a Block with only 1 predecessor needs no Phi */ @@ -424,7 +423,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi /* create a new Phi */ NEW_ARR_A(ir_node*, in, n_cfgpreds); for (i = 0; i < n_cfgpreds; ++i) - in[i] = new_Unknown(mode); + in[i] = new_r_Dummy(irg, mode); phi = new_r_Phi(block, n_cfgpreds, in, mode); /* Important: always keep block phi list up to date. */ @@ -956,7 +955,7 @@ static void get_head_outs(ir_node *node, void *env) * (Some blocks need to be removed once again.) * Returns 1 if the given block belongs to the condition chain. */ -static unsigned find_condition_chain(ir_node *block) +static void find_condition_chain(ir_node *block) { const ir_edge_t *edge; unsigned mark = 0; @@ -979,7 +978,7 @@ static unsigned find_condition_chain(ir_node *block) * continuing with another subtree. */ if (loop_info.cc_size + nodes_n > opt_params.max_cc_size) { set_Block_mark(block, 0); - return 0; + return; } /* Check if block only has a jmp instruction. */ @@ -1042,8 +1041,6 @@ static unsigned find_condition_chain(ir_node *block) if (is_in_loop(src) && ! irn_visited(src)) find_condition_chain(src); } - - return mark; } /** @@ -1059,6 +1056,7 @@ static void fix_copy_inversion(void) ir_node **phis; ir_node *phi, *next; ir_node *head_cp = get_inversion_copy(loop_head); + ir_graph *irg = get_irn_irg(head_cp); int arity = get_irn_arity(head_cp); int backedges = get_backedge_n(head_cp, 0); int new_arity = arity - backedges; @@ -1074,7 +1072,7 @@ static void fix_copy_inversion(void) ins[pos++] = get_irn_n(head_cp, i); } - new_head = new_Block(new_arity, ins); + new_head = new_r_Block(irg, new_arity, ins); phis = NEW_ARR_F(ir_node *, 0); @@ -1113,6 +1111,7 @@ static void fix_head_inversion(void) ir_node **ins; ir_node *phi, *next; ir_node **phis; + ir_graph *irg = get_irn_irg(loop_head); int arity = get_irn_arity(loop_head); int backedges = get_backedge_n(loop_head, 0); int new_arity = backedges; @@ -1128,7 +1127,7 @@ static void fix_head_inversion(void) ins[pos++] = get_irn_n(loop_head, i); } - new_head = new_Block(new_arity, ins); + new_head = new_r_Block(irg, new_arity, ins); phis = NEW_ARR_F(ir_node *, 0); @@ -1285,7 +1284,6 @@ static void loop_inversion(void) int depth_adaption = opt_params.depth_adaption; unsigned do_inversion = 1; - unsigned has_cc = 0; /* Depth of 0 is the procedure and 1 a topmost loop. */ loop_depth = get_loop_depth(cur_loop) - 1; @@ -1347,7 +1345,7 @@ static void loop_inversion(void) /* Search for condition chains and temporarily save the blocks in an array. */ cc_blocks = NEW_ARR_F(ir_node *, 0); inc_irg_visited(current_ir_graph); - has_cc = find_condition_chain(loop_head); + find_condition_chain(loop_head); unmark_not_allowed_cc_blocks(); DEL_ARR_F(cc_blocks); @@ -1393,10 +1391,6 @@ static void loop_inversion(void) /* Duplicated blocks changed doms */ set_irg_doms_inconsistent(current_ir_graph); - /* Loop content changed */ - set_irg_loopinfo_inconsistent(current_ir_graph); - /* TODO are they? Depends on set_irn_in and set_irn_n exchange and new_node. */ - set_irg_outs_inconsistent(current_ir_graph); count_stats(stats.inverted); } @@ -1658,10 +1652,9 @@ static ir_node *new_Abs(ir_node *op, ir_mode *mode) ir_graph *irg = get_irn_irg(op); ir_node *block = get_nodes_block(op); ir_node *zero = new_r_Const(irg, get_mode_null(mode)); - ir_node *cmp = new_r_Cmp(block, op, zero); - ir_node *cond = new_r_Proj(cmp, mode_b, pn_Cmp_Lt); + ir_node *cmp = new_r_Cmp(block, op, zero, ir_relation_less); ir_node *minus_op = new_r_Minus(block, op, mode); - ir_node *mux = new_r_Mux(block, cond, op, minus_op, mode); + ir_node *mux = new_r_Mux(block, cmp, op, minus_op, mode); return mux; } @@ -1675,8 +1668,8 @@ static void create_duffs_block(void) ir_mode *mode; ir_node *block1, *count_block, *duff_block; - ir_node *ems, *ems_divmod, *ems_mod_proj, *cmp_null, - *cmp_proj, *ems_mode_cond, *x_true, *x_false, *const_null; + ir_node *ems, *ems_mod, *ems_div, *ems_mod_proj, *cmp_null, + *ems_mode_cond, *x_true, *x_false, *const_null; ir_node *true_val, *false_val; ir_node *ins[2]; @@ -1713,21 +1706,25 @@ static void create_duffs_block(void) ems = new_Sub(loop_info.end_val, loop_info.start_val, get_irn_mode(loop_info.end_val)); - DB((dbg, LEVEL_4, "divmod ins %N %N\n", ems, loop_info.step)); - ems_divmod = new_r_DivMod(block1, + DB((dbg, LEVEL_4, "mod ins %N %N\n", ems, loop_info.step)); + ems_mod = new_r_Mod(block1, + new_NoMem(), + ems, + loop_info.step, + mode, + op_pin_state_pinned); + ems_div = new_r_Div(block1, new_NoMem(), ems, loop_info.step, mode, op_pin_state_pinned); - DB((dbg, LEVEL_4, "New module node %N\n", ems_divmod)); - - ems_mod_proj = new_r_Proj(ems_divmod, mode_Iu, pn_DivMod_res_mod); - cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null); - cmp_proj = new_r_Proj(cmp_null, mode_b, pn_Cmp_Eq); - ems_mode_cond = new_r_Cond(block1, cmp_proj); + DB((dbg, LEVEL_4, "New module node %N\n", ems_mod)); + ems_mod_proj = new_r_Proj(ems_mod, mode_Iu, pn_Mod_res); + cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null, ir_relation_less); + ems_mode_cond = new_r_Cond(block1, cmp_null); /* ems % step == 0 */ x_true = new_r_Proj(ems_mode_cond, mode_X, pn_Cond_true); @@ -1767,13 +1764,11 @@ static void create_duffs_block(void) correction = new_r_Phi(count_block, 2, ins, mode); - count = new_r_Proj(ems_divmod, mode, pn_DivMod_res_div); + count = new_r_Proj(ems_div, mode, pn_Div_res); /* (end - start) / step + correction */ count = new_Add(count, correction, mode); - cmp_bad_count = new_r_Cmp(count_block, count, const_null); - /* We preconditioned the loop to be tail-controlled. * So, if count is something 'wrong' like 0, * negative/positive (depending on step direction), @@ -1782,12 +1777,14 @@ static void create_duffs_block(void) /* Depending on step direction, we have to check for > or < 0 */ if (loop_info.decreasing == 1) { - bad_count_neg = new_r_Proj(cmp_bad_count, mode_b, pn_Cmp_Lt); + cmp_bad_count = new_r_Cmp(count_block, count, const_null, + ir_relation_less); } else { - bad_count_neg = new_r_Proj(cmp_bad_count, mode_b, pn_Cmp_Gt); + cmp_bad_count = new_r_Cmp(count_block, count, const_null, + ir_relation_greater); } - bad_count_neg = new_r_Cond(count_block, bad_count_neg); + bad_count_neg = new_r_Cond(count_block, cmp_bad_count); good_count = new_Proj(bad_count_neg, mode_X, pn_Cond_true); bad_count = new_Proj(ems_mode_cond, mode_X, pn_Cond_false); @@ -1986,38 +1983,17 @@ static unsigned get_const_pred(ir_node *node, ir_node **const_pred, ir_node **ot return 1; } -/* Returns the mathematically inverted pn_Cmp. */ -static pn_Cmp get_math_inverted_case(pn_Cmp proj) -{ - switch(proj) { - case pn_Cmp_Eq: - return pn_Cmp_Lg; - case pn_Cmp_Lg: - return pn_Cmp_Eq; - case pn_Cmp_Lt: - return pn_Cmp_Ge; - case pn_Cmp_Le: - return pn_Cmp_Gt; - case pn_Cmp_Gt: - return pn_Cmp_Le; - case pn_Cmp_Ge: - return pn_Cmp_Lt; - default: - panic("Unhandled pn_Cmp."); - } -} - /* Returns 1 if loop exits within 2 steps of the iv. * Norm_proj means we do not exit the loop.*/ static unsigned simulate_next(ir_tarval **count_tar, ir_tarval *stepped, ir_tarval *step_tar, ir_tarval *end_tar, - pn_Cmp norm_proj) + ir_relation norm_proj) { ir_tarval *next; DB((dbg, LEVEL_4, "Loop taken if (stepped)%ld %s (end)%ld ", get_tarval_long(stepped), - get_pnc_string((norm_proj)), + get_relation_string((norm_proj)), get_tarval_long(end_tar))); DB((dbg, LEVEL_4, "comparing latest value %d\n", loop_info.latest_value)); @@ -2028,7 +2004,7 @@ static unsigned simulate_next(ir_tarval **count_tar, DB((dbg, LEVEL_4, "Result: (stepped)%ld IS %s (end)%ld\n", get_tarval_long(stepped), - get_pnc_string(tarval_cmp(stepped, end_tar)), + get_relation_string(tarval_cmp(stepped, end_tar)), get_tarval_long(end_tar))); /* next step */ @@ -2040,7 +2016,7 @@ static unsigned simulate_next(ir_tarval **count_tar, DB((dbg, LEVEL_4, "Loop taken if %ld %s %ld ", get_tarval_long(next), - get_pnc_string(norm_proj), + get_relation_string(norm_proj), get_tarval_long(end_tar))); DB((dbg, LEVEL_4, "comparing latest value %d\n", loop_info.latest_value)); @@ -2065,7 +2041,7 @@ static unsigned simulate_next(ir_tarval **count_tar, static ir_node *is_simple_loop(void) { int arity, i; - ir_node *loop_block, *exit_block, *projx, *cond, *projres, *loop_condition; + ir_node *loop_block, *exit_block, *projx, *cond, *cmp; /* Maximum of one condition, and no endless loops. */ if (loop_info.cf_outs != 1) @@ -2120,13 +2096,12 @@ static ir_node *is_simple_loop(void) /* find value on which loop exit depends */ projx = loop_info.cf_out.pred; cond = get_irn_n(projx, 0); - projres = get_irn_n(cond, 0); - loop_condition = get_irn_n(projres, 0); + cmp = get_irn_n(cond, 0); - if (!is_Cmp(loop_condition)) + if (!is_Cmp(cmp)) return NULL; - DB((dbg, LEVEL_5, "projection is %s\n", get_pnc_string(get_Proj_proj(projx)))); + DB((dbg, LEVEL_5, "projection is %s\n", get_relation_string(get_Proj_proj(projx)))); switch(get_Proj_proj(projx)) { case pn_Cond_false: @@ -2140,8 +2115,7 @@ static ir_node *is_simple_loop(void) } DB((dbg, LEVEL_4, "Valid Cmp.\n")); - - return projres; + return cmp; } /* Returns 1 if all nodes are mode_Iu or mode_Is. */ @@ -2164,7 +2138,7 @@ static unsigned get_unroll_decision_invariant(void) { ir_node *projres, *loop_condition, *iteration_path; - unsigned success, is_latest_val; + unsigned success; ir_tarval *step_tar; ir_mode *mode; @@ -2193,9 +2167,6 @@ static unsigned get_unroll_decision_invariant(void) * Until now we only have end_val. */ if (is_Add(iteration_path) || is_Sub(iteration_path)) { - /* We test against the latest value of the iv. */ - is_latest_val = 1; - loop_info.add = iteration_path; DB((dbg, LEVEL_4, "Case 1: Got add %N (maybe not sane)\n", loop_info.add)); @@ -2222,9 +2193,6 @@ static unsigned get_unroll_decision_invariant(void) } else if (is_Phi(iteration_path)) { ir_node *new_iteration_phi; - /* We compare with the value the iv had entering this run. */ - is_latest_val = 0; - loop_info.iteration_phi = iteration_path; DB((dbg, LEVEL_4, "Case 2: Got phi %N\n", loop_info.iteration_phi)); @@ -2370,15 +2338,16 @@ static unsigned get_preferred_factor_constant(ir_tarval *count_tar) /* TODO split. */ static unsigned get_unroll_decision_constant(void) { - ir_node *projres, *loop_condition, *iteration_path; - unsigned success, is_latest_val; - ir_tarval *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar, *stepped; - pn_Cmp proj_proj, norm_proj; - ir_mode *mode; + ir_node *cmp, *iteration_path; + unsigned success, is_latest_val; + ir_tarval *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar; + ir_tarval *stepped; + ir_relation proj_proj, norm_proj; + ir_mode *mode; /* RETURN if loop is not 'simple' */ - projres = is_simple_loop(); - if (projres == NULL) + cmp = is_simple_loop(); + if (cmp == NULL) return 0; /* One in of the loop condition needs to be loop invariant. => end_val @@ -2396,9 +2365,7 @@ static unsigned get_unroll_decision_constant(void) /\ */ - loop_condition = get_irn_n(projres, 0); - - success = get_const_pred(loop_condition, &loop_info.end_val, &iteration_path); + success = get_const_pred(cmp, &loop_info.end_val, &iteration_path); if (! success) return 0; @@ -2530,17 +2497,16 @@ static unsigned get_unroll_decision_constant(void) DB((dbg, LEVEL_4, "stepped to %ld\n", get_tarval_long(stepped))); - proj_proj = get_Proj_pn_cmp(projres); + proj_proj = get_Cmp_relation(cmp); /* Assure that norm_proj is the stay-in-loop case. */ if (loop_info.exit_cond == 1) - norm_proj = get_math_inverted_case(proj_proj); + norm_proj = get_negated_relation(proj_proj); else norm_proj = proj_proj; - DB((dbg, LEVEL_4, "normalized projection %s\n", get_pnc_string(norm_proj))); - + DB((dbg, LEVEL_4, "normalized projection %s\n", get_relation_string(norm_proj))); /* Executed at most once (stay in counting loop if a Eq b) */ - if (norm_proj == pn_Cmp_Eq) + if (norm_proj == ir_relation_equal) /* TODO Might be worth a warning. */ return 0; @@ -2653,9 +2619,6 @@ static void unroll_loop(void) count_stats(stats.invariant_unroll); set_irg_doms_inconsistent(current_ir_graph); - set_irg_loopinfo_inconsistent(current_ir_graph); - /* TODO is it? */ - set_irg_outs_inconsistent(current_ir_graph); DEL_ARR_F(loop_entries); }