Functions |
bool | bb_loop_header_p (basic_block) |
void | init_loops_structure (struct function *, struct loops *, unsigned) |
struct loops * | flow_loops_find (struct loops *) |
void | disambiguate_loops_with_multiple_latches (void) |
void | flow_loops_free (struct loops *) |
void | flow_loops_dump (FILE *, void(*)(const struct loop *, FILE *, int), int) |
void | flow_loop_dump (const struct loop *, FILE *, void(*)(const struct loop *, FILE *, int), int) |
struct loop * | alloc_loop (void) |
void | flow_loop_free (struct loop *) |
int | flow_loop_nodes_find (basic_block, struct loop *) |
unsigned | fix_loop_structure (bitmap changed_bbs) |
bool | mark_irreducible_loops (void) |
void | release_recorded_exits (void) |
void | record_loop_exits (void) |
void | rescan_loop_exit (edge, bool, bool) |
void | flow_loop_tree_node_add (struct loop *, struct loop *) |
void | flow_loop_tree_node_remove (struct loop *) |
void | place_new_loop (struct function *, struct loop *) |
void | add_loop (struct loop *, struct loop *) |
bool | flow_loop_nested_p (const struct loop *, const struct loop *) |
bool | flow_bb_inside_loop_p (const struct loop *, const_basic_block) |
struct loop * | find_common_loop (struct loop *, struct loop *) |
struct loop * | superloop_at_depth (struct loop *, unsigned) |
int | num_loop_insns (const struct loop *) |
int | average_num_loop_insns (const struct loop *) |
unsigned | get_loop_level (const struct loop *) |
bool | loop_exit_edge_p (const struct loop *, const_edge) |
bool | loop_exits_to_bb_p (struct loop *, basic_block) |
bool | loop_exits_from_bb_p (struct loop *, basic_block) |
void | mark_loop_exit_edges (void) |
location_t | get_loop_location (struct loop *loop) |
basic_block * | get_loop_body (const struct loop *) |
unsigned | get_loop_body_with_size (const struct loop *, basic_block *, unsigned) |
basic_block * | get_loop_body_in_dom_order (const struct loop *) |
basic_block * | get_loop_body_in_bfs_order (const struct loop *) |
basic_block * | get_loop_body_in_custom_order (const struct loop *, int(*)(const void *, const void *)) |
vec< edge > | get_loop_exit_edges (const struct loop *) |
edge | single_exit (const struct loop *) |
edge | single_likely_exit (struct loop *loop) |
unsigned | num_loop_branches (const struct loop *) |
edge | loop_preheader_edge (const struct loop *) |
edge | loop_latch_edge (const struct loop *) |
void | add_bb_to_loop (basic_block, struct loop *) |
void | remove_bb_from_loops (basic_block) |
void | cancel_loop_tree (struct loop *) |
void | delete_loop (struct loop *) |
basic_block | create_preheader (struct loop *, int) |
void | create_preheaders (int) |
void | force_single_succ_latches (void) |
void | verify_loop_structure (void) |
bool | just_once_each_iteration_p (const struct loop *, const_basic_block) |
gcov_type | expected_loop_iterations_unbounded (const struct loop *) |
unsigned | expected_loop_iterations (const struct loop *) |
rtx | doloop_condition_get (rtx) |
bool | can_duplicate_loop_p (const struct loop *loop) |
edge | create_empty_if_region_on_edge (edge, tree) |
struct loop * | create_empty_loop_on_edge (edge, tree, tree, tree, tree, tree *, tree *, struct loop *) |
struct loop * | duplicate_loop (struct loop *, struct loop *) |
void | copy_loop_info (struct loop *loop, struct loop *target) |
void | duplicate_subloops (struct loop *, struct loop *) |
bool | duplicate_loop_to_header_edge (struct loop *, edge, unsigned, sbitmap, edge, vec< edge > *, int) |
struct loop * | loopify (edge, edge, basic_block, edge, edge, bool, unsigned, unsigned) |
struct loop * | loop_version (struct loop *, void *, basic_block *, unsigned, unsigned, unsigned, bool) |
bool | remove_path (edge) |
void | unloop (struct loop *, bool *, bitmap) |
void | scale_loop_frequencies (struct loop *, int, int) |
void | iv_analysis_loop_init (struct loop *) |
bool | iv_analyze (rtx, rtx, struct rtx_iv *) |
bool | iv_analyze_result (rtx, rtx, struct rtx_iv *) |
bool | iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *) |
rtx | get_iv_value (struct rtx_iv *, rtx) |
bool | biv_p (rtx, rtx) |
void | find_simple_exit (struct loop *, struct niter_desc *) |
void | iv_analysis_done (void) |
struct niter_desc * | get_simple_loop_desc (struct loop *loop) |
void | free_simple_loop_desc (struct loop *loop) |
static struct niter_desc * | simple_loop_desc () |
static struct loop * | get_loop () |
static unsigned | loop_depth () |
static struct loop * | loop_outer () |
static bool | loop_has_exit_edges () |
vec< loop_p, va_gc > * | get_loops () |
static unsigned | number_of_loops () |
static bool | loops_state_satisfies_p () |
static void | loops_state_set () |
static void | loops_state_clear () |
static void | fel_next () |
static void | fel_init () |
unsigned | estimate_reg_pressure_cost (unsigned, unsigned, bool, bool) |
void | init_set_costs (void) |
void | loop_optimizer_init (unsigned) |
void | loop_optimizer_finalize (void) |
void | unswitch_loops (void) |
void | unroll_and_peel_loops (int) |
void | doloop_optimize_loops (void) |
void | move_loop_invariants (void) |
void | scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound) |
vec< basic_block > | get_loop_hot_path (const struct loop *loop) |
static struct loop * | loop_outermost () |
void | record_niter_bound (struct loop *, double_int, bool, bool) |
HOST_WIDE_INT | get_estimated_loop_iterations_int (struct loop *) |
HOST_WIDE_INT | get_max_loop_iterations_int (struct loop *) |
bool | get_estimated_loop_iterations (struct loop *loop, double_int *nit) |
bool | get_max_loop_iterations (struct loop *loop, double_int *nit) |
int | bb_loop_depth (const_basic_block) |
static double_int | gcov_type_to_double_int () |
create_empty_loop_on_edge
|
| - pred_bb - ------ pred_bb ------
| | | | iv0 = initial_value |
| -----|----- ---------|-----------
| | ______ | entry_edge
| | entry_edge / | |
| | ====> | -V---V- loop_header -------------
| V | | iv_before = phi (iv0, iv_after) |
| - succ_bb - | ---|-----------------------------
| | | | |
| ----------- | ---V--- loop_body ---------------
| | | iv_after = iv_before + stride |
| | | if (iv_before < upper_bound) |
| | ---|--------------\--------------
| | | \ exit_e
| | V \
| | - loop_latch - V- succ_bb -
| | | | | |
| | /------------- -----------
| \ ___ /
Creates an empty loop as shown above, the IV_BEFORE is the SSA_NAME
that is used before the increment of IV. IV_BEFORE should be used for
adding code to the body that uses the IV. OUTER is the outer loop in
which the new loop should be inserted.
Both INITIAL_VALUE and UPPER_BOUND expressions are gimplified and
inserted on the loop entry edge. This implies that this function
should be used only when the UPPER_BOUND expression is a loop
invariant.
Create header, latch and wire up the loop.
Set immediate dominator information.
Initialize a loop structure and put it in a loop hierarchy.
TODO: Fix frequencies and counts.
Update dominators.
Modify edge flags.
Construct IV code in loop.
Insert loop exit condition.
unsigned estimate_reg_pressure_cost |
( |
unsigned |
n_new, |
|
|
unsigned |
n_old, |
|
|
bool |
speed, |
|
|
bool |
call_p |
|
) |
| |
Register pressure estimation for induction variable optimizations & loop
invariant motion.
Estimates cost of increased register pressure caused by making N_NEW new
registers live around the loop. N_OLD is the number of registers live
around the loop. If CALL_P is true, also take into account that
call-used registers may be clobbered in the loop body, reducing the
number of available registers before we spill.
If there is a call in the loop body, the call-clobbered registers
are not available for loop invariants.
If we have enough registers, we should use them and not restrict
the transformations unnecessarily.
If we are close to running out of registers, try to preserve
them.
If we run out of registers, it is very expensive to add another
one.
IRA regional allocation deals with high register pressure
better. So decrease the cost (to do more accurate the cost
calculation for IRA, we need to know how many registers lives
through the loop transparently).
struct loop* loop_version |
( |
struct loop * |
loop, |
|
|
void * |
cond_expr, |
|
|
basic_block * |
condition_bb, |
|
|
unsigned |
then_prob, |
|
|
unsigned |
then_scale, |
|
|
unsigned |
else_scale, |
|
|
bool |
place_after |
|
) |
| |
|
read |
Main entry point for Loop Versioning transformation.
This transformation given a condition and a loop, creates
-if (condition) { loop_copy1 } else { loop_copy2 },
where loop_copy1 is the loop transformed in one way, and loop_copy2
is the loop transformed in another way (or unchanged). 'condition'
may be a run time test for things that were not resolved by static
analysis (overlapping ranges (anti-aliasing), alignment, etc.).
THEN_PROB is the probability of the then edge of the if. THEN_SCALE
is the ratio by that the frequencies in the original loop should
be scaled. ELSE_SCALE is the ratio by that the frequencies in the
new loop should be scaled.
If PLACE_AFTER is true, we place the new loop after LOOP in the
instruction stream, otherwise it is placed before LOOP.
Record entry and latch edges for the loop
Note down head of loop as first_head.
Duplicate loop.
After duplication entry edge now points to new loop head block.
Note down new head as second_head.
Split loop entry edge and insert new block with cond expr.
loopify redirected latch_edge. Update its PENDING_STMTS.
loopify redirected condition_bb's succ edge. Update its PENDING_STMTS.
Adjust irreducible flag.
At this point condition_bb is loop preheader with two successors,
first_head and second_head. Make sure that loop preheader has only
one successor.
Referenced by scale_dominated_blocks_in_loop(), and vect_create_cond_for_alias_checks().
void unloop |
( |
struct loop * |
loop, |
|
|
bool * |
irred_invalidated, |
|
|
bitmap |
loop_closed_ssa_invalidated |
|
) |
| |
Remove the latch edge of a LOOP and update loops to indicate that
the LOOP was removed. After this function, original loop latch will
have no successor, which caller is expected to fix somehow.
If this may cause the information about irreducible regions to become
invalid, IRRED_INVALIDATED is set to true.
LOOP_CLOSED_SSA_INVALIDATED, if non-NULL, is a bitmap where we store
basic blocks that had non-trivial update on their loop_father.
This is relatively straightforward. The dominators are unchanged, as
loop header dominates loop latch, so the only thing we have to care of
is the placement of loops and basic blocks inside the loop tree. We
move them all to the loop->outer, and then let fix_bb_placements do
its work.
Remove the loop and free its data.
We do not pass IRRED_INVALIDATED to fix_bb_placements here, as even if
there is an irreducible region inside the cancelled loop, the flags will
be still correct.
void verify_loop_structure |
( |
void |
| ) |
|
Checks that information about loops is correct
-- sizes of loops are all right
-- results of get_loop_body really belong to the loop
-- loop header have just single entry edge and single latch edge
-- loop latches have only single successor that is header of their loop
-- irreducible loops are correctly marked
-- the cached loop depth and loop father of each bb is correct
We need up-to-date dominators, compute or verify them.
Check the headers.
Check the recorded loop father and sizes of loops.
Ignore this block if it is in an inner loop.
Check headers and latches.
Check irreducible loops.
Record old info.
Recount it.
Compare.
Check the recorded loop exits.
Check that the list forms a cycle, and all elements except
for the head are nonnull.
When a loop exit is also an entry edge which
can happen when avoiding CFG manipulations
then the last loop exited is the outer loop
of the loop entered.
@verbatim
Natural loop analysis code for GNU compiler. Copyright (C) 2002-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/.