diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1724238cbdd4bd293a9bce92eeb72b1f15f28415..e307ba81706ffe7b3366b1cc7a367d1064bcd10e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2006-09-05 Andrew Pinski <pinskia@physics.uc.edu> + + PR tree-opt/28937 + * tree-flow.h (tree_ssa_unswitch_loops): Return unsigned int. + (canonicalize_induction_variables): Likewise. + (tree_unroll_loops_completely): Likewise. + (tree_ssa_prefetch_arrays): Likewise. + (remove_empty_loops): Likewise. + * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Return + TODO_cleanup_cfg instead of directly calling + cleanup_tree_cfg_loop. + * tree-ssa-loop-ivcanon.c (canonicalize_induction_variables): + Likewise. + (tree_unroll_loops_completely): Likewise. + (remove_empty_loops): Likewise. + * tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Likewise. + * tree-ssa-loop.c (tree_ssa_loop_unswitch): Use the return value + of tree_ssa_unswitch_loops. + (tree_ssa_loop_ivcanon): Use the return value of + canonicalize_induction_variables. + (tree_ssa_empty_loop): Use the return value of + remove_empty_loops. + (tree_complete_unroll): Use the return value of + tree_unroll_loops_completely. + (tree_ssa_loop_prefetch): Use the return value of + tree_ssa_prefetch_arrays. + * passes.c (execute_todo): Before Cleanup CFG, set + updating_used_alone and after cleanup CFG, call + recalculate_used_alone. + + 2006-09-05 Andrew Pinski <pinskia@physics.uc.edu> PR tree-opt/28952 diff --git a/gcc/passes.c b/gcc/passes.c index fe6f637e86890e0d4e0716ea5ac22d598211f7f2..46e4756e84db6c5ffe1eb2fc8d5df686b94cb261 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -727,11 +727,17 @@ execute_todo (unsigned int flags) /* Always cleanup the CFG before trying to update SSA . */ if (flags & TODO_cleanup_cfg) { + /* CFG Cleanup can cause a constant to prop into an ARRAY_REF. */ + updating_used_alone = true; + if (current_loops) cleanup_tree_cfg_loop (); else cleanup_tree_cfg (); + /* Update the used alone after cleanup cfg. */ + recalculate_used_alone (); + /* When cleanup_tree_cfg merges consecutive blocks, it may perform some simplistic propagation when removing single valued PHI nodes. This propagation may, in turn, cause the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5488b9df4cf0cdd085592d072e0d2f66bb580fd2..5f11f19baf65e9c3d4f52b474712af45874ce79d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-09-05 Andrew Pinski <pinskia@physics.uc.edu> + + PR tree-opt/28937 + * g++.dg/opt/unroll2.C: New test. + 2006-09-05 Andrew Pinski <pinskia@physics.uc.edu> PR tree-opt/28952 diff --git a/gcc/testsuite/g++.dg/opt/unroll2.C b/gcc/testsuite/g++.dg/opt/unroll2.C new file mode 100644 index 0000000000000000000000000000000000000000..82a1e7f56d8da32edf861f794fa276293bbc67ce --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/unroll2.C @@ -0,0 +1,27 @@ +// PR tree-opt/28937 +// Complete unroll forgot to update the statement usage +// which meant we ICEd in add_virtual_operand. + +// { dg-do compile } +// { dg-options "-O2" } + + +class SHA256 +{ + unsigned m_digest; + unsigned long long m_count; + unsigned char _buffer[64]; + static void Transform (unsigned * data); + void WriteByteBlock (unsigned t); +}; +void SHA256::WriteByteBlock (unsigned t) +{ + unsigned data32[16]; + Transform (data32); + unsigned long long lenInBits = m_count; + if (t != (64 - 8)) + return; + for (int i = 0; i < 2; i++) + _buffer[t++] = (unsigned char)lenInBits; +} + diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 46966663fe5f0f22ef024fd1290f0837c729b290..5156bad032502903001ae4d1c2247b31f63a56e4 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -798,11 +798,11 @@ bool empty_block_p (basic_block); /* In tree-ssa-loop*.c */ void tree_ssa_lim (struct loops *); -void tree_ssa_unswitch_loops (struct loops *); -void canonicalize_induction_variables (struct loops *); -void tree_unroll_loops_completely (struct loops *, bool); -void tree_ssa_prefetch_arrays (struct loops *); -void remove_empty_loops (struct loops *); +unsigned int tree_ssa_unswitch_loops (struct loops *); +unsigned int canonicalize_induction_variables (struct loops *); +unsigned int tree_unroll_loops_completely (struct loops *, bool); +unsigned int tree_ssa_prefetch_arrays (struct loops *); +unsigned int remove_empty_loops (struct loops *); void tree_ssa_iv_optimize (struct loops *); bool number_of_iterations_exit (struct loop *, edge, diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 0ad2069983f45b9d829dae146fc3a90049be4875..a56679d3239d876bb26f9a71761731819fbfa56b 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -330,7 +330,7 @@ canonicalize_loop_induction_variables (struct loops *loops, struct loop *loop, /* The main entry point of the pass. Adds canonical induction variables to the suitable LOOPS. */ -void +unsigned int canonicalize_induction_variables (struct loops *loops) { unsigned i; @@ -352,14 +352,15 @@ canonicalize_induction_variables (struct loops *loops) scev_reset (); if (changed) - cleanup_tree_cfg_loop (); + return TODO_cleanup_cfg; + return 0; } /* Unroll LOOPS completely if they iterate just few times. Unless MAY_INCREASE_SIZE is true, perform the unrolling only if the size of the code does not increase. */ -void +unsigned int tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) { unsigned i; @@ -388,7 +389,8 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) scev_reset (); if (changed) - cleanup_tree_cfg_loop (); + return TODO_cleanup_cfg; + return 0; } /* Checks whether LOOP is empty. */ @@ -562,7 +564,7 @@ try_remove_empty_loop (struct loop *loop, bool *changed) /* Remove the empty LOOPS. */ -void +unsigned int remove_empty_loops (struct loops *loops) { bool changed = false; @@ -574,6 +576,7 @@ remove_empty_loops (struct loops *loops) if (changed) { scev_reset (); - cleanup_tree_cfg_loop (); + return TODO_cleanup_cfg; } + return 0; } diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c index b58dbf6fccdb13e77330ac415712b09aab18f885..9340bbb4029ef97fda9fa13c14fdb848f62dd9b4 100644 --- a/gcc/tree-ssa-loop-prefetch.c +++ b/gcc/tree-ssa-loop-prefetch.c @@ -1006,12 +1006,13 @@ fail: /* Issue prefetch instructions for array references in LOOPS. */ -void +unsigned int tree_ssa_prefetch_arrays (struct loops *loops) { unsigned i; struct loop *loop; bool unrolled = false; + int todo_flags = 0; if (!HAVE_prefetch /* It is possible to ask compiler for say -mtune=i486 -march=pentium4. @@ -1019,7 +1020,7 @@ tree_ssa_prefetch_arrays (struct loops *loops) of processor costs and i486 does not have prefetch, but -march=pentium4 causes HAVE_prefetch to be true. Ugh. */ || PREFETCH_BLOCK == 0) - return; + return 0; initialize_original_copy_tables (); @@ -1057,8 +1058,9 @@ tree_ssa_prefetch_arrays (struct loops *loops) if (unrolled) { scev_reset (); - cleanup_tree_cfg_loop (); + todo_flags |= TODO_cleanup_cfg; } free_original_copy_tables (); + return todo_flags; } diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index ecb632cabc75a7d52bc37ac1150dced5a2d39aca..d9102b284b6739834c77dc44d9b8e2f683b3f965 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -80,7 +80,7 @@ static tree tree_may_unswitch_on (basic_block, struct loop *); /* Main entry point. Perform loop unswitching on all suitable LOOPS. */ -void +unsigned int tree_ssa_unswitch_loops (struct loops *loops) { int i, num; @@ -104,7 +104,8 @@ tree_ssa_unswitch_loops (struct loops *loops) } if (changed) - cleanup_tree_cfg_loop (); + return TODO_cleanup_cfg; + return 0; } /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index ee1b9b374eaeca632a7eea1c92453a5541775c8b..475f31e3ba855f0b6be96f40974e45076a08a3c5 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -158,8 +158,7 @@ tree_ssa_loop_unswitch (void) if (!current_loops) return 0; - tree_ssa_unswitch_loops (current_loops); - return 0; + return tree_ssa_unswitch_loops (current_loops); } static bool @@ -260,8 +259,7 @@ tree_ssa_loop_ivcanon (void) if (!current_loops) return 0; - canonicalize_induction_variables (current_loops); - return 0; + return canonicalize_induction_variables (current_loops); } static bool @@ -322,8 +320,7 @@ tree_ssa_empty_loop (void) if (!current_loops) return 0; - remove_empty_loops (current_loops); - return 0; + return remove_empty_loops (current_loops); } struct tree_opt_pass pass_empty_loop = @@ -381,11 +378,10 @@ tree_complete_unroll (void) if (!current_loops) return 0; - tree_unroll_loops_completely (current_loops, - flag_unroll_loops - || flag_peel_loops - || optimize >= 3); - return 0; + return tree_unroll_loops_completely (current_loops, + flag_unroll_loops + || flag_peel_loops + || optimize >= 3); } static bool @@ -419,8 +415,7 @@ tree_ssa_loop_prefetch (void) if (!current_loops) return 0; - tree_ssa_prefetch_arrays (current_loops); - return 0; + return tree_ssa_prefetch_arrays (current_loops); } static bool