summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-10 09:41:08 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-10 09:41:08 +0000
commit7ae97ba6651703d99d9f0e20a4e48eb7743c103c (patch)
treed9310279809b94e076740c9f2881ea95cf1aea97 /gcc/tree-ssa-structalias.c
parent6c2acfc4892316b46df0fe4a6769fb6766ab1e0b (diff)
downloadgcc-7ae97ba6651703d99d9f0e20a4e48eb7743c103c.tar.gz
2015-12-10 Richard Biener <rguenther@suse.de>
PR ipa/68331 * tree-ssa-structalias.c (set_uids_in_ptset): Add fndecl parameter and make vars_contains_nonlocal properly have function-scope semantics in IPA mode. (find_what_var_points_to): Add fndecl parameter. (find_what_p_points_to): Likewise. (pt_solution_includes_global): Remove IPA PTA early out. (compute_points_to_sets): Adjust. (ipa_pta_execute): Likewise. Clear final_solutions after each function. * gcc.dg/torture/ipa-pta-3.c: New testcase. * g++.dg/ipa/ipa-pta-1.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231498 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c69
1 files changed, 42 insertions, 27 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index ec30e1d6f48..5d29e5cca66 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -159,9 +159,7 @@
The is_global_var bit which marks escape points is overly conservative
in IPA mode. Split it to is_escape_point and is_global_var - only
- externally visible globals are escape points in IPA mode. This is
- also needed to fix the pt_solution_includes_global predicate
- (and thus ptr_deref_may_alias_global_p).
+ externally visible globals are escape points in IPA mode.
The way we introduce DECL_PT_UID to avoid fixing up all points-to
sets in the translation unit when we copy a DECL during inlining
@@ -186,6 +184,7 @@
propagating it simply like the clobber / uses solutions. The
solution can go alongside the non-IPA espaced solution and be
used to query which vars escape the unit through a function.
+ This is also required to make the escaped-HEAP trick work in IPA mode.
We never put function decls in points-to sets so we do not
keep the set of called functions for indirect calls.
@@ -6150,7 +6149,8 @@ shared_bitmap_add (bitmap pt_vars)
/* Set bits in INTO corresponding to the variable uids in solution set FROM. */
static void
-set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
+set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
+ tree fndecl)
{
unsigned int i;
bitmap_iterator bi;
@@ -6188,7 +6188,19 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
/* Add the decl to the points-to set. Note that the points-to
set contains global variables. */
bitmap_set_bit (into, DECL_PT_UID (vi->decl));
- if (vi->is_global_var)
+ if (vi->is_global_var
+ /* In IPA mode the escaped_heap trick doesn't work as
+ ESCAPED is escaped from the unit but
+ pt_solution_includes_global needs to answer true for
+ all variables not automatic within a function.
+ For the same reason is_global_var is not the
+ correct flag to track - local variables from other
+ functions also need to be considered global.
+ Conveniently all HEAP vars are not put in function
+ scope. */
+ || (in_ipa_mode
+ && fndecl
+ && ! auto_var_in_fn_p (vi->decl, fndecl)))
pt->vars_contains_nonlocal = true;
}
}
@@ -6198,7 +6210,7 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
/* Compute the points-to solution *PT for the variable VI. */
static struct pt_solution
-find_what_var_points_to (varinfo_t orig_vi)
+find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
{
unsigned int i;
bitmap_iterator bi;
@@ -6263,7 +6275,7 @@ find_what_var_points_to (varinfo_t orig_vi)
finished_solution = BITMAP_GGC_ALLOC ();
stats.points_to_sets_created++;
- set_uids_in_ptset (finished_solution, vi->solution, pt);
+ set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl);
result = shared_bitmap_lookup (finished_solution);
if (!result)
{
@@ -6282,7 +6294,7 @@ find_what_var_points_to (varinfo_t orig_vi)
/* Given a pointer variable P, fill in its points-to set. */
static void
-find_what_p_points_to (tree p)
+find_what_p_points_to (tree fndecl, tree p)
{
struct ptr_info_def *pi;
tree lookup_p = p;
@@ -6301,7 +6313,7 @@ find_what_p_points_to (tree p)
return;
pi = get_ptr_info (p);
- pi->pt = find_what_var_points_to (vi);
+ pi->pt = find_what_var_points_to (fndecl, vi);
}
@@ -6467,12 +6479,6 @@ pt_solution_includes_global (struct pt_solution *pt)
if (pt->ipa_escaped)
return pt_solution_includes_global (&ipa_escaped_pt);
- /* ??? This predicate is not correct for the IPA-PTA solution
- as we do not properly distinguish between unit escape points
- and global variables. */
- if (cfun->gimple_df->ipa_pta)
- return true;
-
return false;
}
@@ -6969,7 +6975,8 @@ compute_points_to_sets (void)
solve_constraints ();
/* Compute the points-to set for ESCAPED used for call-clobber analysis. */
- cfun->gimple_df->escaped = find_what_var_points_to (get_varinfo (escaped_id));
+ cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl,
+ get_varinfo (escaped_id));
/* Make sure the ESCAPED solution (which is used as placeholder in
other solutions) does not reference itself. This simplifies
@@ -6982,7 +6989,7 @@ compute_points_to_sets (void)
tree ptr = ssa_name (i);
if (ptr
&& POINTER_TYPE_P (TREE_TYPE (ptr)))
- find_what_p_points_to (ptr);
+ find_what_p_points_to (cfun->decl, ptr);
}
/* Compute the call-used/clobbered sets. */
@@ -7004,7 +7011,7 @@ compute_points_to_sets (void)
memset (pt, 0, sizeof (struct pt_solution));
else if ((vi = lookup_call_use_vi (stmt)) != NULL)
{
- *pt = find_what_var_points_to (vi);
+ *pt = find_what_var_points_to (cfun->decl, vi);
/* Escaped (and thus nonlocal) variables are always
implicitly used by calls. */
/* ??? ESCAPED can be empty even though NONLOCAL
@@ -7025,7 +7032,7 @@ compute_points_to_sets (void)
memset (pt, 0, sizeof (struct pt_solution));
else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
{
- *pt = find_what_var_points_to (vi);
+ *pt = find_what_var_points_to (cfun->decl, vi);
/* Escaped (and thus nonlocal) variables are always
implicitly clobbered by calls. */
/* ??? ESCAPED can be empty even though NONLOCAL
@@ -7565,7 +7572,7 @@ ipa_pta_execute (void)
??? Note that the computed escape set is not correct
for the whole unit as we fail to consider graph edges to
externally visible functions. */
- ipa_escaped_pt = find_what_var_points_to (get_varinfo (escaped_id));
+ ipa_escaped_pt = find_what_var_points_to (NULL, get_varinfo (escaped_id));
/* Make sure the ESCAPED solution (which is used as placeholder in
other solutions) does not reference itself. This simplifies
@@ -7591,7 +7598,7 @@ ipa_pta_execute (void)
{
if (ptr
&& POINTER_TYPE_P (TREE_TYPE (ptr)))
- find_what_p_points_to (ptr);
+ find_what_p_points_to (node->decl, ptr);
}
/* Compute the call-use and call-clobber sets for indirect calls
@@ -7625,10 +7632,10 @@ ipa_pta_execute (void)
{
*gimple_call_clobber_set (stmt)
= find_what_var_points_to
- (first_vi_for_offset (fi, fi_clobbers));
+ (node->decl, first_vi_for_offset (fi, fi_clobbers));
*gimple_call_use_set (stmt)
= find_what_var_points_to
- (first_vi_for_offset (fi, fi_uses));
+ (node->decl, first_vi_for_offset (fi, fi_uses));
}
/* Handle direct calls to external functions. */
else if (decl)
@@ -7638,7 +7645,7 @@ ipa_pta_execute (void)
memset (pt, 0, sizeof (struct pt_solution));
else if ((vi = lookup_call_use_vi (stmt)) != NULL)
{
- *pt = find_what_var_points_to (vi);
+ *pt = find_what_var_points_to (node->decl, vi);
/* Escaped (and thus nonlocal) variables are always
implicitly used by calls. */
/* ??? ESCAPED can be empty even though NONLOCAL
@@ -7659,7 +7666,7 @@ ipa_pta_execute (void)
memset (pt, 0, sizeof (struct pt_solution));
else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
{
- *pt = find_what_var_points_to (vi);
+ *pt = find_what_var_points_to (node->decl, vi);
/* Escaped (and thus nonlocal) variables are always
implicitly clobbered by calls. */
/* ??? ESCAPED can be empty even though NONLOCAL
@@ -7719,13 +7726,15 @@ ipa_pta_execute (void)
if (!uses->anything)
{
sol = find_what_var_points_to
- (first_vi_for_offset (vi, fi_uses));
+ (node->decl,
+ first_vi_for_offset (vi, fi_uses));
pt_solution_ior_into (uses, &sol);
}
if (!clobbers->anything)
{
sol = find_what_var_points_to
- (first_vi_for_offset (vi, fi_clobbers));
+ (node->decl,
+ first_vi_for_offset (vi, fi_clobbers));
pt_solution_ior_into (clobbers, &sol);
}
}
@@ -7735,6 +7744,12 @@ ipa_pta_execute (void)
}
fn->gimple_df->ipa_pta = true;
+
+ /* We have to re-set the final-solution cache after each function
+ because what is a "global" is dependent on function context. */
+ final_solutions->empty ();
+ obstack_free (&final_solutions_obstack, NULL);
+ gcc_obstack_init (&final_solutions_obstack);
}
delete_points_to_sets ();