2015-10-31 Tom de Vries <tom@codesourcery.com>
backport from trunk:
2015-10-31 Tom de Vries <tom@codesourcery.com>
* tree-ssa-structalias.c (intra_create_variable_infos): Don't expect
existing varinfo for arguments.
* tree-ssa-structalias.c (ipa_pta_execute): Add extra arg to call to
create_function_info_for. Dump constraints generated during
create_function_info_for. Move intra_create_variable_infos call and
function-return-values-escape bit to ...
(create_function_info_for): ... here, and merge
intra_create_variable_infos call with argument loop. Add and handle
nonlocal_p parameter.
* tree-ssa-structalias.c (create_function_info_for): Make sure prev_vi
updating is alap, and seperated from preceding code. Make sure
insert_vi_for_tree is seperated from surrounding code.
* tree-ssa-structalias.c (ipa_pta_execute): Use make_copy_constraint.
---
gcc/tree-ssa-structalias.c | 121 +++++++++++++++++++++++++++------------------
1 file changed, 72 insertions(+), 49 deletions(-)
@@ -5422,10 +5422,12 @@ count_num_arguments (tree decl, bool *is_varargs)
}
/* Creation function node for DECL, using NAME, and return the index
- of the variable we've created for the function. */
+ of the variable we've created for the function. If NONLOCAL_p, create
+ initial constraints. */
static varinfo_t
-create_function_info_for (tree decl, const char *name, bool add_id)
+create_function_info_for (tree decl, const char *name, bool add_id,
+ bool nonlocal_p)
{
struct function *fn = DECL_STRUCT_FUNCTION (decl);
varinfo_t vi, prev_vi;
@@ -5465,6 +5467,7 @@ create_function_info_for (tree decl, const char *name, bool add_id)
clobbervi->fullsize = vi->fullsize;
clobbervi->is_full_var = true;
clobbervi->is_global_var = false;
+
gcc_assert (prev_vi->offset < clobbervi->offset);
prev_vi->next = clobbervi->id;
prev_vi = clobbervi;
@@ -5479,6 +5482,7 @@ create_function_info_for (tree decl, const char *name, bool add_id)
usevi->fullsize = vi->fullsize;
usevi->is_full_var = true;
usevi->is_global_var = false;
+
gcc_assert (prev_vi->offset < usevi->offset);
prev_vi->next = usevi->id;
prev_vi = usevi;
@@ -5501,10 +5505,16 @@ create_function_info_for (tree decl, const char *name, bool add_id)
chainvi->fullsize = vi->fullsize;
chainvi->is_full_var = true;
chainvi->is_global_var = false;
+
+ insert_vi_for_tree (fn->static_chain_decl, chainvi);
+
+ if (nonlocal_p
+ && chainvi->may_have_pointers)
+ make_constraint_from (chainvi, nonlocal_id);
+
gcc_assert (prev_vi->offset < chainvi->offset);
prev_vi->next = chainvi->id;
prev_vi = chainvi;
- insert_vi_for_tree (fn->static_chain_decl, chainvi);
}
/* Create a variable for the return var. */
@@ -5530,11 +5540,25 @@ create_function_info_for (tree decl, const char *name, bool add_id)
resultvi->is_full_var = true;
if (DECL_RESULT (decl))
resultvi->may_have_pointers = true;
+
+ if (DECL_RESULT (decl))
+ insert_vi_for_tree (DECL_RESULT (decl), resultvi);
+
gcc_assert (prev_vi->offset < resultvi->offset);
prev_vi->next = resultvi->id;
prev_vi = resultvi;
- if (DECL_RESULT (decl))
- insert_vi_for_tree (DECL_RESULT (decl), resultvi);
+ }
+
+ /* We also need to make function return values escape. Nothing
+ escapes by returning from main though. */
+ if (nonlocal_p
+ && !MAIN_NAME_P (DECL_NAME (decl)))
+ {
+ varinfo_t fi, rvi;
+ fi = lookup_vi_for_tree (decl);
+ rvi = first_vi_for_offset (fi, fi_result);
+ if (rvi && rvi->offset == fi_result)
+ make_copy_constraint (get_varinfo (escaped_id), rvi->id);
}
/* Set up variables for each argument. */
@@ -5560,14 +5584,19 @@ create_function_info_for (tree decl, const char *name, bool add_id)
argvi->fullsize = vi->fullsize;
if (arg)
argvi->may_have_pointers = true;
+
+ if (arg)
+ insert_vi_for_tree (arg, argvi);
+
+ if (nonlocal_p
+ && argvi->may_have_pointers)
+ make_constraint_from (argvi, nonlocal_id);
+
gcc_assert (prev_vi->offset < argvi->offset);
prev_vi->next = argvi->id;
prev_vi = argvi;
if (arg)
- {
- insert_vi_for_tree (arg, argvi);
- arg = DECL_CHAIN (arg);
- }
+ arg = DECL_CHAIN (arg);
}
/* Add one representative for all further args. */
@@ -5591,6 +5620,11 @@ create_function_info_for (tree decl, const char *name, bool add_id)
argvi->is_full_var = true;
argvi->is_heap_var = true;
argvi->fullsize = vi->fullsize;
+
+ if (nonlocal_p
+ && argvi->may_have_pointers)
+ make_constraint_from (argvi, nonlocal_id);
+
gcc_assert (prev_vi->offset < argvi->offset);
prev_vi->next = argvi->id;
prev_vi = argvi;
@@ -5891,12 +5925,8 @@ intra_create_variable_infos (struct function *fn)
bool recursive_restrict_p
= (restrict_pointer_p
&& !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t))));
- varinfo_t p = lookup_vi_for_tree (t);
- if (p == NULL)
- {
- p = create_variable_info_for_1 (t, alias_get_name (t), false);
- insert_vi_for_tree (t, p);
- }
+ varinfo_t p = create_variable_info_for_1 (t, alias_get_name (t), false);
+ insert_vi_for_tree (t, p);
/* For restrict qualified pointers build a representative for
the pointed-to object. Note that this ends up handling
@@ -7317,8 +7347,34 @@ ipa_pta_execute (void)
gcc_assert (!node->clone_of);
+ /* For externally visible or attribute used annotated functions use
+ local constraints for their arguments.
+ For local functions we see all callers and thus do not need initial
+ constraints for parameters. */
+ bool nonlocal_p = (node->used_from_other_partition
+ || node->externally_visible
+ || node->force_output
+ || node->address_taken);
+
vi = create_function_info_for (node->decl,
- alias_get_name (node->decl), false);
+ alias_get_name (node->decl), false,
+ nonlocal_p);
+ if (dump_file
+ && from != constraints.length ())
+ {
+ fprintf (dump_file,
+ "Generating intial constraints for %s", node->name ());
+ if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
+ fprintf (dump_file, " (%s)",
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (node->decl)));
+ fprintf (dump_file, "\n\n");
+ dump_constraints (dump_file, from);
+ fprintf (dump_file, "\n");
+
+ from = constraints.length ();
+ }
+
node->call_for_symbol_thunks_and_aliases
(associate_varinfo_to_alias, vi, true);
}
@@ -7365,39 +7421,6 @@ ipa_pta_execute (void)
func = DECL_STRUCT_FUNCTION (node->decl);
gcc_assert (cfun == NULL);
- /* For externally visible or attribute used annotated 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->used_from_other_partition
- || node->externally_visible
- || node->force_output
- || node->address_taken)
- {
- intra_create_variable_infos (func);
-
- /* We also need to make function return values escape. Nothing
- escapes by returning from main though. */
- if (!MAIN_NAME_P (DECL_NAME (node->decl)))
- {
- varinfo_t fi, rvi;
- fi = lookup_vi_for_tree (node->decl);
- rvi = first_vi_for_offset (fi, fi_result);
- if (rvi && rvi->offset == fi_result)
- {
- struct constraint_expr includes;
- struct constraint_expr var;
- includes.var = escaped_id;
- includes.offset = 0;
- includes.type = SCALAR;
- var.var = rvi->id;
- var.offset = 0;
- var.type = SCALAR;
- process_constraint (new_constraint (includes, var));
- }
- }
- }
-
/* Build constriants for the function body. */
FOR_EACH_BB_FN (bb, func)
{
--
1.9.1