On April 1, 2019 4:13:28 PM GMT+02:00, Richard Sandiford <richard.sandif...@arm.com> wrote: >Richard Biener <rguent...@suse.de> writes: >> After the fix to RPO VN in loop header copying DF via RTL invariant >> motion takes 50% of the compile-time for the second testcase in >> PR46590. This is caused by the DF live problem iterating over >> all dirty blocks for the local problem which is all blocks of >> the function because while loop-invariant uses df_analyze_loop >> it always marks all blocks of the function as dirty via >> df_live_set_all_dirty. One of the possible fixes is to add >> a df_live_set_loop_dirty () function which causes the problem >> to only iterate over one loop blocks. >> >> It turns out the LIVE problem is always present so we cannot >> remove it which in turn means we have to mark blocks possibly >> not visited by invaraint motion as dirty (thus the new >> df_live_set_all_dirty at the end of move_loop_invariants). >> >> Anyhow - I'm not really into how DF should ideally work here > >Me neither, but as discussed on IRC, here's alternative that seems >to give a similar speed-up. > >- df_live is already present at -O2, so we only need to add it and > mark all blocks dirty for -O > >- df_process_deferred_rescans should be enough to force a rescan of > blocks affected by moving invariants, but calling it in find_defs > means that we don't do any rescans for the final loop > >Still testing, but posting for comments.
Looks like a good cleanup. It will still process all blocks at the first df_analyze_loop call but at least not all over again for each loop. So if it works out OK since it's conceptually simpler. Richard. >Thanks, >Richard > > >2019-04-01 Richard Sandiford <richard.sandif...@arm.com> > >gcc/ > PR rtl-optimization/46950 > * loop-invariant.c (find_defs): Move df_remove_problem and > df_process_deferred_rescans to move_invariants. > Move df_live_add_problem and df_live_set_all_dirty calls > to move_invariants. > (move_invariants): Likewise. > (move_loop_invariants): Likewise, making the df_live calls > conditional on -O. Remove the problem again if we added it > locally. > >Index: gcc/loop-invariant.c >=================================================================== >--- gcc/loop-invariant.c 2019-03-08 18:15:33.704751739 +0000 >+++ gcc/loop-invariant.c 2019-04-01 14:09:13.553206345 +0000 >@@ -681,11 +681,7 @@ find_defs (struct loop *loop) > loop->num); > } > >- df_remove_problem (df_chain); >- df_process_deferred_rescans (); > df_chain_add_problem (DF_UD_CHAIN); >- df_live_add_problem (); >- df_live_set_all_dirty (); > df_set_flags (DF_RD_PRUNE_DEAD_DEFS); > df_analyze_loop (loop); > check_invariant_table_size (); >@@ -1891,6 +1887,10 @@ move_invariants (struct loop *loop) > GENERAL_REGS, NO_REGS, GENERAL_REGS); > } > } >+ /* Remove the DF_UD_CHAIN problem added in find_defs before >rescanning, >+ to save a bit of compile time. */ >+ df_remove_problem (df_chain); >+ df_process_deferred_rescans (); > } > > /* Initializes invariant motion data. */ >@@ -2254,6 +2254,11 @@ move_loop_invariants (void) > { > struct loop *loop; > >+ if (optimize == 1) >+ { >+ df_live_add_problem (); >+ df_live_set_all_dirty (); >+ } > if (flag_ira_loop_pressure) > { > df_analyze (); >@@ -2286,5 +2291,8 @@ move_loop_invariants (void) > invariant_table = NULL; > invariant_table_size = 0; > >+ if (optimize == 1) >+ df_remove_problem (df_live); >+ > checking_verify_flow_info (); > }