OSDN Git Service

2010-04-15 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Apr 2010 13:16:44 +0000 (13:16 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:32:44 +0000 (14:32 +0900)
* tree-ssa-structalias.c (struct variable_info): Add
is_fn_info flag.
(new_var_info): Initialize it.
(dump_constraints): Support printing last added constraints.
(debug_constraints): Adjust.
(dump_constraint_graph): Likewise.
(make_heapvar_for): Check for NULL cfun.
(get_function_part_constraint): New function.
(get_fi_for_callee): Likewise.
(find_func_aliases): Properly implement IPA PTA constraints.
(process_ipa_clobber): New function.
(find_func_clobbers): Likewise.
(insert_into_field_list_sorted): Remove.
(create_function_info_for): Properly allocate vars for IPA mode.
Do not use insert_into_field_list_sorted.
(create_variable_info_for): Properly generate constraints for
global vars in IPA mode.
(dump_solution_for_var): Always dump the solution.
(set_uids_in_ptset): Initialize DECL_PT_UID if in ipa-mode.
(find_what_var_points_to): Adjust.
(pt_solution_set): Change.
(pt_solution_ior_into): New function.
(pt_solution_empty_p): Export.
(pt_solution_includes_global): Adjust.
(pt_solution_includes_1): Likewise.
(pt_solutions_intersect_1): Likewise.
(dump_sa_points_to_info): Check some invariants.
(solve_constraints): Move constraint dumping ...
(compute_points_to_sets): ... here.
(ipa_pta_execute): ... and here.
(compute_may_aliases): Do not re-compute points-to info
locally if IPA info is available.
(ipa_escaped_pt): New global var.
(ipa_pta_execute): Properly implement IPA PTA.
* tree-into-ssa.c (dump_decl_set): Support dumping
decls not in referenced-vars.
* tree-flow.h (struct gimple_df): Add ipa_pta flag.
* tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Adjust.
(dump_points_to_solution): Likewise.
* tree-dfa.c (dump_variable): Also dump DECL_PT_UID.
* tree-inline.c (remap_ssa_name): Copy IPA points-to solution.
(remap_gimple_stmt): Reset call clobber/use information if
necessary.
(copy_decl_to_var): Copy DECL_PT_UID.
(copy_result_decl_to_var): Likewise.
* tree.c (make_node_stat): Initialize DECL_PT_UID.
(copy_node_stat): Copy it.
* tree.h (DECL_PT_UID): New macro.
(SET_DECL_PT_UID): Likewise.
(DECL_PT_UID_SET_P): Likewise.
(struct tree_decl_minimal): Add pt_uid member.
* tree-ssa-alias.h (struct pt_solution): Add ipa_escaped flag.
(pt_solution_empty_p): Declare.
(pt_solution_set): Adjust.
(ipa_escaped_pt): Declare.
* cfgexpand.c (update_alias_info_with_stack_vars): Adjust.
* gimple-pretty-print.c (pp_points_to_solution): New function.
(dump_gimple_call): Dump call clobber/use information.
* tree-dump.c (dump_option_value_in): Add TDF_ALIAS entry.
* tree-pass.h (TDF_ALIAS): New dump option.
* tree-pretty-print.c (dump_decl_name): Dump DECL_PT_UID if asked to.
* doc/invoke.texi (-fipa-pta): Update documentation.

* gcc.dg/ipa/ipa-pta-1.c: New testcase.
* gcc.dg/ipa/ipa-pta-2.c: Likewise.
* gcc.dg/ipa/ipa-pta-3.c: Likewise.
* gcc.dg/ipa/ipa-pta-4.c: Likewise.
* gcc.dg/ipa/ipa-pta-5.c: Likewise.
* gcc.dg/ipa/ipa-pta-6.c: Likewise.
* gcc.dg/ipa/ipa-pta-7.c: Likewise.
* gcc.dg/ipa/ipa-pta-8.c: Likewise.
* gcc.dg/ipa/ipa-pta-9.c: Likewise.
* gcc.dg/ipa/ipa-pta-10.c: Likewise.
* gcc.dg/ipa/ipa-pta-11.c: Likewise.
* gcc.dg/ipa/ipa-pta-12.c: Likewise.
* gcc.dg/ipa/ipa-pta-13.c: Likewise.
* gcc.dg/torture/ipa-pta-2.c: Likewise.
* gcc.dg/torture/ipa-pta-1.c: Adjust.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158374 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
gcc/tree-inline.c
gcc/tree-ssa-structalias.c
gcc/tree.h

index b4ece29..4d6eed3 100644 (file)
@@ -1,5 +1,70 @@
 2010-04-15  Richard Guenther  <rguenther@suse.de>
 
+       * tree-ssa-structalias.c (struct variable_info): Add
+       is_fn_info flag.
+       (new_var_info): Initialize it.
+       (dump_constraints): Support printing last added constraints.
+       (debug_constraints): Adjust.
+       (dump_constraint_graph): Likewise.
+       (make_heapvar_for): Check for NULL cfun.
+       (get_function_part_constraint): New function.
+       (get_fi_for_callee): Likewise.
+       (find_func_aliases): Properly implement IPA PTA constraints.
+       (process_ipa_clobber): New function.
+       (find_func_clobbers): Likewise.
+       (insert_into_field_list_sorted): Remove.
+       (create_function_info_for): Properly allocate vars for IPA mode.
+       Do not use insert_into_field_list_sorted.
+       (create_variable_info_for): Properly generate constraints for
+       global vars in IPA mode.
+       (dump_solution_for_var): Always dump the solution.
+       (set_uids_in_ptset): Initialize DECL_PT_UID if in ipa-mode.
+       (find_what_var_points_to): Adjust.
+       (pt_solution_set): Change.
+       (pt_solution_ior_into): New function.
+       (pt_solution_empty_p): Export.
+       (pt_solution_includes_global): Adjust.
+       (pt_solution_includes_1): Likewise.
+       (pt_solutions_intersect_1): Likewise.
+       (dump_sa_points_to_info): Check some invariants.
+       (solve_constraints): Move constraint dumping ...
+       (compute_points_to_sets): ... here.
+       (ipa_pta_execute): ... and here.
+       (compute_may_aliases): Do not re-compute points-to info
+       locally if IPA info is available.
+       (ipa_escaped_pt): New global var.
+       (ipa_pta_execute): Properly implement IPA PTA.
+       * tree-into-ssa.c (dump_decl_set): Support dumping
+       decls not in referenced-vars.
+       * tree-flow.h (struct gimple_df): Add ipa_pta flag.
+       * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Adjust.
+       (dump_points_to_solution): Likewise.
+       * tree-dfa.c (dump_variable): Also dump DECL_PT_UID.
+       * tree-inline.c (remap_ssa_name): Copy IPA points-to solution.
+       (remap_gimple_stmt): Reset call clobber/use information if
+       necessary.
+       (copy_decl_to_var): Copy DECL_PT_UID.
+       (copy_result_decl_to_var): Likewise.
+       * tree.c (make_node_stat): Initialize DECL_PT_UID.
+       (copy_node_stat): Copy it.
+       * tree.h (DECL_PT_UID): New macro.
+       (SET_DECL_PT_UID): Likewise.
+       (DECL_PT_UID_SET_P): Likewise.
+       (struct tree_decl_minimal): Add pt_uid member.
+       * tree-ssa-alias.h (struct pt_solution): Add ipa_escaped flag.
+       (pt_solution_empty_p): Declare.
+       (pt_solution_set): Adjust.
+       (ipa_escaped_pt): Declare.
+       * cfgexpand.c (update_alias_info_with_stack_vars): Adjust.
+       * gimple-pretty-print.c (pp_points_to_solution): New function.
+       (dump_gimple_call): Dump call clobber/use information.
+       * tree-dump.c (dump_option_value_in): Add TDF_ALIAS entry.
+       * tree-pass.h (TDF_ALIAS): New dump option.
+       * tree-pretty-print.c (dump_decl_name): Dump DECL_PT_UID if asked to.
+       * doc/invoke.texi (-fipa-pta): Update documentation.
+
+2010-04-15  Richard Guenther  <rguenther@suse.de>
+
        * Makefile.in (OBJS-common): Add gimple-fold.o.
        (gimple-fold.o): New rule.
        * tree.h (maybe_fold_offset_to_reference,
index 6afc713..107fabe 100644 (file)
@@ -6647,15 +6647,6 @@ and reference analysis.  This option can cause excessive memory and
 compile-time usage on large compilation units.  It is not enabled by
 default at any optimization level.
 
-@item -fipa-profile
-@opindex fipa-profile
-Perform interprocedural profile propagation.  The functions called only from
-cold functions are marked as cold. Also functions executed once (such as
-@code{cold}, @code{noreturn}, static constructors or destructors) are identified. Cold
-functions and loop less parts of functions executed once are then optimized for
-size.
-Enabled by default at @option{-O} and higher.
-
 @item -fipa-cp
 @opindex fipa-cp
 Perform interprocedural constant propagation.
index 031d0b4..b60f087 100644 (file)
@@ -1,3 +1,21 @@
+2010-04-15  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/ipa/ipa-pta-1.c: New testcase.
+       * gcc.dg/ipa/ipa-pta-2.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-3.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-4.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-5.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-6.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-7.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-8.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-9.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-10.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-11.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-12.c: Likewise.
+       * gcc.dg/ipa/ipa-pta-13.c: Likewise.
+       * gcc.dg/torture/ipa-pta-2.c: Likewise.
+       * gcc.dg/torture/ipa-pta-1.c: Adjust.
+
 2010-04-14  Bernd Schmidt  <bernd.schmidt@codesourcery.com>
 
        PR target/21803
index dadb166..947ab81 100644 (file)
@@ -21,9 +21,6 @@ int l;
 int *s = &l;
 /* { dg-final { scan-ipa-dump "s = { ESCAPED NONLOCAL l }" "pta" } } */
 
-/* Make p and q referenced so they do not get optimized out.  */
-int foo() { return &p < &q; }
-
 int main()
 {
   return 0;
index 64d29c6..bb2ee23 100644 (file)
@@ -1411,12 +1411,11 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
                    break;
                  }
 
-             /* Reset alias info.
-                ???  By maintaining DECL_PT_UID this should not
-                be necessary, but the plan is to only maintain
-                it when IPA-PTA was run.  It's not too easy to
-                detect this here ...  */
-             gimple_call_reset_alias_info (copy);
+             /* Reset alias info if we didn't apply measures to
+                keep it valid over inlining by setting DECL_PT_UID.  */
+             if (!id->src_cfun->gimple_df
+                 || !id->src_cfun->gimple_df->ipa_pta)
+               gimple_call_reset_alias_info (copy);
            }
            break;
 
index c1ce673..c11d3b8 100644 (file)
@@ -3694,10 +3694,7 @@ get_function_part_constraint (varinfo_t fi, unsigned part)
   else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
     {
       varinfo_t ai = first_vi_for_offset (fi, part);
-      if (ai)
-       c.var = ai->id;
-      else
-       c.var = anything_id;
+      c.var = ai ? ai->id : anything_id;
       c.offset = 0;
       c.type = SCALAR;
     }
@@ -4309,7 +4306,7 @@ find_func_aliases (gimple origt)
          /* If we are returning a value, assign it to the result.  */
          lhsop = gimple_call_lhs (t);
          if (lhsop
-             && type_could_have_pointers (TREE_TYPE (lhsop)))
+             && could_have_pointers (lhsop))
            {
              struct constraint_expr rhs;
              struct constraint_expr *lhsp;
@@ -4818,29 +4815,36 @@ first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
    OFFSET.  If there is no such varinfo the varinfo directly preceding
    OFFSET is returned.  */
 
-static varinfo_t
-first_or_preceding_vi_for_offset (varinfo_t start,
-                                 unsigned HOST_WIDE_INT offset)
+static void
+process_ipa_clobber (varinfo_t fi, tree ptr)
 {
-  /* If we cannot reach offset from start, lookup the first field
-     and start from there.  */
-  if (start->offset > offset)
-    start = lookup_vi_for_tree (start->decl);
+  VEC(ce_s, heap) *ptrc = NULL;
+  struct constraint_expr *c, lhs;
+  unsigned i;
+  get_constraint_for (ptr, &ptrc);
+  lhs = get_function_part_constraint (fi, fi_clobbers);
+  for (i = 0; VEC_iterate (ce_s, ptrc, i, c); i++)
+    process_constraint (new_constraint (lhs, *c));
+  VEC_free (ce_s, heap, ptrc);
+}
 
-  /* We may not find a variable in the field list with the actual
-     offset when when we have glommed a structure to a variable.
-     In that case, however, offset should still be within the size
-     of the variable.
-     If we got beyond the offset we look for return the field
-     directly preceding offset which may be the last field.  */
-  while (start->next
-        && offset >= start->offset
-        && !((offset - start->offset) < start->size))
-    start = start->next;
+/* Walk statement T setting up clobber and use constraints according to the
+   references found in T.  This function is a main part of the
+   IPA constraint builder.  */
 
-  return start;
-}
+static void
+find_func_clobbers (gimple origt)
+{
+  gimple t = origt;
+  VEC(ce_s, heap) *lhsc = NULL;
+  VEC(ce_s, heap) *rhsc = NULL;
+  varinfo_t fi;
 
+  /* Add constraints for clobbered/used in IPA mode.
+     We are not interested in what automatic variables are clobbered
+     or used as we only use the information in the caller to which
+     they do not escape.  */
+  gcc_assert (in_ipa_mode);
 
 /* This structure is used during pushing fields onto the fieldstack
    to track the offset of the field, since bitpos_of_field gives it
@@ -5084,6 +5088,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < clobbervi->offset);
       prev_vi->next = clobbervi;
       prev_vi = clobbervi;
+      stats.total_vars++;
 
       asprintf (&tempname, "%s.use", name);
       newname = ggc_strdup (tempname);
@@ -5098,6 +5103,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < usevi->offset);
       prev_vi->next = usevi;
       prev_vi = usevi;
+      stats.total_vars++;
     }
 
   /* And one for the static chain.  */
@@ -5120,6 +5126,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < chainvi->offset);
       prev_vi->next = chainvi;
       prev_vi = chainvi;
+      stats.total_vars++;
       insert_vi_for_tree (fn->static_chain_decl, chainvi);
     }
 
@@ -5149,6 +5156,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < resultvi->offset);
       prev_vi->next = resultvi;
       prev_vi = resultvi;
+      stats.total_vars++;
       if (DECL_RESULT (decl))
        insert_vi_for_tree (DECL_RESULT (decl), resultvi);
     }
@@ -5179,6 +5187,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < argvi->offset);
       prev_vi->next = argvi;
       prev_vi = argvi;
+      stats.total_vars++;
       if (arg)
        {
          insert_vi_for_tree (arg, argvi);
@@ -5211,6 +5220,7 @@ create_function_info_for (tree decl, const char *name)
       gcc_assert (prev_vi->offset < argvi->offset);
       prev_vi->next = argvi;
       prev_vi = argvi;
+      stats.total_vars++;
     }
 
   return vi;
@@ -5256,11 +5266,62 @@ create_variable_info_for_1 (tree decl, const char *name)
       vi = new_var_info (decl, name);
       vi->offset = 0;
       vi->size = ~0;
-      vi->fullsize = ~0;
-      vi->is_unknown_size_var = true;
-      vi->is_full_var = true;
-      vi->may_have_pointers = could_have_pointers (decl);
-      return vi;
+    }
+  else
+    {
+      vi->fullsize = TREE_INT_CST_LOW (declsize);
+      vi->size = vi->fullsize;
+    }
+
+  insert_vi_for_tree (vi->decl, vi);
+
+  /* ???  The setting of vi->may_have_pointers is too conservative here
+     and may get refined below.  Thus we have superfluous constraints
+     here sometimes which triggers the commented assert in
+     dump_sa_points_to_info.  */
+  if (vi->is_global_var
+      && vi->may_have_pointers)
+    {
+      /* Mark global restrict qualified pointers.  */
+      if (POINTER_TYPE_P (TREE_TYPE (decl))
+         && TYPE_RESTRICT (TREE_TYPE (decl)))
+       make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
+
+      /* For escaped variables initialize them from nonlocal.  */
+      if (!in_ipa_mode
+         || DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
+       make_copy_constraint (vi, nonlocal_id);
+
+      /* If this is a global variable with an initializer and we are in
+        IPA mode generate constraints for it.  In non-IPA mode
+        the initializer from nonlocal is all we need.  */
+      if (in_ipa_mode
+         && DECL_INITIAL (vi->decl))
+       {
+         VEC (ce_s, heap) *rhsc = NULL;
+         struct constraint_expr lhs, *rhsp;
+         unsigned i;
+         get_constraint_for (DECL_INITIAL (vi->decl), &rhsc);
+         lhs.var = vi->id;
+         lhs.offset = 0;
+         lhs.type = SCALAR;
+         for (i = 0; VEC_iterate (ce_s, rhsc, i, rhsp); ++i)
+           process_constraint (new_constraint (lhs, *rhsp));
+         /* If this is a variable that escapes from the unit
+            the initializer escapes as well.  */
+         if (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
+           {
+             lhs.var = escaped_id;
+             lhs.offset = 0;
+             lhs.type = SCALAR;
+             for (i = 0; VEC_iterate (ce_s, rhsc, i, rhsp); ++i)
+               process_constraint (new_constraint (lhs, *rhsp));
+           }
+         VEC_free (ce_s, heap, rhsc);
+         /* ???  Force us to not use subfields.  Else we'd have to parse
+            arbitrary initializers.  */
+         VEC_free (fieldoff_s, heap, fieldstack);
+       }
     }
 
   /* Collect field information.  */
@@ -5331,7 +5392,10 @@ create_variable_info_for_1 (tree decl, const char *name)
       const char *newname = "NULL";
       char *tempname;
 
-      if (dump_file)
+      vi->offset = fo->offset;
+      vi->may_have_pointers = fo->may_have_pointers;
+      if (vi->is_global_var
+         && vi->may_have_pointers)
        {
          asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
                    "+" HOST_WIDE_INT_PRINT_DEC, name, fo->offset, fo->size);
@@ -5660,7 +5724,12 @@ find_what_var_points_to (varinfo_t orig_vi, struct pt_solution *pt)
          if (vi->id == nothing_id)
            pt->null = 1;
          else if (vi->id == escaped_id)
-           pt->escaped = 1;
+           {
+             if (in_ipa_mode)
+               pt->ipa_escaped = 1;
+             else
+               pt->escaped = 1;
+           }
          else if (vi->id == nonlocal_id)
            pt->nonlocal = 1;
          else if (vi->is_heap_var)
@@ -6025,7 +6094,13 @@ dump_sa_points_to_info (FILE *outfile)
     {
       varinfo_t vi = get_varinfo (i);
       if (!vi->may_have_pointers)
-       continue;
+       {
+         gcc_assert (find (i) == i
+                     || !(vi = get_varinfo (find (i)))->may_have_pointers);
+         /* ???  See create_variable_info_for.
+            gcc_assert (bitmap_empty_p (vi->solution));  */
+         continue;
+       }
       dump_solution_for_var (outfile, i);
     }
 }
@@ -6657,26 +6732,13 @@ ipa_pta_execute (void)
          || node->clone_of)
        continue;
 
-      vi = create_function_info_for (node->decl,
-                                    alias_get_name (node->decl));
-
-      /* Associate the varinfo node with all aliases.  */
-      for (alias = node->same_body; alias; alias = alias->next)
-       insert_vi_for_tree (alias->decl, vi);
+      create_function_info_for (node->decl,
+                               cgraph_node_name (node));
     }
 
   /* Create constraints for global variables and their initializers.  */
   for (var = varpool_nodes; var; var = var->next)
-    {
-      struct varpool_node *alias;
-      varinfo_t vi;
-
-      vi = get_vi_for_tree (var->decl);
-
-      /* Associate the varinfo node with all aliases.  */
-      for (alias = var->extra_name; alias; alias = alias->next)
-       insert_vi_for_tree (alias->decl, vi);
-    }
+    get_vi_for_tree (var->decl);
 
   if (dump_file)
     {
index e2f54a3..ace4ae6 100644 (file)
@@ -2501,16 +2501,12 @@ struct function;
 
 /* Every ..._DECL node gets a unique number that stays the same even
    when the decl is copied by the inliner once it is set.  */
-#define DECL_PT_UID(NODE) \
-  (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid == -1u \
-   ? (NODE)->decl_minimal.uid : (NODE)->decl_common.pt_uid)
+#define DECL_PT_UID(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.pt_uid == -1u ? (NODE)->decl_minimal.uid : (NODE)->decl_minimal.pt_uid)
 /* Initialize the ..._DECL node pt-uid to the decls uid.  */
-#define SET_DECL_PT_UID(NODE, UID) \
-  (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid = (UID))
+#define SET_DECL_PT_UID(NODE, UID) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.pt_uid = (UID))
 /* Whether the ..._DECL node pt-uid has been initialized and thus needs to
    be preserved when copyin the decl.  */
-#define DECL_PT_UID_SET_P(NODE) \
-  (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid != -1u)
+#define DECL_PT_UID_SET_P(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.pt_uid != -1u)
 
 /* These two fields describe where in the source code the declaration
    was.  If the declaration appears in several places (as for a C
@@ -2537,6 +2533,7 @@ struct GTY(()) tree_decl_minimal {
   struct tree_common common;
   location_t locus;
   unsigned int uid;
+  unsigned int pt_uid;
   tree name;
   tree context;
 };