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. 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 (); }