middle-end/38474 - fix alias walk budget accounting in IPA analysis
authorRichard Biener <rguenther@suse.de>
Fri, 12 Feb 2021 10:13:36 +0000 (11:13 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 12 Feb 2021 11:34:28 +0000 (12:34 +0100)
The walk_aliased_vdef calls do not update the walking budget until
it is hit by a single call (and then in one case it resumes with
no limit at all).  The following rectifies this in multiple places.
It also makes the updates more consistend and fixes
determine_known_aggregate_parts to account its own alias queries.

2021-02-12  Richard Biener  <rguenther@suse.de>

PR middle-end/38474
* ipa-fnsummary.c (unmodified_parm_1): Only walk when
fbi->aa_walk_budget is bigger than zero.  Update
fbi->aa_walk_budget.
(param_change_prob): Likewise.
* ipa-prop.c (detect_type_change_from_memory_writes):
Properly account walk_aliased_vdefs.
(parm_preserved_before_stmt_p): Canonicalize updates.
(parm_ref_data_preserved_p): Likewise.
(parm_ref_data_pass_through_p): Likewise.
(determine_known_aggregate_parts): Account own alias queries.

gcc/ipa-fnsummary.c
gcc/ipa-prop.c

index 70b1fc2..e32e69c 100644 (file)
@@ -1197,7 +1197,8 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
       return SSA_NAME_VAR (op);
     }
   /* Non-SSA parm reference?  */
-  if (TREE_CODE (op) == PARM_DECL)
+  if (TREE_CODE (op) == PARM_DECL
+      && fbi->aa_walk_budget > 0)
     {
       bool modified = false;
 
@@ -1205,12 +1206,13 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
       ao_ref_init (&refd, op);
       int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
                                       mark_modified, &modified, NULL, NULL,
-                                      fbi->aa_walk_budget + 1);
+                                      fbi->aa_walk_budget);
       if (walked < 0)
        {
          fbi->aa_walk_budget = 0;
          return NULL_TREE;
        }
+      fbi->aa_walk_budget -= walked;
       if (!modified)
        {
          if (size_p)
@@ -2240,7 +2242,7 @@ param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
 
       if (init != error_mark_node)
        return 0;
-      if (!bb->count.nonzero_p ())
+      if (!bb->count.nonzero_p () || fbi->aa_walk_budget == 0)
        return REG_BR_PROB_BASE;
       if (dump_file)
        {
@@ -2255,8 +2257,12 @@ param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
       int walked
        = walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
                              NULL, NULL, fbi->aa_walk_budget);
+      if (walked > 0)
+       fbi->aa_walk_budget -= walked;
       if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
        {
+         if (walked < 0)
+           fbi->aa_walk_budget = 0;
          if (dump_file)
            {
              if (walked < 0)
index 9e34899..010c43f 100644 (file)
@@ -803,6 +803,9 @@ detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
       || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
     return true;
 
+  if (fbi->aa_walk_budget == 0)
+    return false;
+
   ao_ref_init (&ao, arg);
   ao.base = base;
   ao.offset = offset;
@@ -815,7 +818,11 @@ detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
 
   int walked
     = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
-                         &tci, NULL, NULL, fbi->aa_walk_budget + 1);
+                         &tci, NULL, NULL, fbi->aa_walk_budget);
+  if (walked >= 0)
+    fbi->aa_walk_budget -= walked;
+  else
+    fbi->aa_walk_budget = 0;
 
   if (walked >= 0 && !tci.type_maybe_changed)
     return false;
@@ -948,21 +955,20 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
 
   gcc_checking_assert (fbi);
   paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
-  if (paa->parm_modified)
+  if (paa->parm_modified || fbi->aa_walk_budget == 0)
     return false;
 
   gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
   ao_ref_init (&refd, parm_load);
   int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
                                   &modified, NULL, NULL,
-                                  fbi->aa_walk_budget + 1);
+                                  fbi->aa_walk_budget);
   if (walked < 0)
     {
       modified = true;
-      if (fbi)
-       fbi->aa_walk_budget = 0;
+      fbi->aa_walk_budget = 0;
     }
-  else if (fbi)
+  else
     fbi->aa_walk_budget -= walked;
   if (paa && modified)
     paa->parm_modified = true;
@@ -1010,14 +1016,14 @@ parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
 
   gcc_checking_assert (fbi);
   paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
-  if (paa->ref_modified)
+  if (paa->ref_modified || fbi->aa_walk_budget == 0)
     return false;
 
   gcc_checking_assert (gimple_vuse (stmt));
   ao_ref_init (&refd, ref);
   int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
                                   &modified, NULL, NULL,
-                                  fbi->aa_walk_budget + 1);
+                                  fbi->aa_walk_budget);
   if (walked < 0)
     {
       modified = true;
@@ -1051,13 +1057,13 @@ parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
   struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
                                                              gimple_bb (call),
                                                              index);
-  if (paa->pt_modified)
+  if (paa->pt_modified || fbi->aa_walk_budget == 0)
     return false;
 
   ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
   int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
                                   &modified, NULL, NULL,
-                                  fbi->aa_walk_budget + 1);
+                                  fbi->aa_walk_budget);
   if (walked < 0)
     {
       fbi->aa_walk_budget = 0;
@@ -2040,7 +2046,8 @@ determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
      of the aggregate is affected by definition of the virtual operand, it
      builds a sorted linked list of ipa_agg_jf_list describing that.  */
 
-  for (tree dom_vuse = gimple_vuse (call); dom_vuse;)
+  for (tree dom_vuse = gimple_vuse (call);
+       dom_vuse && fbi->aa_walk_budget > 0;)
     {
       gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
 
@@ -2052,6 +2059,7 @@ determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
          continue;
        }
 
+      fbi->aa_walk_budget--;
       if (stmt_may_clobber_ref_p_1 (stmt, &r))
        {
          struct ipa_known_agg_contents_list *content