On March 12, 2020 11:29:45 PM GMT+01:00, Segher Boessenkool 
<seg...@kernel.crashing.org> wrote:
>The df dataflow solvers use the aux field in the basic_block struct,
>although that is reserved for any use by passes.  And not only that,
>it is required that you set all such fields to NULL before calling
>the solvers, or you quietly get wrong results.
>
>This changes the solvers to use a local array for last_change_age
>instead, just like it already had a local array for last_visit_age.
>
>Tested on powerpc64-linux {-m32,-m64}.  Also tested with the tests for
>PR94042, which it also solves (I need to confirm that still though,
>there are other testsuite problems interfering with my testing).

OK for trunk and affected branches (can you report back how old this issue is?) 

Thanks, 
Richard. 

>       PR rtl-optimization/94148
>       PR rtl-optimization/94042
>       * df-core.c (BB_LAST_CHANGE_AGE): Delete.
>       (df_worklist_propagate_forward): New parameter last_change_age, use
>       that instead of bb->aux.
>       (df_worklist_propagate_backward): Ditto.
>       (df_worklist_dataflow_doublequeue): Use a local array last_change_age.
>
>---
> gcc/df-core.c | 35 ++++++++++++++++++-----------------
> 1 file changed, 18 insertions(+), 17 deletions(-)
>
>diff --git a/gcc/df-core.c b/gcc/df-core.c
>index 346849e..9875a26 100644
>--- a/gcc/df-core.c
>+++ b/gcc/df-core.c
>@@ -871,9 +871,6 @@ make_pass_df_finish (gcc::context *ctxt)
>    The general data flow analysis engine.
>----------------------------------------------------------------------------*/
> 
>-/* Return time BB when it was visited for last time.  */
>-#define BB_LAST_CHANGE_AGE(bb) ((ptrdiff_t)(bb)->aux)
>-
> /* Helper function for df_worklist_dataflow.
>    Propagate the dataflow forward.
>    Given a BB_INDEX, do the dataflow propagation
>@@ -897,7 +894,8 @@ df_worklist_propagate_forward (struct dataflow
>*dataflow,
>                                unsigned *bbindex_to_postorder,
>                                bitmap pending,
>                                sbitmap considered,
>-                             ptrdiff_t age)
>+                             vec<int> &last_change_age,
>+                             int age)
> {
>   edge e;
>   edge_iterator ei;
>@@ -908,7 +906,8 @@ df_worklist_propagate_forward (struct dataflow
>*dataflow,
>   if (EDGE_COUNT (bb->preds) > 0)
>     FOR_EACH_EDGE (e, ei, bb->preds)
>       {
>-        if (age <= BB_LAST_CHANGE_AGE (e->src)
>+      if (bbindex_to_postorder[e->src->index] < last_change_age.length ()
>+          && age <= last_change_age[bbindex_to_postorder[e->src->index]]
>           && bitmap_bit_p (considered, e->src->index))
>           changed |= dataflow->problem->con_fun_n (e);
>       }
>@@ -942,7 +941,8 @@ df_worklist_propagate_backward (struct dataflow
>*dataflow,
>                                 unsigned *bbindex_to_postorder,
>                                 bitmap pending,
>                                 sbitmap considered,
>-                              ptrdiff_t age)
>+                              vec<int> &last_change_age,
>+                              int age)
> {
>   edge e;
>   edge_iterator ei;
>@@ -953,7 +953,8 @@ df_worklist_propagate_backward (struct dataflow
>*dataflow,
>   if (EDGE_COUNT (bb->succs) > 0)
>     FOR_EACH_EDGE (e, ei, bb->succs)
>       {
>-        if (age <= BB_LAST_CHANGE_AGE (e->dest)
>+      if (bbindex_to_postorder[e->dest->index] < last_change_age.length ()
>+          && age <= last_change_age[bbindex_to_postorder[e->dest->index]]
>           && bitmap_bit_p (considered, e->dest->index))
>           changed |= dataflow->problem->con_fun_n (e);
>       }
>@@ -991,10 +992,10 @@ df_worklist_propagate_backward (struct dataflow
>*dataflow,
>  worklists (we are processing WORKLIST and storing new BBs to visit in
>    PENDING).
> 
>-   As an optimization we maintain ages when BB was changed (stored in
>bb->aux)
>-   and when it was last visited (stored in last_visit_age).  This
>avoids need
>-   to re-do confluence function for edges to basic blocks whose source
>-   did not change since destination was visited last time.  */
>+   As an optimization we maintain ages when BB was changed (stored in
>+   last_change_age) and when it was last visited (stored in
>last_visit_age).
>+   This avoids need to re-do confluence function for edges to basic
>blocks
>+   whose source did not change since destination was visited last
>time.  */
> 
> static void
> df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
>@@ -1010,11 +1011,11 @@ df_worklist_dataflow_doublequeue (struct
>dataflow *dataflow,
>   int age = 0;
>   bool changed;
>   vec<int> last_visit_age = vNULL;
>+  vec<int> last_change_age = vNULL;
>   int prev_age;
>-  basic_block bb;
>-  int i;
> 
>   last_visit_age.safe_grow_cleared (n_blocks);
>+  last_change_age.safe_grow_cleared (n_blocks);
> 
>   /* Double-queueing. Worklist is for the current iteration,
>      and pending is for the next. */
>@@ -1032,30 +1033,30 @@ df_worklist_dataflow_doublequeue (struct
>dataflow *dataflow,
> 
>         bitmap_clear_bit (pending, index);
>         bb_index = blocks_in_postorder[index];
>-        bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
>         prev_age = last_visit_age[index];
>         if (dir == DF_FORWARD)
>           changed = df_worklist_propagate_forward (dataflow, bb_index,
>                                                    bbindex_to_postorder,
>                                                    pending, considered,
>+                                                   last_change_age,
>                                                    prev_age);
>         else
>           changed = df_worklist_propagate_backward (dataflow, bb_index,
>                                                     bbindex_to_postorder,
>                                                     pending, considered,
>+                                                    last_change_age,
>                                                     prev_age);
>         last_visit_age[index] = ++age;
>         if (changed)
>-          bb->aux = (void *)(ptrdiff_t)age;
>+          last_change_age[index] = age;
>       }
>       bitmap_clear (worklist);
>     }
>-  for (i = 0; i < n_blocks; i++)
>-    BASIC_BLOCK_FOR_FN (cfun, blocks_in_postorder[i])->aux = NULL;
> 
>   BITMAP_FREE (worklist);
>   BITMAP_FREE (pending);
>   last_visit_age.release ();
>+  last_change_age.release ();
> 
>   /* Dump statistics. */
>   if (dump_file)

Reply via email to