* [PATCH] tree-optimization/112653 - PTA and return
@ 2023-11-27 14:31 Richard Biener
0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2023-11-27 14:31 UTC (permalink / raw)
To: gcc-patches; +Cc: Jan Hubicka
The following separates the escape solution for return stmts not
only during points-to solving but also for later querying. This
requires adjusting the points-to-global tests to include escapes
through returns. Technically the patch replaces the existing
post-processing which computes the transitive closure of the
returned value solution by a proper artificial variable with
transitive closure constraints. Instead of adding the solution
to escaped we track it separately.
Bootstrapped and tested on x86_64-unknown-linux-gnu, will push.
Richard.
PR tree-optimization/112653
* gimple-ssa.h (gimple_df): Add escaped_return solution.
* tree-ssa.cc (init_tree_ssa): Reset it.
(delete_tree_ssa): Likewise.
* tree-ssa-structalias.cc (escaped_return_id): New.
(find_func_aliases): Handle non-IPA return stmts by
adding to ESCAPED_RETURN.
(set_uids_in_ptset): Adjust HEAP escaping to also cover
escapes through return.
(init_base_vars): Initialize ESCAPED_RETURN.
(compute_points_to_sets): Replace ESCAPED post-processing
with recording the ESCAPED_RETURN solution.
* tree-ssa-alias.cc (ref_may_alias_global_p_1): Check
the ESCAPED_RETUNR solution.
(dump_alias_info): Dump it.
* cfgexpand.cc (update_alias_info_with_stack_vars): Update it.
* ipa-icf.cc (sem_item_optimizer::fixup_points_to_sets):
Likewise.
* tree-parloops.cc (expand_call_inline): Reset it.
* tree-sra.cc (maybe_add_sra_candidate): Check it.
* gcc.dg/tree-ssa/pta-return-1.c: New testcase.
---
gcc/cfgexpand.cc | 3 +-
gcc/gimple-ssa.h | 4 +-
gcc/ipa-icf.cc | 1 +
gcc/testsuite/gcc.dg/tree-ssa/pta-return-1.c | 16 +++
gcc/tree-inline.cc | 5 +-
gcc/tree-parloops.cc | 5 +-
gcc/tree-sra.cc | 2 +-
gcc/tree-ssa-alias.cc | 6 +-
gcc/tree-ssa-structalias.cc | 124 +++++++------------
gcc/tree-ssa.cc | 2 +
10 files changed, 85 insertions(+), 83 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pta-return-1.c
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index e58327b239b..feed001f3c9 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -863,7 +863,8 @@ update_alias_info_with_stack_vars (void)
add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped,
decls_to_partitions, &visited, temp);
-
+ add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped_return,
+ decls_to_partitions, &visited, temp);
delete decls_to_partitions;
BITMAP_FREE (temp);
}
diff --git a/gcc/gimple-ssa.h b/gcc/gimple-ssa.h
index f2cffa2b159..79637058f70 100644
--- a/gcc/gimple-ssa.h
+++ b/gcc/gimple-ssa.h
@@ -76,8 +76,10 @@ struct GTY(()) gimple_df {
/* Artificial variable used for the virtual operand FUD chain. */
tree vop;
- /* The PTA solution for the ESCAPED artificial variable. */
+ /* The PTA solution for the ESCAPED and ESCAPED_RETURN artificial
+ variables. */
struct pt_solution escaped;
+ struct pt_solution escaped_return;
/* A map of decls to artificial ssa-names that point to the partition
of the decl. */
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index bbdfd445397..c72c9d57a80 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -3506,6 +3506,7 @@ sem_item_optimizer::fixup_points_to_sets (void)
&& SSA_NAME_PTR_INFO (name))
fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
fixup_pt_set (&fn->gimple_df->escaped);
+ fixup_pt_set (&fn->gimple_df->escaped_return);
/* The above gets us to 99% I guess, at least catching the
address compares. Below also gets us aliasing correct
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-return-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-return-1.c
new file mode 100644
index 00000000000..9c2416e7810
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-return-1.c
@@ -0,0 +1,16 @@
+/* PR112653 */
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+char *test;
+char *
+copy_test ()
+{
+ char *test2 = __builtin_malloc (1000);
+ __builtin_memmove (test2, test, 1000);
+ return test2;
+}
+
+/* We should be able to turn the memmove into memcpy by means of alias
+ analysis. */
+/* { dg-final { scan-tree-dump "memcpy" "optimized" } } */
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 0b14118b94b..59847166842 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -5147,7 +5147,10 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
/* Reset the escaped solution. */
if (cfun->gimple_df)
- pt_solution_reset (&cfun->gimple_df->escaped);
+ {
+ pt_solution_reset (&cfun->gimple_df->escaped);
+ pt_solution_reset (&cfun->gimple_df->escaped_return);
+ }
/* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */
if (id->dst_simt_vars && id->dst_simt_vars->length () > 0)
diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc
index 80f3dd6dce2..50e61f00413 100644
--- a/gcc/tree-parloops.cc
+++ b/gcc/tree-parloops.cc
@@ -4147,7 +4147,10 @@ parallelize_loops (bool oacc_kernels_p)
which local variables will escape. Reset the points-to solution
for ESCAPED. */
if (changed)
- pt_solution_reset (&cfun->gimple_df->escaped);
+ {
+ pt_solution_reset (&cfun->gimple_df->escaped);
+ pt_solution_reset (&cfun->gimple_df->escaped_return);
+ }
return changed;
}
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 3a0d52675fe..0349410972e 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -2026,7 +2026,7 @@ maybe_add_sra_candidate (tree var)
/* There are cases where non-addressable variables fail the
pt_solutions_check test, e.g in gcc.dg/uninit-40.c. */
|| (TREE_ADDRESSABLE (var)
- && pt_solution_includes (&cfun->gimple_df->escaped, var))
+ && pt_solution_includes (&cfun->gimple_df->escaped_return, var))
|| (TREE_CODE (var) == RESULT_DECL
&& !DECL_BY_REFERENCE (var)
&& aggregate_value_p (var, current_function_decl)))
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index 373940b5f6c..a708f7e8d28 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -496,7 +496,8 @@ ref_may_alias_global_p_1 (tree base, bool escaped_local_p)
if (DECL_P (base))
return (is_global_var (base)
|| (escaped_local_p
- && pt_solution_includes (&cfun->gimple_df->escaped, base)));
+ && pt_solution_includes (&cfun->gimple_df->escaped_return,
+ base)));
else if (TREE_CODE (base) == MEM_REF
|| TREE_CODE (base) == TARGET_MEM_REF)
return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0),
@@ -579,6 +580,9 @@ dump_alias_info (FILE *file)
fprintf (file, "\nESCAPED");
dump_points_to_solution (file, &cfun->gimple_df->escaped);
+ fprintf (file, "\nESCAPED_RETURN");
+ dump_points_to_solution (file, &cfun->gimple_df->escaped_return);
+
fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
FOR_EACH_SSA_NAME (i, ptr, cfun)
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index ee9313c59ca..6db10d5fe11 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -365,8 +365,8 @@ vi_next (varinfo_t vi)
/* Static IDs for the special variables. Variable ID zero is unused
and used as terminator for the sub-variable chain. */
enum { nothing_id = 1, anything_id = 2, string_id = 3,
- escaped_id = 4, nonlocal_id = 5,
- storedanything_id = 6, integer_id = 7 };
+ escaped_id = 4, nonlocal_id = 5, escaped_return_id = 6,
+ storedanything_id = 7, integer_id = 8 };
/* Return a new variable info structure consisting for a variable
named NAME, and using constraint graph node NODE. Append it
@@ -5221,23 +5221,18 @@ find_func_aliases (struct function *fn, gimple *origt)
&& gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
{
greturn *return_stmt = as_a <greturn *> (t);
- fi = NULL;
- if (!in_ipa_mode
- && SSA_VAR_P (gimple_return_retval (return_stmt)))
- {
- /* We handle simple returns by post-processing the solutions. */
- ;
- }
- if (!(fi = get_vi_for_tree (fn->decl)))
- make_escape_constraint (gimple_return_retval (return_stmt));
- else if (in_ipa_mode)
+ tree retval = gimple_return_retval (return_stmt);
+ if (!in_ipa_mode)
+ make_constraint_to (escaped_return_id, retval);
+ else
{
struct constraint_expr lhs ;
struct constraint_expr *rhsp;
unsigned i;
+ fi = lookup_vi_for_tree (fn->decl);
lhs = get_function_part_constraint (fi, fi_result);
- get_constraint_for_rhs (gimple_return_retval (return_stmt), &rhsc);
+ get_constraint_for_rhs (retval, &rhsc);
FOR_EACH_VEC_ELT (rhsc, i, rhsp)
process_constraint (new_constraint (lhs, *rhsp));
}
@@ -6665,6 +6660,7 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
unsigned int i;
bitmap_iterator bi;
varinfo_t escaped_vi = get_varinfo (find (escaped_id));
+ varinfo_t escaped_return_vi = get_varinfo (find (escaped_return_id));
bool everything_escaped
= escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
@@ -6682,6 +6678,9 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
pt->vars_contains_escaped = true;
pt->vars_contains_escaped_heap |= vi->is_heap_var;
}
+ if (escaped_return_vi->solution
+ && bitmap_bit_p (escaped_return_vi->solution, i))
+ pt->vars_contains_escaped_heap |= vi->is_heap_var;
if (vi->is_restrict_var)
pt->vars_contains_restrict = true;
@@ -7196,6 +7195,7 @@ init_base_vars (void)
varinfo_t var_string;
varinfo_t var_escaped;
varinfo_t var_nonlocal;
+ varinfo_t var_escaped_return;
varinfo_t var_storedanything;
varinfo_t var_integer;
@@ -7271,6 +7271,16 @@ init_base_vars (void)
var_nonlocal->fullsize = ~0;
var_nonlocal->is_special_var = 1;
+ /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
+ memory via a regular return stmt. */
+ var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
+ gcc_assert (var_escaped_return->id == escaped_return_id);
+ var_escaped_return->is_artificial_var = 1;
+ var_escaped_return->offset = 0;
+ var_escaped_return->size = ~0;
+ var_escaped_return->fullsize = ~0;
+ var_escaped_return->is_special_var = 0;
+
/* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
lhs.type = SCALAR;
lhs.var = escaped_id;
@@ -7315,6 +7325,24 @@ init_base_vars (void)
rhs.offset = 0;
process_constraint (new_constraint (lhs, rhs));
+ /* Transitively close ESCAPED_RETURN.
+ ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
+ ESCAPED_RETURN = *ESCAPED_RETURN. */
+ lhs.type = SCALAR;
+ lhs.var = escaped_return_id;
+ lhs.offset = 0;
+ rhs.type = SCALAR;
+ rhs.var = escaped_return_id;
+ rhs.offset = UNKNOWN_OFFSET;
+ process_constraint (new_constraint (lhs, rhs));
+ lhs.type = SCALAR;
+ lhs.var = escaped_return_id;
+ lhs.offset = 0;
+ rhs.type = DEREF;
+ rhs.var = escaped_return_id;
+ rhs.offset = 0;
+ process_constraint (new_constraint (lhs, rhs));
+
/* Create the STOREDANYTHING variable, used to represent the set of
variables stored to *ANYTHING. */
var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
@@ -7555,70 +7583,6 @@ compute_points_to_sets (void)
/* From the constraints compute the points-to sets. */
solve_constraints ();
- /* Post-process solutions for escapes through returns. */
- edge_iterator ei;
- edge e;
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
- if (greturn *ret = safe_dyn_cast <greturn *> (*gsi_last_bb (e->src)))
- {
- tree val = gimple_return_retval (ret);
- /* ??? Easy to handle simple indirections with some work.
- Arbitrary references like foo.bar.baz are more difficult
- (but conservatively easy enough with just looking at the base).
- Mind to fixup find_func_aliases as well. */
- if (!val || !SSA_VAR_P (val))
- continue;
- /* returns happen last in non-IPA so they only influence
- the ESCAPED solution and we can filter local variables. */
- varinfo_t escaped_vi = get_varinfo (find (escaped_id));
- varinfo_t vi = lookup_vi_for_tree (val);
- bitmap delta = BITMAP_ALLOC (&pta_obstack);
- bitmap_iterator bi;
- unsigned i;
- for (; vi; vi = vi_next (vi))
- {
- varinfo_t part_vi = get_varinfo (find (vi->id));
- EXECUTE_IF_AND_COMPL_IN_BITMAP (part_vi->solution,
- escaped_vi->solution, 0, i, bi)
- {
- varinfo_t pointed_to_vi = get_varinfo (i);
- if (pointed_to_vi->is_global_var
- /* We delay marking of heap memory as global. */
- || pointed_to_vi->is_heap_var)
- bitmap_set_bit (delta, i);
- }
- }
-
- /* Now compute the transitive closure. */
- bitmap_ior_into (escaped_vi->solution, delta);
- bitmap new_delta = BITMAP_ALLOC (&pta_obstack);
- while (!bitmap_empty_p (delta))
- {
- EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
- {
- varinfo_t pointed_to_vi = get_varinfo (i);
- pointed_to_vi = get_varinfo (find (pointed_to_vi->id));
- unsigned j;
- bitmap_iterator bi2;
- EXECUTE_IF_AND_COMPL_IN_BITMAP (pointed_to_vi->solution,
- escaped_vi->solution,
- 0, j, bi2)
- {
- varinfo_t pointed_to_vi2 = get_varinfo (j);
- if (pointed_to_vi2->is_global_var
- /* We delay marking of heap memory as global. */
- || pointed_to_vi2->is_heap_var)
- bitmap_set_bit (new_delta, j);
- }
- }
- bitmap_ior_into (escaped_vi->solution, new_delta);
- bitmap_clear (delta);
- std::swap (delta, new_delta);
- }
- BITMAP_FREE (delta);
- BITMAP_FREE (new_delta);
- }
-
if (dump_file && (dump_flags & TDF_STATS))
dump_sa_stats (dump_file);
@@ -7634,6 +7598,12 @@ compute_points_to_sets (void)
points-to solution queries. */
cfun->gimple_df->escaped.escaped = 0;
+ /* The ESCAPED_RETURN solution is what contains all memory that needs
+ to be considered global. */
+ cfun->gimple_df->escaped_return
+ = find_what_var_points_to (cfun->decl, get_varinfo (escaped_return_id));
+ cfun->gimple_df->escaped_return.escaped = 1;
+
/* Compute the points-to sets for pointer SSA_NAMEs. */
unsigned i;
tree ptr;
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 3858a63de20..9e6233fea2c 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1216,6 +1216,7 @@ init_tree_ssa (struct function *fn, int size)
fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
pt_solution_reset (&fn->gimple_df->escaped);
+ pt_solution_reset (&fn->gimple_df->escaped_return);
init_ssanames (fn, size);
}
@@ -1233,6 +1234,7 @@ delete_tree_ssa (struct function *fn)
fn->gimple_df->default_defs->empty ();
fn->gimple_df->default_defs = NULL;
pt_solution_reset (&fn->gimple_df->escaped);
+ pt_solution_reset (&fn->gimple_df->escaped_return);
if (fn->gimple_df->decls_to_pointers != NULL)
delete fn->gimple_df->decls_to_pointers;
fn->gimple_df->decls_to_pointers = NULL;
--
2.35.3
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-11-27 14:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-27 14:31 [PATCH] tree-optimization/112653 - PTA and return Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).