re PR fortran/81827 (Large compile time with derived-type rrays)
authorRichard Biener <rguenther@suse.de>
Thu, 17 Aug 2017 10:04:04 +0000 (10:04 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 17 Aug 2017 10:04:04 +0000 (10:04 +0000)
2017-08-17  Richard Biener  <rguenther@suse.de>

PR tree-optimization/81827
* tree-ssa-structalias.c (struct variable_info): Add is_reg_var
flag.
(new_var_info): Initialize it conservatively.
(get_call_vi): Mark register vars.
(new_scalar_tmp_constraint_exp): Likewise.
(handle_rhs_call): Likewise.
(handle_const_call): Likewise.
(create_function_info_for): Likewise.
(solve_constraints): Sort varinfos to separate register from
non-register vars to pack points-to solution bitmaps during
iteration.

From-SVN: r251143

gcc/ChangeLog
gcc/tree-ssa-structalias.c

index 26eb5451121ba0bc18913f7e8774010fecc47c77..d4db491b1f28bb5a978670c928f824ce90e91288 100644 (file)
@@ -1,3 +1,18 @@
+2017-08-17  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81827
+       * tree-ssa-structalias.c (struct variable_info): Add is_reg_var
+       flag.
+       (new_var_info): Initialize it conservatively.
+       (get_call_vi): Mark register vars.
+       (new_scalar_tmp_constraint_exp): Likewise.
+       (handle_rhs_call): Likewise.
+       (handle_const_call): Likewise.
+       (create_function_info_for): Likewise.
+       (solve_constraints): Sort varinfos to separate register from
+       non-register vars to pack points-to solution bitmaps during
+       iteration.
+
 2017-08-17  Marek Polacek  <polacek@redhat.com>
 
        * gimplify.c (gimplify_adjust_omp_clauses): Compare with 0 instead of
index c120ce4030307b45fd897bab2169b671b01bf8cc..c95d1e3784bcc964f46b3092188b73c7153e7bb1 100644 (file)
@@ -257,6 +257,9 @@ struct variable_info
   /* True if this is a heap variable.  */
   unsigned int is_heap_var : 1;
 
+  /* True if this is a register variable.  */
+  unsigned int is_reg_var : 1;
+
   /* True if this field may contain pointers.  */
   unsigned int may_have_pointers : 1;
 
@@ -389,6 +392,7 @@ new_var_info (tree t, const char *name, bool add_id)
                          /* We have to treat even local register variables
                             as escape points.  */
                          || (VAR_P (t) && DECL_HARD_REGISTER (t)));
+  ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
   ret->solution = BITMAP_ALLOC (&pta_obstack);
   ret->oldsolution = NULL;
   ret->next = 0;
@@ -422,12 +426,14 @@ get_call_vi (gcall *call)
   vi->size = 1;
   vi->fullsize = 2;
   vi->is_full_var = true;
+  vi->is_reg_var = true;
 
   vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
   vi2->offset = 1;
   vi2->size = 1;
   vi2->fullsize = 2;
   vi2->is_full_var = true;
+  vi2->is_reg_var = true;
 
   vi->next = vi2->id;
 
@@ -2892,6 +2898,7 @@ new_scalar_tmp_constraint_exp (const char *name, bool add_id)
   vi->size = -1;
   vi->fullsize = -1;
   vi->is_full_var = 1;
+  vi->is_reg_var = 1;
 
   tmp.var = vi->id;
   tmp.type = SCALAR;
@@ -3930,6 +3937,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
        {
          varinfo_t uses = get_call_use_vi (stmt);
          varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
+         tem->is_reg_var = true;
          make_constraint_to (tem->id, arg);
          make_any_offset_constraints (tem);
          if (!(flags & EAF_DIRECT))
@@ -3943,6 +3951,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
          varinfo_t uses = get_call_use_vi (stmt);
          varinfo_t clobbers = get_call_clobber_vi (stmt);
          varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
+         tem->is_reg_var = true;
          make_constraint_to (tem->id, arg);
          make_any_offset_constraints (tem);
          if (!(flags & EAF_DIRECT))
@@ -4110,7 +4119,10 @@ handle_const_call (gcall *stmt, vec<ce_s> *results)
   /* May return offsetted arguments.  */
   varinfo_t tem = NULL;
   if (gimple_call_num_args (stmt) != 0)
-    tem = new_var_info (NULL_TREE, "callarg", true);
+    {
+      tem = new_var_info (NULL_TREE, "callarg", true);
+      tem->is_reg_var = true;
+    }
   for (k = 0; k < gimple_call_num_args (stmt); ++k)
     {
       tree arg = gimple_call_arg (stmt, k);
@@ -5712,6 +5724,7 @@ create_function_info_for (tree decl, const char *name, bool add_id,
       clobbervi->fullsize = vi->fullsize;
       clobbervi->is_full_var = true;
       clobbervi->is_global_var = false;
+      clobbervi->is_reg_var = true;
 
       gcc_assert (prev_vi->offset < clobbervi->offset);
       prev_vi->next = clobbervi->id;
@@ -5727,6 +5740,7 @@ create_function_info_for (tree decl, const char *name, bool add_id,
       usevi->fullsize = vi->fullsize;
       usevi->is_full_var = true;
       usevi->is_global_var = false;
+      usevi->is_reg_var = true;
 
       gcc_assert (prev_vi->offset < usevi->offset);
       prev_vi->next = usevi->id;
@@ -7075,6 +7089,39 @@ solve_constraints (void)
 {
   struct scc_info *si;
 
+  /* Sort varinfos so that ones that cannot be pointed to are last.
+     This makes bitmaps more efficient.  */
+  unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
+  for (unsigned i = 0; i < integer_id + 1; ++i)
+    map[i] = i;
+  /* Start with non-register vars (as possibly address-taken), followed
+     by register vars as conservative set of vars never appearing in
+     the points-to solution bitmaps.  */
+  unsigned j = integer_id + 1;
+  for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+    if (! varmap[i]->is_reg_var)
+      map[i] = j++;
+  for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+    if (varmap[i]->is_reg_var)
+      map[i] = j++;
+  /* Shuffle varmap according to map.  */
+  for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+    {
+      while (map[varmap[i]->id] != i)
+       std::swap (varmap[i], varmap[map[varmap[i]->id]]);
+      gcc_assert (bitmap_empty_p (varmap[i]->solution));
+      varmap[i]->id = i;
+      varmap[i]->next = map[varmap[i]->next];
+      varmap[i]->head = map[varmap[i]->head];
+    }
+  /* Finally rewrite constraints.  */
+  for (unsigned i = 0; i < constraints.length (); ++i)
+    {
+      constraints[i]->lhs.var = map[constraints[i]->lhs.var];
+      constraints[i]->rhs.var = map[constraints[i]->rhs.var];
+    }
+  free (map);
+
   if (dump_file)
     fprintf (dump_file,
             "\nCollapsing static cycles and doing variable "