diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 06:51:43 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 06:51:43 +0000 |
commit | d8a0d6b8af37fd836425e5d8e2f510c7e8753bd5 (patch) | |
tree | f5af72013d20563b8340bcf3462e935b8ad07bef /gcc | |
parent | 85c11f8971a88d45613596396aa8215103fbdd1c (diff) | |
download | gcc-d8a0d6b8af37fd836425e5d8e2f510c7e8753bd5.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123670 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/cfgloop.c | 2 | ||||
-rw-r--r-- | gcc/cfgloop.h | 3 | ||||
-rw-r--r-- | gcc/cfgloopmanip.c | 79 | ||||
-rw-r--r-- | gcc/predict.c | 4 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfgcleanup.c | 5 | ||||
-rw-r--r-- | gcc/tree-scalar-evolution.c | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-manip.c | 12 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.c | 14 |
10 files changed, 109 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6542dc83882..0309e9fa92f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 12ce92cdd9e..b30e3527a6c 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -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; diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index cbad81d27f0..15d55890f6a 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -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 \ diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 9ca3947a0c6..0e876e566e1 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -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. */ - FOR_EACH_BB (bb) + if (changed_bbs) { - if (changed_bbs - && (void *) (size_t) bb->loop_father->depth != bb->aux) - bitmap_set_bit (changed_bbs, bb->index); + FOR_EACH_BB (bb) + { + if ((void *) (size_t) bb->loop_father->depth != bb->aux) + bitmap_set_bit (changed_bbs, bb->index); - bb->aux = NULL; + 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 } diff --git a/gcc/predict.c b/gcc/predict.c index 097cfb86070..7cae1b720ed 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -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 (); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index fa4800e00c2..a0af80442e8 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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; diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 8cf66cb4a27..39dcfe7c3ab 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -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); diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 846d27414d5..955240b6895 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -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 diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index bce9890d6a4..30f853469fc 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -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. */ diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 777685af652..86b26562754 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -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, |