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

Reply via email to