diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-03 13:18:28 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-03 13:18:28 +0000 |
commit | b18878555c397f5aab203df348bfa33d114ee242 (patch) | |
tree | 5ae15df89724e96bf58d1a0b6e82cf43aa9b2617 /gcc/tree-ssa-loop-ivcanon.c | |
parent | d0b2c064ddbe9f8680a11522d16403a9b5826e1b (diff) | |
download | gcc-b18878555c397f5aab203df348bfa33d114ee242.tar.gz |
* gcc.dg/tree-ssa/loop-24.c: Update dump file matching; enable -O2.
* gcc.dg/tree-ssa/loop-25.c: Likewise.
* gcc.dg/tree-ssa/loop-26.c: Likewise.
* gcc.dg/tree-ssa/pr32044.c: Likewise.
* gcc.dg/tree-ssa/loop-29.c: Likewise.
* gcc.dg/tree-ssa/loop-10.c: Likewise.
* gnat.dg/loop_optimization6.adb: Enable -O2.
* ipa-pure-const.c (analyze): Update loop optimizer init.
* tree-ssa-loop-iv-canon.c (empty_loop_p, remove_empty_loop,
try_remove_empty_loop, remove_empty_loops): Remove.
* tree-ssa-loop.c (tree_ssa_empty_loop, pass_empty_loop): Remove.
* tree-ssa-dce.c (find_obviously_necessary_stmts): Use finiteness info
to mark regular loops as neccesary.
(degenerate_phi_p): New function.
(propagate_necessity, remove_dead_phis): Use it.
(forward_edge_to_pdom): Likewise.
(eliminate_unnecessary_stmts): Take care to remove uses of results of
virtual PHI nodes that became unreachable.
(perform_tree_ssa_dce): Initialize/deinitialize loop optimizer.
* tree-flow.h (remove_empty_loops): Remove.
* passes.c (init_optimization_passes): Remove.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivcanon.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.c | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 8e45bbb97e6..a04466a4027 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -558,187 +558,3 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) return 0; } - -/* Checks whether LOOP is empty. */ - -static bool -empty_loop_p (struct loop *loop) -{ - edge exit; - basic_block *body; - gimple_stmt_iterator gsi; - unsigned i; - - /* If the loop has multiple exits, it is too hard for us to handle. - Similarly, if the exit is not dominating, we cannot determine - whether the loop is not infinite. */ - exit = single_dom_exit (loop); - if (!exit) - return false; - - /* The loop must be finite. */ - if (!finite_loop_p (loop)) - return false; - - /* Values of all loop exit phi nodes must be invariants. */ - for (gsi = gsi_start(phi_nodes (exit->dest)); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple phi = gsi_stmt (gsi); - tree def; - - if (!is_gimple_reg (PHI_RESULT (phi))) - continue; - - def = PHI_ARG_DEF_FROM_EDGE (phi, exit); - - if (!expr_invariant_in_loop_p (loop, def)) - return false; - } - - /* And there should be no memory modifying or from other reasons - unremovable statements. */ - body = get_loop_body (loop); - for (i = 0; i < loop->num_nodes; i++) - { - /* Irreducible region might be infinite. */ - if (body[i]->flags & BB_IRREDUCIBLE_LOOP) - { - free (body); - return false; - } - - for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - - if (gimple_vdef (stmt) - || gimple_has_volatile_ops (stmt)) - { - free (body); - return false; - } - - /* Also, asm statements and calls may have side effects and we - cannot change the number of times they are executed. */ - switch (gimple_code (stmt)) - { - case GIMPLE_CALL: - if (gimple_has_side_effects (stmt)) - { - free (body); - return false; - } - break; - - case GIMPLE_ASM: - /* We cannot remove volatile assembler. */ - if (gimple_asm_volatile_p (stmt)) - { - free (body); - return false; - } - break; - - default: - break; - } - } - } - free (body); - - return true; -} - -/* Remove LOOP by making it exit in the first iteration. */ - -static void -remove_empty_loop (struct loop *loop) -{ - edge exit = single_dom_exit (loop), non_exit; - gimple cond_stmt = last_stmt (exit->src); - basic_block *body; - unsigned n_before, freq_in, freq_h; - gcov_type exit_count = exit->count; - - if (dump_file) - fprintf (dump_file, "Removing empty loop %d\n", loop->num); - - non_exit = EDGE_SUCC (exit->src, 0); - if (non_exit == exit) - non_exit = EDGE_SUCC (exit->src, 1); - - if (exit->flags & EDGE_TRUE_VALUE) - gimple_cond_make_true (cond_stmt); - else - gimple_cond_make_false (cond_stmt); - update_stmt (cond_stmt); - - /* Let us set the probabilities of the edges coming from the exit block. */ - exit->probability = REG_BR_PROB_BASE; - non_exit->probability = 0; - non_exit->count = 0; - - /* Update frequencies and counts. Everything before - the exit needs to be scaled FREQ_IN/FREQ_H times, - where FREQ_IN is the frequency of the entry edge - and FREQ_H is the frequency of the loop header. - Everything after the exit has zero frequency. */ - freq_h = loop->header->frequency; - freq_in = EDGE_FREQUENCY (loop_preheader_edge (loop)); - if (freq_h != 0) - { - body = get_loop_body_in_dom_order (loop); - for (n_before = 1; n_before <= loop->num_nodes; n_before++) - if (body[n_before - 1] == exit->src) - break; - scale_bbs_frequencies_int (body, n_before, freq_in, freq_h); - scale_bbs_frequencies_int (body + n_before, loop->num_nodes - n_before, - 0, 1); - free (body); - } - - /* Number of executions of exit is not changed, thus we need to restore - the original value. */ - exit->count = exit_count; -} - -/* Removes LOOP if it is empty. Returns true if LOOP is removed. CHANGED - is set to true if LOOP or any of its subloops is removed. */ - -static bool -try_remove_empty_loop (struct loop *loop, bool *changed) -{ - bool nonempty_subloop = false; - struct loop *sub; - - /* First, all subloops must be removed. */ - for (sub = loop->inner; sub; sub = sub->next) - nonempty_subloop |= !try_remove_empty_loop (sub, changed); - - if (nonempty_subloop || !empty_loop_p (loop)) - return false; - - remove_empty_loop (loop); - *changed = true; - return true; -} - -/* Remove the empty loops. */ - -unsigned int -remove_empty_loops (void) -{ - bool changed = false; - struct loop *loop; - - for (loop = current_loops->tree_root->inner; loop; loop = loop->next) - try_remove_empty_loop (loop, &changed); - - if (changed) - { - scev_reset (); - return TODO_cleanup_cfg; - } - return 0; -} - |