cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.

* cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
	(create_preheaders): Check that loops are available.
	(fix_loop_structure): Clean up, improve comments.
	* tree-ssa-loop-manip.c (rewrite_into_loop_closed_ssa):
	Check that loops are available.  Set LOOP_CLOSED_SSA to the loops
	state flags.
	* tree-scalar-evolution.c (scev_finalize): Clear scalar_evolution_info.
	* predict.c (tree_estimate_probability): Do not call
	calculate_dominance_info.  Call create_preheaders.
	* tree-cfgcleanup.c (cleanup_tree_cfg_loop): Only call
	rewrite_into_loop_closed_ssa if LOOP_CLOSED_SSA is set in loops state
	flags.
	* cfgloop.c (loop_preheader_edge): Assert that loops have preheaders.
	* cfgloop.h (LOOP_CLOSED_SSA): New constant.
	* tree-cfg.c (tree_split_edge): Make an assert more precise.
	* tree-ssa-threadedge.c (thread_across_edge): Comment the function
	arguments.

From-SVN: r123670
This commit is contained in:
Zdenek Dvorak 2007-04-09 08:51:43 +02:00 committed by Zdenek Dvorak
parent 782c9150c3
commit c7b852c8a6
10 changed files with 113 additions and 37 deletions

View File

@ -1,3 +1,23 @@
2007-04-09 Zdenek Dvorak <dvorakz@suse.cz>
* cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
(create_preheaders): Check that loops are available.
(fix_loop_structure): Clean up, improve comments.
* tree-ssa-loop-manip.c (rewrite_into_loop_closed_ssa):
Check that loops are available. Set LOOP_CLOSED_SSA to the loops
state flags.
* tree-scalar-evolution.c (scev_finalize): Clear scalar_evolution_info.
* predict.c (tree_estimate_probability): Do not call
calculate_dominance_info. Call create_preheaders.
* tree-cfgcleanup.c (cleanup_tree_cfg_loop): Only call
rewrite_into_loop_closed_ssa if LOOP_CLOSED_SSA is set in loops state
flags.
* cfgloop.c (loop_preheader_edge): Assert that loops have preheaders.
* cfgloop.h (LOOP_CLOSED_SSA): New constant.
* tree-cfg.c (tree_split_edge): Make an assert more precise.
* tree-ssa-threadedge.c (thread_across_edge): Comment the function
arguments.
2007-04-08 Jan Hubicka <jh@suse.cz>
* tree.h (maybe_fold_offset_to_component_ref): Declare.

View File

@ -1548,6 +1548,8 @@ loop_preheader_edge (const struct loop *loop)
edge e;
edge_iterator ei;
gcc_assert ((current_loops->state & LOOPS_HAVE_PREHEADERS) != 0);
FOR_EACH_EDGE (e, ei, loop->header->preds)
if (e->src != loop->latch)
break;

View File

@ -169,7 +169,8 @@ enum
LOOPS_HAVE_SIMPLE_LATCHES = 2,
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
LOOPS_HAVE_RECORDED_EXITS = 8,
LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16
LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
LOOP_CLOSED_SSA = 32
};
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \

View File

@ -1105,7 +1105,7 @@ create_preheader (struct loop *loop, int flags)
int nentry = 0;
bool irred = false;
bool latch_edge_was_fallthru;
edge one_succ_pred = 0;
edge one_succ_pred = NULL, single_entry = NULL;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, loop->header->preds)
@ -1114,21 +1114,20 @@ create_preheader (struct loop *loop, int flags)
continue;
irred |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
nentry++;
single_entry = e;
if (single_succ_p (e->src))
one_succ_pred = e;
}
gcc_assert (nentry);
if (nentry == 1)
{
e = loop_preheader_edge (loop);
if (/* We do not allow entry block to be the loop preheader, since we
cannot emit code there. */
e->src != ENTRY_BLOCK_PTR
single_entry->src != ENTRY_BLOCK_PTR
/* If we want simple preheaders, also force the preheader to have
just a single successor. */
&& !((flags & CP_SIMPLE_PREHEADERS)
&& !single_succ_p (e->src)))
&& !single_succ_p (single_entry->src)))
return NULL;
}
@ -1177,6 +1176,9 @@ create_preheaders (int flags)
loop_iterator li;
struct loop *loop;
if (!current_loops)
return;
FOR_EACH_LOOP (li, loop, 0)
create_preheader (loop, flags);
current_loops->state |= LOOPS_HAVE_PREHEADERS;
@ -1380,19 +1382,33 @@ fix_loop_structure (bitmap changed_bbs)
basic_block bb;
struct loop *loop, *ploop;
loop_iterator li;
bool record_exits = false;
struct loop **superloop = XNEWVEC (struct loop *, number_of_loops ());
/* Remove the old bb -> loop mapping. */
gcc_assert (current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES);
/* Remove the old bb -> loop mapping. Remember the depth of the blocks in
the loop hierarchy, so that we can recognize blocks whose loop nesting
relationship has changed. */
FOR_EACH_BB (bb)
{
bb->aux = (void *) (size_t) bb->loop_father->depth;
if (changed_bbs)
bb->aux = (void *) (size_t) bb->loop_father->depth;
bb->loop_father = current_loops->tree_root;
}
/* Remove the dead loops from structures. */
current_loops->tree_root->num_nodes = n_basic_blocks;
FOR_EACH_LOOP (li, loop, 0)
if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
{
release_recorded_exits ();
record_exits = true;
}
/* Remove the dead loops from structures. We start from the innermost
loops, so that when we remove the loops, we know that the loops inside
are preserved, and do not waste time relinking loops that will be
removed later. */
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
loop->num_nodes = 0;
if (loop->header)
continue;
@ -1407,39 +1423,52 @@ fix_loop_structure (bitmap changed_bbs)
delete_loop (loop);
}
/* Rescan the bodies of loops, starting from the outermost. */
/* Rescan the bodies of loops, starting from the outermost ones. We assume
that no optimization interchanges the order of the loops, i.e., it cannot
happen that L1 was superloop of L2 before and it is subloop of L2 now
(without explicitly updating loop information). At the same time, we also
determine the new loop structure. */
current_loops->tree_root->num_nodes = n_basic_blocks;
FOR_EACH_LOOP (li, loop, 0)
{
superloop[loop->num] = loop->header->loop_father;
loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
}
/* Now fix the loop nesting. */
FOR_EACH_LOOP (li, loop, 0)
{
bb = loop_preheader_edge (loop)->src;
if (bb->loop_father != loop->outer)
ploop = superloop[loop->num];
if (ploop != loop->outer)
{
flow_loop_tree_node_remove (loop);
flow_loop_tree_node_add (bb->loop_father, loop);
flow_loop_tree_node_add (ploop, loop);
}
}
free (superloop);
/* Mark the blocks whose loop has changed. */
if (changed_bbs)
{
FOR_EACH_BB (bb)
{
if ((void *) (size_t) bb->loop_father->depth != bb->aux)
bitmap_set_bit (changed_bbs, bb->index);
bb->aux = NULL;
}
}
/* Mark the blocks whose loop has changed. */
FOR_EACH_BB (bb)
{
if (changed_bbs
&& (void *) (size_t) bb->loop_father->depth != bb->aux)
bitmap_set_bit (changed_bbs, bb->index);
bb->aux = NULL;
}
if (current_loops->state & LOOPS_HAVE_PREHEADERS)
create_preheaders (CP_SIMPLE_PREHEADERS);
if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
mark_irreducible_loops ();
if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
{
release_recorded_exits ();
record_loop_exits ();
}
if (record_exits)
record_loop_exits ();
#ifdef ENABLE_CHECKING
verify_loop_structure ();
#endif
}

View File

@ -1290,7 +1290,9 @@ tree_estimate_probability (void)
add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit ();
calculate_dominance_info (CDI_DOMINATORS);
/* We use loop_niter_by_eval, which requires that the loops have
preheaders. */
create_preheaders (CP_SIMPLE_PREHEADERS);
calculate_dominance_info (CDI_POST_DOMINATORS);
tree_bb_level_predictions ();

View File

@ -3118,7 +3118,7 @@ tree_split_edge (edge edge_in)
new_edge->count = edge_in->count;
e = redirect_edge_and_branch (edge_in, new_bb);
gcc_assert (e);
gcc_assert (e == edge_in);
reinstall_phi_args (new_edge, e);
return new_bb;

View File

@ -599,7 +599,7 @@ cleanup_tree_cfg_loop (void)
{
bool changed = cleanup_tree_cfg ();
if (changed)
if (changed && current_loops != NULL)
{
bitmap changed_bbs = BITMAP_ALLOC (NULL);
calculate_dominance_info (CDI_DOMINATORS);
@ -608,7 +608,8 @@ cleanup_tree_cfg_loop (void)
/* This usually does nothing. But sometimes parts of cfg that originally
were inside a loop get out of it due to edge removal (since they
become unreachable by back edges from latch). */
rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
if ((current_loops->state & LOOP_CLOSED_SSA) != 0)
rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
BITMAP_FREE (changed_bbs);

View File

@ -2862,6 +2862,7 @@ scev_finalize (void)
{
htab_delete (scalar_evolution_info);
BITMAP_FREE (already_instantiated);
scalar_evolution_info = NULL;
}
/* Replace ssa names for that scev can prove they are constant by the

View File

@ -355,10 +355,16 @@ find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks, bitmap need_phis)
void
rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
{
bitmap loop_exits = get_loops_exits ();
bitmap loop_exits;
bitmap *use_blocks;
unsigned i, old_num_ssa_names;
bitmap names_to_rename = BITMAP_ALLOC (NULL);
bitmap names_to_rename;
if (!current_loops)
return;
loop_exits = get_loops_exits ();
names_to_rename = BITMAP_ALLOC (NULL);
/* If the pass has caused the SSA form to be out-of-date, update it
now. */
@ -383,6 +389,8 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
/* Fix up all the names found to be used outside their original
loops. */
update_ssa (TODO_update_ssa);
current_loops->state |= LOOP_CLOSED_SSA;
}
/* Check invariants of the loop closed ssa form for the USE in BB. */

View File

@ -488,7 +488,19 @@ simplify_control_stmt_condition (edge e,
Note it is quite common for the first block inside a loop to
end with a conditional which is either always true or always
false when reached via the loop backedge. Thus we do not want
to blindly disable threading across a loop backedge. */
to blindly disable threading across a loop backedge.
DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
to avoid allocating memory.
HANDLE_DOMINATING_ASSERTS is true if we should try to replace operands of
the simplified condition with left-hand sides of ASSERT_EXPRs they are
used in.
STACK is used to undo temporary equivalences created during the walk of
E->dest.
SIMPLIFY is a pass-specific function used to simplify statements. */
void
thread_across_edge (tree dummy_cond,