The following records whether a points-to solution contains any
local automatic variables, not including parameters or result storage.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

This was requested by HJ (or rather suggested by me).

Richard.

        * tree-ssa-alias.h (pt_solution::vars_contains_auto): New.
        (ptr_deref_may_alias_auto_p): Declare.
        (pt_solution_includes_auto): Likewise.
        * tree-ssa-structalias.cc (set_uids_in_ptset): Record auto
        variables.
        (pt_solution_includes_auto): New function.
        (ipa_escaped_pt): Adjust.
        * tree-ssa-alias.cc (ptr_deref_may_alias_auto_p): New function.
---
 gcc/tree-ssa-alias.cc       | 24 ++++++++++++++++++++++++
 gcc/tree-ssa-alias.h        |  4 ++++
 gcc/tree-ssa-structalias.cc | 30 +++++++++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index 467ef1c215f..1d10f6dbd97 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -238,6 +238,30 @@ ptr_deref_may_alias_global_p (tree ptr, bool 
escaped_local_p)
   return pt_solution_includes_global (&pi->pt, escaped_local_p);
 }
 
+/* Return true, if dereferencing PTR may alias with a local automatic
+   variable.  */
+
+bool
+ptr_deref_may_alias_auto_p (tree ptr)
+{
+  struct ptr_info_def *pi;
+
+  /* If we end up with a pointer constant here that may point
+     to local stack memory.  */
+  if (TREE_CODE (ptr) != SSA_NAME)
+    return true;
+
+  pi = SSA_NAME_PTR_INFO (ptr);
+
+  /* If we do not have points-to information for this variable,
+     we have to punt.  */
+  if (!pi)
+    return true;
+
+  return pt_solution_includes_auto (&pi->pt);
+}
+
+
 /* Return true if dereferencing PTR may alias DECL.
    The caller is responsible for applying TBAA to see if PTR
    may access DECL at all.  */
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index e0785c5d4bb..ccac9c539bb 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -54,6 +54,8 @@ struct GTY(()) pt_solution
 
   /* Nonzero if the vars bitmap includes a variable included in 'nonlocal'.  */
   unsigned int vars_contains_nonlocal : 1;
+  /* Nonzero if the vars bitmap includes a local automatic variable.  */
+  unsigned int vars_contains_auto : 1;
   /* Nonzero if the vars bitmap includes a variable included in 'escaped'.  */
   unsigned int vars_contains_escaped : 1;
   /* Nonzero if the vars bitmap includes a anonymous heap variable that
@@ -127,6 +129,7 @@ extern tree ao_ref_base_alias_ptr_type (ao_ref *);
 extern bool ao_ref_alignment (ao_ref *, unsigned int *,
                              unsigned HOST_WIDE_INT *);
 extern bool ptr_deref_may_alias_global_p (tree, bool);
+extern bool ptr_deref_may_alias_auto_p (tree);
 extern bool ptr_derefs_may_alias_p (tree, tree);
 extern bool ptrs_compare_unequal (tree, tree);
 extern bool ref_may_alias_global_p (tree, bool);
@@ -182,6 +185,7 @@ extern unsigned int compute_may_aliases (void);
 extern bool pt_solution_empty_p (const pt_solution *);
 extern bool pt_solution_singleton_or_null_p (struct pt_solution *, unsigned *);
 extern bool pt_solution_includes_global (struct pt_solution *, bool);
+extern bool pt_solution_includes_auto (struct pt_solution *);
 extern bool pt_solution_includes (struct pt_solution *, const_tree);
 extern bool pt_solution_includes_const_pool (struct pt_solution *);
 extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution 
*);
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index ab6658a0981..3b557cc4cd1 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -801,6 +801,13 @@ set_uids_in_ptset (bitmap into, bitmap from, struct 
pt_solution *pt,
                  && ! auto_var_in_fn_p (vi->decl, fndecl)))
            pt->vars_contains_nonlocal = true;
 
+         /* If the variable is an automatic in the local stack frame, record
+            that.  Note this does not include PARM_DECL and RESULT_DECL which
+            are managed by the caller.  */
+         if (VAR_P (vi->decl)
+             && auto_var_in_fn_p (vi->decl, fndecl))
+           pt->vars_contains_auto = true;
+
          /* If we have a variable that is interposable record that fact
             for pointer comparison simplification.  */
          if (VAR_P (vi->decl)
@@ -1120,6 +1127,27 @@ pt_solution_includes_global (struct pt_solution *pt, 
bool escaped_local_p)
   return false;
 }
 
+/* Return true if the points-to solution *PT includes local automatic
+   storage.  */
+
+bool
+pt_solution_includes_auto (struct pt_solution *pt)
+{
+  if (pt->anything
+      || pt->vars_contains_auto)
+    return true;
+
+  /* 'escaped' is also a placeholder so we have to look into it.  */
+  if (pt->escaped)
+    return pt_solution_includes_auto (&cfun->gimple_df->escaped);
+
+  if (pt->ipa_escaped)
+    return pt_solution_includes_auto (&ipa_escaped_pt);
+
+  return false;
+}
+
+
 /* Return true if the points-to solution *PT includes the variable
    declaration DECL.  */
 
@@ -1803,7 +1831,7 @@ make_pass_build_ealias (gcc::context *ctxt)
 /* IPA PTA solutions for ESCAPED.  */
 struct pt_solution ipa_escaped_pt
   = { true, false, false, false, false, false,
-      false, false, false, false, false, NULL };
+      false, false, false, false, false, false, NULL };
 
 
 /* Execute the driver for IPA PTA.  */
-- 
2.51.0

Reply via email to