Commit 7351bcaa by Jan Hubicka Committed by Jan Hubicka

loop-24.c: Update dump file matching; enable -O2.

	* 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.

From-SVN: r149206
parent 5071eab7
2009-07-03 Jan Hubicka <jh@suse.cz>
* 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.
2009-07-03 Uros Bizjak <ubizjak@gmail.com> 2009-07-03 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (fix_trunc<mode>_fisttp_i387_1): Use * config/i386/i386.md (fix_trunc<mode>_fisttp_i387_1): Use
......
...@@ -535,7 +535,11 @@ end: ...@@ -535,7 +535,11 @@ end:
effect. */ effect. */
if (mark_dfs_back_edges ()) if (mark_dfs_back_edges ())
{ {
loop_optimizer_init (LOOPS_HAVE_PREHEADERS); /* Preheaders are needed for SCEV to work.
Simple lateches and recorded exits improve chances that loop will
proved to be finite in testcases such as in loop-15.c and loop-24.c */
loop_optimizer_init (LOOPS_NORMAL
| LOOPS_HAVE_RECORDED_EXITS);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
flow_loops_dump (dump_file, NULL, 0); flow_loops_dump (dump_file, NULL, 0);
if (mark_irreducible_loops ()) if (mark_irreducible_loops ())
......
...@@ -651,7 +651,6 @@ init_optimization_passes (void) ...@@ -651,7 +651,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_lim); NEXT_PASS (pass_lim);
NEXT_PASS (pass_tree_unswitch); NEXT_PASS (pass_tree_unswitch);
NEXT_PASS (pass_scev_cprop); NEXT_PASS (pass_scev_cprop);
NEXT_PASS (pass_empty_loop);
NEXT_PASS (pass_record_bounds); NEXT_PASS (pass_record_bounds);
NEXT_PASS (pass_check_data_deps); NEXT_PASS (pass_check_data_deps);
NEXT_PASS (pass_loop_distribution); NEXT_PASS (pass_loop_distribution);
......
2009-07-03 Jan Hubicka <jh@suse.cz>
* 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.
2009-07-02 Mark Mitchell <mark@codesourcery.com> 2009-07-02 Mark Mitchell <mark@codesourcery.com>
* g++.dg/warn/null4.C: Extend. * g++.dg/warn/null4.C: Extend.
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-optimized" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-require-effective-target int32plus } */ /* { dg-require-effective-target int32plus } */
int bar (void); int bar (void);
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O -fstrict-overflow -fdump-tree-empty" } */ /* { dg-options "-O2 -fstrict-overflow -fdump-tree-optimized" } */
void foo(int a, int b) void foo(int a, int b)
{ for(;a!=b;a+=4); } { for(;a!=b;a+=4); }
...@@ -13,5 +13,5 @@ void foo3(int*a, int* b) ...@@ -13,5 +13,5 @@ void foo3(int*a, int* b)
void foo4(int*a, int*b) void foo4(int*a, int*b)
{ for(;a!=b;a++); } { for(;a!=b;a++); }
/* { dg-final { scan-tree-dump-times "Removing empty loop" 4 "empty" } } */ /* { dg-final { scan-tree-dump-not "if" "optimized" } } */
/* { dg-final { cleanup-tree-dump "empty" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-profile" } */ /* { dg-options "-O1 -fdump-tree-profile" } */
int foo(void); int foo(void);
void bla(void); void bla(void);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
determine number of iterations of the following loops unconditionally. */ determine number of iterations of the following loops unconditionally. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O -fstrict-overflow -fdump-tree-empty" } */ /* { dg-options "-O2 -fstrict-overflow -fdump-tree-optimized-blocks" } */
unsigned foo(unsigned int n) unsigned foo(unsigned int n)
{ {
...@@ -25,5 +25,5 @@ int foo0(int i0, int i1) ...@@ -25,5 +25,5 @@ int foo0(int i0, int i1)
return j; return j;
} }
/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */ /* { dg-final { scan-tree-dump-times "if" 2 "optimized" } } */
/* { dg-final { cleanup-tree-dump "empty" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* PR 31885 */ /* PR 31885 */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-empty" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */
struct s { struct s {
int *blah; int *blah;
...@@ -17,5 +17,5 @@ foo (struct s *p) ...@@ -17,5 +17,5 @@ foo (struct s *p)
p++; p++;
} }
/* { dg-final { scan-tree-dump-times "Removing empty loop" 1 "empty" } } */ /* { dg-final { scan-tree-dump-not "if" "optimized" } } */
/* { dg-final { cleanup-tree-dump "empty" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-optimized" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */
int foo (int n) int foo (int n)
{ {
...@@ -43,13 +43,12 @@ int baz (int n) ...@@ -43,13 +43,12 @@ int baz (int n)
return i; return i;
} }
/* The loops computing division/modulo by 64 should be eliminated. */ /* The loops computing division/modulo by 64 should be eliminated */
/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */ /* { dg-final { scan-tree-dump-times "if" 6 "optimized" } } */
/* There should be no division/modulo in the final dump (division and modulo /* There should be no division/modulo in the final dump (division and modulo
by 64 are done using bit operations). */ by 64 are done using bit operations). */
/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
/* { dg-final { cleanup-tree-dump "empty" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
-- { dg-do compile } -- { dg-do compile }
-- { dg-options "-O -gnatp -fdump-tree-optimized" } -- { dg-options "-O2 -gnatp -fdump-tree-optimized" }
package body Loop_Optimization6 is package body Loop_Optimization6 is
procedure Foo is procedure Foo is
......
...@@ -745,7 +745,6 @@ unsigned int tree_ssa_unswitch_loops (void); ...@@ -745,7 +745,6 @@ unsigned int tree_ssa_unswitch_loops (void);
unsigned int canonicalize_induction_variables (void); unsigned int canonicalize_induction_variables (void);
unsigned int tree_unroll_loops_completely (bool, bool); unsigned int tree_unroll_loops_completely (bool, bool);
unsigned int tree_ssa_prefetch_arrays (void); unsigned int tree_ssa_prefetch_arrays (void);
unsigned int remove_empty_loops (void);
void tree_ssa_iv_optimize (void); void tree_ssa_iv_optimize (void);
unsigned tree_predictive_commoning (void); unsigned tree_predictive_commoning (void);
tree canonicalize_loop_ivs (struct loop *, htab_t, tree *); tree canonicalize_loop_ivs (struct loop *, htab_t, tree *);
......
...@@ -434,18 +434,43 @@ find_obviously_necessary_stmts (struct edge_list *el) ...@@ -434,18 +434,43 @@ find_obviously_necessary_stmts (struct edge_list *el)
} }
} }
/* Pure and const functions are finite and thus have no infinite loops in
them. */
if ((TREE_READONLY (current_function_decl)
|| DECL_PURE_P (current_function_decl))
&& !DECL_LOOPING_CONST_OR_PURE_P (current_function_decl))
return;
/* Prevent the empty possibly infinite loops from being removed. */
if (el) if (el)
{ {
/* Prevent the loops from being removed. We must keep the infinite loops, loop_iterator li;
and we currently do not have a means to recognize the finite ones. */ struct loop *loop;
scev_initialize ();
if (mark_irreducible_loops ())
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
edge_iterator ei; edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & EDGE_DFS_BACK) if ((e->flags & EDGE_DFS_BACK)
&& (e->flags & EDGE_IRREDUCIBLE_LOOP))
{
if (dump_file)
fprintf (dump_file, "Marking back edge of irreducible loop %i->%i\n",
e->src->index, e->dest->index);
mark_control_dependent_edges_necessary (e->dest, el); mark_control_dependent_edges_necessary (e->dest, el);
} }
} }
FOR_EACH_LOOP (li, loop, 0)
if (!finite_loop_p (loop))
{
if (dump_file)
fprintf (dump_file, "can not prove finiteness of loop %i\n", loop->num);
mark_control_dependent_edges_necessary (loop->latch, el);
}
scev_finalize ();
}
} }
...@@ -570,6 +595,19 @@ mark_all_reaching_defs_necessary (gimple stmt) ...@@ -570,6 +595,19 @@ mark_all_reaching_defs_necessary (gimple stmt)
mark_all_reaching_defs_necessary_1, NULL, &visited); mark_all_reaching_defs_necessary_1, NULL, &visited);
} }
/* Return true for PHI nodes with one or identical arguments
can be removed. */
static bool
degenerate_phi_p (gimple phi)
{
unsigned int i;
tree op = gimple_phi_arg_def (phi, 0);
for (i = 1; i < gimple_phi_num_args (phi); i++)
if (gimple_phi_arg_def (phi, i) != op)
return false;
return true;
}
/* Propagate necessity using the operands of necessary statements. /* Propagate necessity using the operands of necessary statements.
Process the uses on each statement in the worklist, and add all Process the uses on each statement in the worklist, and add all
feeding statements which contribute to the calculation of this feeding statements which contribute to the calculation of this
...@@ -632,7 +670,7 @@ propagate_necessity (struct edge_list *el) ...@@ -632,7 +670,7 @@ propagate_necessity (struct edge_list *el)
mark_operand_necessary (arg); mark_operand_necessary (arg);
} }
if (aggressive) if (aggressive && !degenerate_phi_p (stmt))
{ {
for (k = 0; k < gimple_phi_num_args (stmt); k++) for (k = 0; k < gimple_phi_num_args (stmt); k++)
{ {
...@@ -822,23 +860,13 @@ remove_dead_phis (basic_block bb) ...@@ -822,23 +860,13 @@ remove_dead_phis (basic_block bb)
very simple dead PHI removal here. */ very simple dead PHI removal here. */
if (!is_gimple_reg (gimple_phi_result (phi))) if (!is_gimple_reg (gimple_phi_result (phi)))
{ {
unsigned i;
tree vuse;
/* Virtual PHI nodes with one or identical arguments /* Virtual PHI nodes with one or identical arguments
can be removed. */ can be removed. */
vuse = gimple_phi_arg_def (phi, 0); if (degenerate_phi_p (phi))
for (i = 1; i < gimple_phi_num_args (phi); ++i)
{
if (gimple_phi_arg_def (phi, i) != vuse)
{
vuse = NULL_TREE;
break;
}
}
if (vuse != NULL_TREE)
{ {
tree vdef = gimple_phi_result (phi); tree vdef = gimple_phi_result (phi);
tree vuse = gimple_phi_arg_def (phi, 0);
use_operand_p use_p; use_operand_p use_p;
imm_use_iterator iter; imm_use_iterator iter;
gimple use_stmt; gimple use_stmt;
...@@ -899,7 +927,7 @@ static edge ...@@ -899,7 +927,7 @@ static edge
forward_edge_to_pdom (edge e, basic_block post_dom_bb) forward_edge_to_pdom (edge e, basic_block post_dom_bb)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
edge e2; edge e2 = NULL;
edge_iterator ei; edge_iterator ei;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -924,6 +952,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) ...@@ -924,6 +952,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
for (gsi = gsi_start_phis (post_dom_bb); !gsi_end_p (gsi);) for (gsi = gsi_start_phis (post_dom_bb); !gsi_end_p (gsi);)
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
tree op;
/* Dead PHI do not imply control dependency. */ /* Dead PHI do not imply control dependency. */
if (!gimple_plf (phi, STMT_NECESSARY) if (!gimple_plf (phi, STMT_NECESSARY)
...@@ -947,8 +976,12 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) ...@@ -947,8 +976,12 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
remove_phi_node (&gsi, true); remove_phi_node (&gsi, true);
continue; continue;
} }
gcc_assert (e2); if (!e2)
add_phi_arg (phi, gimple_phi_arg_def (phi, e2->dest_idx), e); op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
else
op = gimple_phi_arg_def (phi, e2->dest_idx);
add_phi_arg (phi, op, e);
gcc_assert (e2 || degenerate_phi_p (phi));
gsi_next (&gsi); gsi_next (&gsi);
} }
} }
...@@ -1094,7 +1127,42 @@ eliminate_unnecessary_stmts (void) ...@@ -1094,7 +1127,42 @@ eliminate_unnecessary_stmts (void)
} }
} }
} }
/* Since we don't track liveness of virtual PHI nodes, it is possible that we
rendered some PHI nodes unreachable while they are still in use.
Mark them for renaming. */
if (cfg_altered)
{
basic_block next_bb;
find_unreachable_blocks ();
for (bb = ENTRY_BLOCK_PTR->next_bb; bb != EXIT_BLOCK_PTR; bb = next_bb)
{
next_bb = bb->next_bb;
if (!(bb->flags & BB_REACHABLE))
{
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
if (!is_gimple_reg (gimple_phi_result (gsi_stmt (gsi))))
{
bool found = false;
imm_use_iterator iter;
FOR_EACH_IMM_USE_STMT (stmt, iter, gimple_phi_result (gsi_stmt (gsi)))
{
if (!(gimple_bb (stmt)->flags & BB_REACHABLE))
continue;
if (gimple_code (stmt) == GIMPLE_PHI
|| gimple_plf (stmt, STMT_NECESSARY))
{
found = true;
BREAK_FROM_IMM_USE_STMT (iter);
}
}
if (found)
mark_virtual_phi_result_for_renaming (gsi_stmt (gsi));
}
delete_basic_block (bb);
}
}
}
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
/* Remove dead PHI nodes. */ /* Remove dead PHI nodes. */
...@@ -1197,6 +1265,13 @@ perform_tree_ssa_dce (bool aggressive) ...@@ -1197,6 +1265,13 @@ perform_tree_ssa_dce (bool aggressive)
struct edge_list *el = NULL; struct edge_list *el = NULL;
bool something_changed = 0; bool something_changed = 0;
/* Preheaders are needed for SCEV to work.
Simple lateches and recorded exits improve chances that loop will
proved to be finite in testcases such as in loop-15.c and loop-24.c */
if (aggressive)
loop_optimizer_init (LOOPS_NORMAL
| LOOPS_HAVE_RECORDED_EXITS);
tree_dce_init (aggressive); tree_dce_init (aggressive);
if (aggressive) if (aggressive)
...@@ -1216,6 +1291,9 @@ perform_tree_ssa_dce (bool aggressive) ...@@ -1216,6 +1291,9 @@ perform_tree_ssa_dce (bool aggressive)
find_obviously_necessary_stmts (el); find_obviously_necessary_stmts (el);
if (aggressive)
loop_optimizer_finalize ();
longest_chain = 0; longest_chain = 0;
total_chain = 0; total_chain = 0;
chain_ovfl = false; chain_ovfl = false;
......
...@@ -558,187 +558,3 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) ...@@ -558,187 +558,3 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
return 0; 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;
}
...@@ -433,37 +433,6 @@ struct gimple_opt_pass pass_scev_cprop = ...@@ -433,37 +433,6 @@ struct gimple_opt_pass pass_scev_cprop =
} }
}; };
/* Remove empty loops. */
static unsigned int
tree_ssa_empty_loop (void)
{
if (number_of_loops () <= 1)
return 0;
return remove_empty_loops ();
}
struct gimple_opt_pass pass_empty_loop =
{
{
GIMPLE_PASS,
"empty", /* name */
NULL, /* gate */
tree_ssa_empty_loop, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_COMPLETE_UNROLL, /* tv_id */
PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_verify_loops
| TODO_ggc_collect /* todo_flags_finish */
}
};
/* Record bounds on numbers of iterations of loops. */ /* Record bounds on numbers of iterations of loops. */
static unsigned int static unsigned int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment