GCC Middle and Back End API Reference
|
Data Structures | |
struct | loop_size |
Enumerations | |
enum | unroll_level { UL_SINGLE_ITER, UL_NO_GROWTH, UL_ALL } |
Variables | |
static vec< loop_p > | loops_to_unloop |
static vec< int > | loops_to_unloop_nunroll |
enum unroll_level |
@verbatim Induction variable canonicalization and loop peeling.
Copyright (C) 2004-2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/.
This pass detects the loops that iterate a constant number of times, adds a canonical induction variable (step -1, tested against 0) and replaces the exit test. This enables the less powerful rtl level analysis to use this information. This might spoil the code in some cases (by increasing register pressure). Note that in the case the new variable is not needed, ivopts will get rid of it, so it might only be a problem when there are no other linear induction variables. In that case the created optimization possibilities are likely to pay up. Additionally in case we detect that it is beneficial to unroll the loop completely, we do it right here to expose the optimization possibilities to the following passes.
Specifies types of loops that may be unrolled.
unsigned int canonicalize_induction_variables | ( | void | ) |
The main entry point of the pass. Adds canonical induction variables to the suitable loops.
References bitmap_empty_p(), canonicalize_loop_induction_variables(), cfun, changed, estimate_numbers_of_iterations(), free_numbers_of_iterations_estimates(), LI_FROM_INNERMOST, LOOP_CLOSED_SSA, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS, loops_state_satisfies_p(), mark_irreducible_loops(), need_ssa_update_p(), rewrite_into_loop_closed_ssa(), scev_reset(), UL_SINGLE_ITER, and unloop_loops().
Referenced by tree_ssa_loop_ivcanon().
|
static |
Adds a canonical induction variable to LOOP if suitable. CREATE_IV is true if we may create a new iv. UL determines which loops we are allowed to completely unroll. If TRY_EVAL is true, we try to determine the number of iterations of a loop by direct evaluation. Returns true if cfg is changed.
References chrec_contains_undetermined(), create_canonical_iv(), dump_file, dump_flags, find_loop_niter(), find_loop_niter_by_eval(), gimple_location(), HOST_WIDE_INT, just_once_each_iteration_p(), last_stmt(), max_loop_iterations_int(), loop::num, number_of_latch_executions(), print_generic_expr(), record_niter_bound(), remove_redundant_iv_tests(), single_exit(), single_likely_exit(), edge_def::src, tree_to_double_int(), and try_unroll_loop_completely().
Referenced by canonicalize_induction_variables(), and tree_unroll_loops_completely_1().
|
static |
Return true if OP in STMT will be constant after peeling LOOP.
References affine_iv::base, ctor_for_folding(), handled_component_p(), is_gimple_min_invariant(), loop_containing_stmt(), simple_iv(), and affine_iv::step.
Referenced by tree_estimate_loop_size().
|
static |
Adds a canonical induction variable to LOOP iterating NITER times. EXIT is the exit edge whose condition is replaced.
References build_int_cst(), create_iv(), dump_file, dump_flags, edge_def::flags, gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gsi_last_bb(), last_stmt(), loop::num, print_generic_expr(), edge_def::src, type(), and update_stmt().
Referenced by canonicalize_loop_induction_variables().
|
static |
Estimate number of insns of completely unrolled loop. It is (NUNROLL + 1) * size of loop body with taking into account the fact that in last copy everything after exit conditional is dead and that some instructions will be eliminated after peeling. Loop body is likely going to simplify further, this is difficult to guess, we just decrease the result by 1/3.
References loop_size::eliminated_by_peeling, HOST_WIDE_INT, loop_size::last_iteration, loop_size::last_iteration_eliminated_by_peeling, and loop_size::overall.
Referenced by try_unroll_loop_completely().
edge loop_edge_to_cancel | ( | ) |
Loop LOOP is known to not loop. See if there is an edge in the loop body that can be remove to make the loop to always exit and at the same time it does not make any code potentially executed during the last iteration dead. After complette unrolling we still may get rid of the conditional on the exit in the last copy even if we have no idea what it does. This is quite common case for loops of form int a[5]; for (i=0;i<b;i++) a[i]=0; Here we prove the loop to iterate 5 times but we do not know it from induction variable. For now we handle only simple case where there is exit condition just before the latch block and the latch block contains no statements with side effect that may otherwise terminate the execution of loop (such as by EH or by terminating the program or longjmp). In the general case we may want to cancel the paths leading to statements loop-niter identified as having undefined effect in the last iteration. The other cases are hopefully rare and will be cleaned up later.
References edge_def::dest, edge_def::flags, get_loop_exit_edges(), gimple_has_side_effects(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), loop::header, loop::latch, basic_block_def::preds, edge_def::src, and basic_block_def::succs.
Referenced by try_unroll_loop_completely().
|
static |
Propagate constant SSA_NAMEs defined in basic block BB.
References gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_phi_arg_def(), gimple_phi_num_args(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_remove(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), is_gimple_assign(), propagate_into_all_uses(), and release_ssa_name().
Referenced by tree_unroll_loops_completely().
|
static |
Propagate VAL into all uses of SSA_NAME.
References fold_stmt_inplace(), get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs_code(), GIMPLE_SINGLE_RHS, gsi_for_stmt(), is_gimple_assign(), maybe_clean_or_replace_eh_stmt(), recompute_tree_invariant_for_addr_expr(), and update_stmt().
Referenced by propagate_constants_for_unrolling().
|
static |
Remove all tests for exits that are known to be taken after LOOP was peeled NPEELED times. Put gcc_unreachable before every statement known to not be executed.
References nb_iter_bound::bound, loop::bounds, builtin_decl_implicit(), changed, dump_file, dump_flags, edge_def::flags, double_int::from_uhwi(), gimple_bb(), gimple_build_call(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_location(), gimple_set_location(), gsi_for_stmt(), gsi_insert_before(), GSI_NEW_STMT, nb_iter_bound::is_exit, loop_exit_edge_p(), nb_iter_bound::next, print_gimple_stmt(), nb_iter_bound::stmt, double_int::ule(), double_int::ult(), and update_stmt().
Referenced by unloop_loops().
|
static |
Remove all exits that are known to be never taken because of the loop bound discovered.
References loop::any_upper_bound, tree_niter_desc::assumptions, nb_iter_bound::bound, loop::bounds, changed, dump_file, dump_flags, edge_def::flags, gimple_bb(), gimple_cond_make_false(), gimple_cond_make_true(), integer_onep(), integer_zerop(), nb_iter_bound::is_exit, loop_exit_edge_p(), tree_niter_desc::may_be_zero, loop::nb_iterations_upper_bound, nb_iter_bound::next, tree_niter_desc::niter, number_of_iterations_exit(), print_gimple_stmt(), nb_iter_bound::stmt, tree_to_double_int(), double_int::ult(), and update_stmt().
Referenced by canonicalize_loop_induction_variables().
|
static |
Computes an estimated number of insns in LOOP. EXIT (if non-NULL) is an exite edge that will be eliminated in all but last iteration of the loop. EDGE_TO_CANCEL (if non-NULL) is an non-exit edge eliminated in the last iteration of loop. Return results in SIZE, estimate benefits for complete unrolling exiting by EXIT. Stop estimating after UPPER_BOUND is met. Return true in this case.
References CDI_DOMINATORS, constant_after_peeling(), loop_size::constant_iv, dominated_by_p(), dump_file, dump_flags, loop_size::eliminated_by_peeling, eni_size_weights, estimate_num_insns(), free(), get_loop_body(), get_loop_hot_path(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_class(), GIMPLE_BINARY_RHS, gimple_call_flags(), gimple_call_fndecl(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_has_side_effects(), gimple_switch_index(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_inexpensive_builtin(), loop_size::last_iteration, loop_size::last_iteration_eliminated_by_peeling, last_stmt(), loop_size::non_call_stmts_on_hot_path, loop::num, loop_size::num_branches_on_hot_path, loop::num_nodes, loop_size::num_non_pure_calls_on_hot_path, loop_size::num_pure_calls_on_hot_path, loop_size::overall, path, print_gimple_stmt(), and edge_def::src.
Referenced by try_unroll_loop_completely().
unsigned tree_num_loop_insns | ( | ) |
Computes an estimated number of insns in LOOP, weighted by WEIGHTS.
References estimate_num_insns(), free(), get_loop_body(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), and loop::num_nodes.
unsigned int tree_unroll_loops_completely | ( | ) |
Unroll LOOPS completely if they iterate just few times. Unless MAY_INCREASE_SIZE is true, perform the unrolling only if the size of the code does not increase.
References loop::aux, bitmap_empty_p(), changed, cleanup_tree_cfg(), estimate_numbers_of_iterations(), free(), free_numbers_of_iterations_estimates(), get_loop_body_in_dom_order(), LOOP_CLOSED_SSA, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS, loops_state_satisfies_p(), mark_irreducible_loops(), propagate_constants_for_unrolling(), rewrite_into_loop_closed_ssa(), scev_reset(), tree_unroll_loops_completely_1(), unloop_loops(), update_ssa(), and verify_loop_closed_ssa().
|
static |
Process loops from innermost to outer, stopping at the innermost loop we unrolled.
References loop::aux, canonicalize_loop_induction_variables(), changed, loop::force_vect, loop::inner, loop_outer(), loop::next, optimize_loop_nest_for_speed_p(), ul, UL_ALL, and UL_NO_GROWTH.
Referenced by tree_unroll_loops_completely().
|
static |
Tries to unroll LOOP completely, i.e. NITER times. UL determines which loops we are allowed to unroll. EXIT is the exit of the loop that should be eliminated. MAXITER specfy bound on number of iterations, -1 if it is not known or too large for HOST_WIDE_INT. The location LOCUS corresponding to the loop is used when emitting a summary of the unroll to the dump file.
References bitmap_clear_bit(), bitmap_ones(), loop_size::constant_iv, basic_block_def::count, dump_enabled_p(), dump_file, dump_flags, dump_printf(), dump_printf_loc(), estimated_unrolled_size(), edge_def::flags, free(), free_original_copy_tables(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_duplicate_loop_to_header_edge(), loop::header, host_integerp(), HOST_WIDE_INT, initialize_original_copy_tables(), loop::inner, last_stmt(), loop_edge_to_cancel(), loop_preheader_edge(), loop::ninsns, loop_size::non_call_stmts_on_hot_path, loop::num, loop_size::num_branches_on_hot_path, loop_size::num_non_pure_calls_on_hot_path, loop_size::num_pure_calls_on_hot_path, loop_size::overall, profile_info, remove_path(), sbitmap_alloc(), edge_def::src, tree_estimate_loop_size(), tree_low_cst(), UL_NO_GROWTH, UL_SINGLE_ITER, update_stmt(), and vNULL.
Referenced by canonicalize_loop_induction_variables().
void unloop_loops | ( | bitmap | loop_closed_ssa_invalidated, |
bool * | irred_invalidated | ||
) |
Cancel all fully unrolled loops by putting __builtin_unreachable on the latch edge. We do it after all unrolling since unlooping moves basic blocks across loop boundaries trashing loop closed SSA form as well as SCEV info needed to be intact during unrolling. IRRED_INVALIDATED is used to bookkeep if information about irreducible regions may become invalid as a result of the transformation. LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case when we need to go into loop closed SSA form.
References builtin_decl_implicit(), CDI_DOMINATORS, edge_def::count, basic_block_def::count, create_basic_block(), edge_def::dest, edge_def::flags, basic_block_def::frequency, gimple_build_call(), edge_def::goto_locus, gsi_insert_after(), GSI_NEW_STMT, gsi_start_bb(), loop::latch, basic_block_def::loop_father, loop_latch_edge(), make_edge(), edge_def::probability, remove_exits_and_undefined_stmts(), set_immediate_dominator(), edge_def::src, and unloop().
Referenced by canonicalize_induction_variables(), and tree_unroll_loops_completely().
Stores loops that will be unlooped after we process whole loop tree.
|
static |