aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-10-27 15:52:44 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-10-27 15:52:44 +0000
commit5c245b956cc455159f9448456eb12b1b7e5b1a88 (patch)
tree3729f0a69b1c096c71531c62d5e4692f6ba33de8
parent06302a02c05eeaeea9e8597dfc6ed3d0e0085357 (diff)
downloadgcc-5c245b956cc455159f9448456eb12b1b7e5b1a88.zip
gcc-5c245b956cc455159f9448456eb12b1b7e5b1a88.tar.gz
gcc-5c245b956cc455159f9448456eb12b1b7e5b1a88.tar.bz2
tree-ssa-structalias.c (find_func_aliases): In IPA mode handle calls to externally visible functions like in regular mode.
2009-10-27 Richard Guenther <rguenther@suse.de> * tree-ssa-structalias.c (find_func_aliases): In IPA mode handle calls to externally visible functions like in regular mode. (create_variable_info_for): Do not create function infos here. (have_alias_info): Remove write-only variable. (solve_constraints): New function split out from common code in compute_points_to_sets and ipa_pta_execute. (compute_points_to_sets): Adjust. (ipa_pta_execute): Likewise. Handle clones and externally visible functions like in non-IPA mode. * gcc.dg/torture/ipa-pta-1.c: Adjust testcase. From-SVN: r153600
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/torture/ipa-pta-1.c26
-rw-r--r--gcc/tree-ssa-structalias.c221
4 files changed, 141 insertions, 122 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d8518c0..89051c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2009-10-27 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (find_func_aliases): In IPA mode
+ handle calls to externally visible functions like in regular mode.
+ (create_variable_info_for): Do not create function infos here.
+ (have_alias_info): Remove write-only variable.
+ (solve_constraints): New function split out from common code
+ in compute_points_to_sets and ipa_pta_execute.
+ (compute_points_to_sets): Adjust.
+ (ipa_pta_execute): Likewise. Handle clones and externally visible
+ functions like in non-IPA mode.
+
2009-10-27 Jakub Jelinek <jakub@redhat.com>
PR c/41842
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1ded942..54abf12 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-10-27 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/torture/ipa-pta-1.c: Adjust testcase.
+
2009-10-27 Jakub Jelinek <jakub@redhat.com>
PR c/41842
diff --git a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
index 1096397..7df130a 100644
--- a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
+++ b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
@@ -4,31 +4,37 @@
struct X { char x; char y; };
-void bar (char *p);
+char *q;
-void test1 (char a, char b, char c, char d, char e, char f, char g, char h)
+static void __attribute__((noinline))
+bar (char *p)
{
- char *p = &a;
+ q = p;
+}
+
+void test1 (char a1, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a1;
p++;
bar (p);
}
-void test2 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+void test2 (struct X a2, char b, char c, char d, char e, char f, char g, char h)
{
- char *p = &a.x;
+ char *p = &a2.x;
p++;
bar (p);
}
-void test3 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+void test3 (struct X a3, char b, char c, char d, char e, char f, char g, char h)
{
- char *p = &a.y;
+ char *p = &a3.y;
bar (p);
}
-void test4 (int a, char b, char c, char d, char e, char f, char g, char h)
+void test4 (int a4, char b, char c, char d, char e, char f, char g, char h)
{
- char *p = (char *)&a;
+ char *p = (char *)&a4;
p++;
p++;
p++;
@@ -36,5 +42,5 @@ void test4 (int a, char b, char c, char d, char e, char f, char g, char h)
bar (p);
}
-/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta" } } */
+/* { dg-final { scan-ipa-dump "bar.arg0 = { a4 a3 a2 a1 }" "pta" } } */
/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index cc655df..7b33936 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -3663,8 +3663,8 @@ find_func_aliases (gimple origt)
pointer passed by address. */
else if (is_gimple_call (t))
{
- tree fndecl;
- if ((fndecl = gimple_call_fndecl (t)) != NULL_TREE
+ tree fndecl = gimple_call_fndecl (t);
+ if (fndecl != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
/* ??? All builtins that are handled here need to be handled
in the alias-oracle query functions explicitly! */
@@ -3774,7 +3774,9 @@ find_func_aliases (gimple origt)
default:
/* Fallthru to general call handling. */;
}
- if (!in_ipa_mode)
+ if (!in_ipa_mode
+ || (fndecl
+ && !lookup_vi_for_tree (fndecl)))
{
VEC(ce_s, heap) *rhsc = NULL;
int flags = gimple_call_flags (t);
@@ -4425,9 +4427,6 @@ create_variable_info_for (tree decl, const char *name)
tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
VEC (fieldoff_s,heap) *fieldstack = NULL;
- if (TREE_CODE (decl) == FUNCTION_DECL && in_ipa_mode)
- return create_function_info_for (decl, name);
-
if (var_can_have_subvars (decl) && use_field_sensitive)
push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
@@ -4773,8 +4772,6 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
}
-static bool have_alias_info = false;
-
/* Compute the points-to solution *PT for the variable VI. */
static void
@@ -5399,44 +5396,12 @@ delete_alias_heapvars (void)
heapvar_for_stmt = NULL;
}
-/* Create points-to sets for the current function. See the comments
- at the start of the file for an algorithmic overview. */
+/* Solve the constraint set. */
static void
-compute_points_to_sets (void)
+solve_constraints (void)
{
struct scc_info *si;
- basic_block bb;
- unsigned i;
- varinfo_t vi;
-
- timevar_push (TV_TREE_PTA);
-
- init_alias_vars ();
- init_alias_heapvars ();
-
- intra_create_variable_infos ();
-
- /* Now walk all statements and derive aliases. */
- FOR_EACH_BB (bb)
- {
- gimple_stmt_iterator gsi;
-
- for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple phi = gsi_stmt (gsi);
-
- if (is_gimple_reg (gimple_phi_result (phi)))
- find_func_aliases (phi);
- }
-
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple stmt = gsi_stmt (gsi);
-
- find_func_aliases (stmt);
- }
- }
if (dump_file)
{
@@ -5493,6 +5458,48 @@ compute_points_to_sets (void)
if (dump_file)
dump_sa_points_to_info (dump_file);
+}
+
+/* Create points-to sets for the current function. See the comments
+ at the start of the file for an algorithmic overview. */
+
+static void
+compute_points_to_sets (void)
+{
+ basic_block bb;
+ unsigned i;
+ varinfo_t vi;
+
+ timevar_push (TV_TREE_PTA);
+
+ init_alias_vars ();
+ init_alias_heapvars ();
+
+ intra_create_variable_infos ();
+
+ /* Now walk all statements and derive aliases. */
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+
+ if (is_gimple_reg (gimple_phi_result (phi)))
+ find_func_aliases (phi);
+ }
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ find_func_aliases (stmt);
+ }
+ }
+
+ /* From the constraints compute the points-to sets. */
+ solve_constraints ();
/* Compute the points-to sets for ESCAPED and CALLUSED used for
call-clobber analysis. */
@@ -5524,8 +5531,6 @@ compute_points_to_sets (void)
}
timevar_pop (TV_TREE_PTA);
-
- have_alias_info = true;
}
@@ -5559,7 +5564,6 @@ delete_points_to_sets (void)
VEC_free (varinfo_t, heap, varmap);
free_alloc_pool (variable_info_pool);
free_alloc_pool (constraint_pool);
- have_alias_info = false;
}
@@ -5658,101 +5662,94 @@ static unsigned int
ipa_pta_execute (void)
{
struct cgraph_node *node;
- struct scc_info *si;
in_ipa_mode = 1;
+
init_alias_heapvars ();
init_alias_vars ();
+ /* Build the constraints. */
for (node = cgraph_nodes; node; node = node->next)
{
unsigned int varid;
+ /* Nodes without a body are not interesting. Especially do not
+ visit clones at this point for now - we get duplicate decls
+ there for inline clones at least. */
+ if (!gimple_has_body_p (node->decl)
+ || node->clone_of)
+ continue;
+
+ /* It does not make sense to have graph edges into or out of
+ externally visible functions. There is no extra information
+ we can gather from them. */
+ if (node->local.externally_visible)
+ continue;
+
varid = create_function_info_for (node->decl,
cgraph_node_name (node));
- if (node->local.externally_visible)
- {
- varinfo_t fi = get_varinfo (varid);
- for (; fi; fi = fi->next)
- make_constraint_from (fi, anything_id);
- }
}
+
for (node = cgraph_nodes; node; node = node->next)
{
- if (node->analyzed)
- {
- struct function *func = DECL_STRUCT_FUNCTION (node->decl);
- basic_block bb;
- tree old_func_decl = current_function_decl;
- if (dump_file)
- fprintf (dump_file,
- "Generating constraints for %s\n",
- cgraph_node_name (node));
- push_cfun (func);
- current_function_decl = node->decl;
+ struct function *func;
+ basic_block bb;
+ tree old_func_decl;
- FOR_EACH_BB_FN (bb, func)
- {
- gimple_stmt_iterator gsi;
+ /* Nodes without a body are not interesting. */
+ if (!gimple_has_body_p (node->decl)
+ || node->clone_of)
+ continue;
- for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
- gsi_next (&gsi))
- {
- gimple phi = gsi_stmt (gsi);
+ if (dump_file)
+ fprintf (dump_file,
+ "Generating constraints for %s\n",
+ cgraph_node_name (node));
- if (is_gimple_reg (gimple_phi_result (phi)))
- find_func_aliases (phi);
- }
+ func = DECL_STRUCT_FUNCTION (node->decl);
+ old_func_decl = current_function_decl;
+ push_cfun (func);
+ current_function_decl = node->decl;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- find_func_aliases (gsi_stmt (gsi));
- }
- current_function_decl = old_func_decl;
- pop_cfun ();
- }
- else
- {
- /* Make point to anything. */
- }
- }
+ /* For externally visible functions use local constraints for
+ their arguments. For local functions we see all callers
+ and thus do not need initial constraints for parameters. */
+ if (node->local.externally_visible)
+ intra_create_variable_infos ();
- if (dump_file)
- {
- fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
- dump_constraints (dump_file);
- }
+ /* Build constriants for the function body. */
+ FOR_EACH_BB_FN (bb, func)
+ {
+ gimple_stmt_iterator gsi;
- if (dump_file)
- fprintf (dump_file,
- "\nCollapsing static cycles and doing variable "
- "substitution:\n");
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
- init_graph (VEC_length (varinfo_t, varmap) * 2);
- build_pred_graph ();
- si = perform_var_substitution (graph);
- rewrite_constraints (graph, si);
+ if (is_gimple_reg (gimple_phi_result (phi)))
+ find_func_aliases (phi);
+ }
- build_succ_graph ();
- free_var_substitution_info (si);
- move_complex_constraints (graph);
- unite_pointer_equivalences (graph);
- find_indirect_cycles (graph);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
- /* Implicit nodes and predecessors are no longer necessary at this
- point. */
- remove_preds_and_fake_succs (graph);
+ find_func_aliases (stmt);
+ }
+ }
- if (dump_file)
- fprintf (dump_file, "\nSolving graph\n");
+ current_function_decl = old_func_decl;
+ pop_cfun ();
+ }
- solve_graph (graph);
+ /* From the constraints compute the points-to sets. */
+ solve_constraints ();
- if (dump_file)
- dump_sa_points_to_info (dump_file);
+ delete_points_to_sets ();
in_ipa_mode = 0;
- delete_alias_heapvars ();
- delete_points_to_sets ();
+
return 0;
}