On 26/10/15 14:29, Richard Biener wrote:
On Mon, Oct 26, 2015 at 1:26 PM, Tom de Vries <tom_devr...@mentor.com> wrote:
Hi,
After spending some time looking at ealias/pta dumps, I realized that
they're hard to understand because we use varinfo names to identify
varinfos, while those names are not necessarily unique.
F.i., for a function f:
...
void
f (int *__restrict__ a, int *__restrict__ b)
{
*a = 1;
*b = 2;
}
...
we have at ealias the constraints:
...
a = &PARM_NOALIAS
PARM_NOALIAS = NONLOCAL
b = &PARM_NOALIAS
PARM_NOALIAS = NONLOCAL
derefaddrtmp = &NONLOCAL
*a = derefaddrtmp
derefaddrtmp = &NONLOCAL
*b = derefaddrtmp
...
F.i. PARM_NOALIAS occurs several times, and it's not clear if there are one
or two varinfos with that name.
Using attached patch, it's clearer what varinfos the constraints relate to:
...
a(8) = &PARM_NOALIAS(9)
PARM_NOALIAS(9) = NONLOCAL(5)
b(10) = &PARM_NOALIAS(11)
PARM_NOALIAS(11) = NONLOCAL(5)
derefaddrtmp(12) = &NONLOCAL(5)
*a(8) = derefaddrtmp(12)
derefaddrtmp(13) = &NONLOCAL(5)
*b(10) = derefaddrtmp(13)
...
It this a good idea, f.i. guarded by (dump_flags & TDF_DETAILS) not to
disturb scans of current tests?
Or, do we f.i. want to fix the names themselves to be unique?
I think so, on most cases the (n) adds clutter without extra info.
Attached patch implements that approach. We get:
a = &PARM_NOALIAS(9)
PARM_NOALIAS(9) = NONLOCAL
b = &PARM_NOALIAS(11)
PARM_NOALIAS(11) = NONLOCAL
derefaddrtmp(12) = &NONLOCAL
*a = derefaddrtmp(12)
derefaddrtmp(13) = &NONLOCAL
*b = derefaddrtmp(13)
OK for trunk if bootstrap and reg-test succeeds?
Thanks,
- Tom
Improve alias dump info
2015-10-28 Tom de Vries <t...@codesourcery.com>
* tree-ssa-structalias.c (new_var_info, make_heapvar)
(make_constraint_from_restrict, make_constraint_from_global_restrict)
(create_function_info_for, create_variable_info_for_1)
(create_variable_info_for): Add and handle add_id parameter.
(get_call_vi, new_scalar_tmp_constraint_exp, handle_rhs_call)
(init_base_vars): Add extra argument to calls to new_var_info.
(get_vi_for_tree): Add extra argument to call to
create_variable_info_for.
(process_constraint, do_deref, process_all_all_constraints): Add extra
argument to calls to new_scalar_tmp_constraint_exp.
(handle_lhs_call, find_func_aliases_for_builtin_call): Add extra
argument to calls to make_heapvar.
(make_restrict_var_constraints): Add extra argument to call to
make_constraint_from_global_restrict.
(intra_create_variable_infos): Add extra argument to call to
create_variable_info_for_1.
(ipa_pta_execute): Add extra argument to call to
create_function_info_for.
---
gcc/tree-ssa-structalias.c | 112 +++++++++++++++++++++++++--------------------
1 file changed, 62 insertions(+), 50 deletions(-)
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 5e070bc..07ec4a5 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -220,7 +220,7 @@ static bitmap_obstack oldpta_obstack;
/* Used for per-solver-iteration bitmaps. */
static bitmap_obstack iteration_obstack;
-static unsigned int create_variable_info_for (tree, const char *);
+static unsigned int create_variable_info_for (tree, const char *, bool);
typedef struct constraint_graph *constraint_graph_t;
static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
@@ -361,11 +361,18 @@ enum { nothing_id = 1, anything_id = 2, string_id = 3,
to the vector of variable info structures. */
static varinfo_t
-new_var_info (tree t, const char *name)
+new_var_info (tree t, const char *name, bool add_id)
{
unsigned index = varmap.length ();
varinfo_t ret = variable_info_pool.allocate ();
+ if (dump_file && add_id)
+ {
+ char *tempname = xasprintf ("%s(%d)", name, index);
+ name = ggc_strdup (tempname);
+ free (tempname);
+ }
+
ret->id = index;
ret->name = name;
ret->decl = t;
@@ -416,13 +423,13 @@ get_call_vi (gcall *call)
if (existed)
return *slot_p;
- vi = new_var_info (NULL_TREE, "CALLUSED");
+ vi = new_var_info (NULL_TREE, "CALLUSED", true);
vi->offset = 0;
vi->size = 1;
vi->fullsize = 2;
vi->is_full_var = true;
- vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED");
+ vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
vi2->offset = 1;
vi2->size = 1;
vi2->fullsize = 2;
@@ -2883,7 +2890,10 @@ get_vi_for_tree (tree t)
{
varinfo_t *slot = vi_for_tree->get (t);
if (slot == NULL)
- return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
+ {
+ unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
+ return get_varinfo (id);
+ }
return *slot;
}
@@ -2891,12 +2901,12 @@ get_vi_for_tree (tree t)
/* Get a scalar constraint expression for a new temporary variable. */
static struct constraint_expr
-new_scalar_tmp_constraint_exp (const char *name)
+new_scalar_tmp_constraint_exp (const char *name, bool add_id)
{
struct constraint_expr tmp;
varinfo_t vi;
- vi = new_var_info (NULL_TREE, name);
+ vi = new_var_info (NULL_TREE, name, add_id);
vi->offset = 0;
vi->size = -1;
vi->fullsize = -1;
@@ -3002,7 +3012,7 @@ process_constraint (constraint_t t)
{
/* Split into tmp = *rhs, *lhs = tmp */
struct constraint_expr tmplhs;
- tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp");
+ tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
process_constraint (new_constraint (tmplhs, rhs));
process_constraint (new_constraint (lhs, tmplhs));
}
@@ -3010,7 +3020,7 @@ process_constraint (constraint_t t)
{
/* Split into tmp = &rhs, *lhs = tmp */
struct constraint_expr tmplhs;
- tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp");
+ tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
process_constraint (new_constraint (tmplhs, rhs));
process_constraint (new_constraint (lhs, tmplhs));
}
@@ -3314,7 +3324,7 @@ do_deref (vec<ce_s> *constraints)
else if (c->type == DEREF)
{
struct constraint_expr tmplhs;
- tmplhs = new_scalar_tmp_constraint_exp ("dereftmp");
+ tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true);
process_constraint (new_constraint (tmplhs, *c));
c->var = tmplhs.var;
}
@@ -3572,7 +3582,7 @@ process_all_all_constraints (vec<ce_s> lhsc,
else
{
struct constraint_expr tmp;
- tmp = new_scalar_tmp_constraint_exp ("allalltmp");
+ tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
FOR_EACH_VEC_ELT (rhsc, i, rhsp)
process_constraint (new_constraint (tmp, *rhsp));
FOR_EACH_VEC_ELT (lhsc, i, lhsp)
@@ -3757,7 +3767,7 @@ build_fake_var_decl (tree type)
Return the created variable. */
static varinfo_t
-make_heapvar (const char *name)
+make_heapvar (const char *name, bool add_id)
{
varinfo_t vi;
tree heapvar;
@@ -3765,7 +3775,7 @@ make_heapvar (const char *name)
heapvar = build_fake_var_decl (ptr_type_node);
DECL_EXTERNAL (heapvar) = 1;
- vi = new_var_info (heapvar, name);
+ vi = new_var_info (heapvar, name, add_id);
vi->is_artificial_var = true;
vi->is_heap_var = true;
vi->is_unknown_size_var = true;
@@ -3783,9 +3793,9 @@ make_heapvar (const char *name)
for tracking restrict pointers. */
static varinfo_t
-make_constraint_from_restrict (varinfo_t lhs, const char *name)
+make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
{
- varinfo_t vi = make_heapvar (name);
+ varinfo_t vi = make_heapvar (name, add_id);
vi->is_restrict_var = 1;
vi->is_global_var = 1;
vi->may_have_pointers = 1;
@@ -3799,9 +3809,10 @@ make_constraint_from_restrict (varinfo_t lhs, const char *name)
point to global memory. */
static varinfo_t
-make_constraint_from_global_restrict (varinfo_t lhs, const char *name)
+make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
+ bool add_id)
{
- varinfo_t vi = make_constraint_from_restrict (lhs, name);
+ varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
make_copy_constraint (vi, nonlocal_id);
return vi;
}
@@ -3881,7 +3892,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
varinfo_t uses = get_call_use_vi (stmt);
if (!(flags & EAF_DIRECT))
{
- varinfo_t tem = new_var_info (NULL_TREE, "callarg");
+ varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
make_constraint_to (tem->id, arg);
make_transitive_closure_constraints (tem);
make_copy_constraint (uses, tem->id);
@@ -3895,7 +3906,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
struct constraint_expr lhs, rhs;
varinfo_t uses = get_call_use_vi (stmt);
varinfo_t clobbers = get_call_clobber_vi (stmt);
- varinfo_t tem = new_var_info (NULL_TREE, "callarg");
+ varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
make_constraint_to (tem->id, arg);
if (!(flags & EAF_DIRECT))
make_transitive_closure_constraints (tem);
@@ -3995,7 +4006,7 @@ handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> rhsc,
varinfo_t vi;
struct constraint_expr tmpc;
rhsc.create (0);
- vi = make_heapvar ("HEAP");
+ vi = make_heapvar ("HEAP", true);
/* We are marking allocated storage local, we deal with it becoming
global by escaping and setting of vars_contains_escaped_heap. */
DECL_EXTERNAL (vi->decl) = 0;
@@ -4246,7 +4257,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
tree ptrptr = gimple_call_arg (t, 0);
get_constraint_for (ptrptr, &lhsc);
do_deref (&lhsc);
- varinfo_t vi = make_heapvar ("HEAP");
+ varinfo_t vi = make_heapvar ("HEAP", true);
/* We are marking allocated storage local, we deal with it becoming
global by escaping and setting of vars_contains_escaped_heap. */
DECL_EXTERNAL (vi->decl) = 0;
@@ -5413,7 +5424,7 @@ count_num_arguments (tree decl, bool *is_varargs)
of the variable we've created for the function. */
static varinfo_t
-create_function_info_for (tree decl, const char *name)
+create_function_info_for (tree decl, const char *name, bool add_id)
{
struct function *fn = DECL_STRUCT_FUNCTION (decl);
varinfo_t vi, prev_vi;
@@ -5424,7 +5435,7 @@ create_function_info_for (tree decl, const char *name)
/* Create the variable info. */
- vi = new_var_info (decl, name);
+ vi = new_var_info (decl, name, add_id);
vi->offset = 0;
vi->size = 1;
vi->fullsize = fi_parm_base + num_args;
@@ -5447,7 +5458,7 @@ create_function_info_for (tree decl, const char *name)
newname = ggc_strdup (tempname);
free (tempname);
- clobbervi = new_var_info (NULL, newname);
+ clobbervi = new_var_info (NULL, newname, false);
clobbervi->offset = fi_clobbers;
clobbervi->size = 1;
clobbervi->fullsize = vi->fullsize;
@@ -5461,7 +5472,7 @@ create_function_info_for (tree decl, const char *name)
newname = ggc_strdup (tempname);
free (tempname);
- usevi = new_var_info (NULL, newname);
+ usevi = new_var_info (NULL, newname, false);
usevi->offset = fi_uses;
usevi->size = 1;
usevi->fullsize = vi->fullsize;
@@ -5483,7 +5494,7 @@ create_function_info_for (tree decl, const char *name)
newname = ggc_strdup (tempname);
free (tempname);
- chainvi = new_var_info (fn->static_chain_decl, newname);
+ chainvi = new_var_info (fn->static_chain_decl, newname, false);
chainvi->offset = fi_static_chain;
chainvi->size = 1;
chainvi->fullsize = vi->fullsize;
@@ -5511,7 +5522,7 @@ create_function_info_for (tree decl, const char *name)
newname = ggc_strdup (tempname);
free (tempname);
- resultvi = new_var_info (resultdecl, newname);
+ resultvi = new_var_info (resultdecl, newname, false);
resultvi->offset = fi_result;
resultvi->size = 1;
resultvi->fullsize = vi->fullsize;
@@ -5541,7 +5552,7 @@ create_function_info_for (tree decl, const char *name)
newname = ggc_strdup (tempname);
free (tempname);
- argvi = new_var_info (argdecl, newname);
+ argvi = new_var_info (argdecl, newname, false);
argvi->offset = fi_parm_base + i;
argvi->size = 1;
argvi->is_full_var = true;
@@ -5573,7 +5584,7 @@ create_function_info_for (tree decl, const char *name)
/* We need sth that can be pointed to for va_start. */
decl = build_fake_var_decl (ptr_type_node);
- argvi = new_var_info (decl, newname);
+ argvi = new_var_info (decl, newname, false);
argvi->offset = fi_parm_base + num_args;
argvi->size = ~0;
argvi->is_full_var = true;
@@ -5612,7 +5623,7 @@ check_for_overlaps (vec<fieldoff_s> fieldstack)
of DECL. */
static varinfo_t
-create_variable_info_for_1 (tree decl, const char *name)
+create_variable_info_for_1 (tree decl, const char *name, bool add_id)
{
varinfo_t vi, newvi;
tree decl_type = TREE_TYPE (decl);
@@ -5624,7 +5635,7 @@ create_variable_info_for_1 (tree decl, const char *name)
if (!declsize
|| !tree_fits_uhwi_p (declsize))
{
- vi = new_var_info (decl, name);
+ vi = new_var_info (decl, name, add_id);
vi->offset = 0;
vi->size = ~0;
vi->fullsize = ~0;
@@ -5679,7 +5690,7 @@ create_variable_info_for_1 (tree decl, const char *name)
if (fieldstack.length () == 0
|| fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
{
- vi = new_var_info (decl, name);
+ vi = new_var_info (decl, name, add_id);
vi->offset = 0;
vi->may_have_pointers = true;
vi->fullsize = tree_to_uhwi (declsize);
@@ -5692,7 +5703,7 @@ create_variable_info_for_1 (tree decl, const char *name)
return vi;
}
- vi = new_var_info (decl, name);
+ vi = new_var_info (decl, name, add_id);
vi->fullsize = tree_to_uhwi (declsize);
if (fieldstack.length () == 1)
vi->is_full_var = true;
@@ -5727,7 +5738,7 @@ create_variable_info_for_1 (tree decl, const char *name)
newvi->only_restrict_pointers = fo->only_restrict_pointers;
if (i + 1 < fieldstack.length ())
{
- varinfo_t tem = new_var_info (decl, name);
+ varinfo_t tem = new_var_info (decl, name, false);
newvi->next = tem->id;
tem->head = vi->id;
}
@@ -5737,9 +5748,9 @@ create_variable_info_for_1 (tree decl, const char *name)
}
static unsigned int
-create_variable_info_for (tree decl, const char *name)
+create_variable_info_for (tree decl, const char *name, bool add_id)
{
- varinfo_t vi = create_variable_info_for_1 (decl, name);
+ varinfo_t vi = create_variable_info_for_1 (decl, name, add_id);
unsigned int id = vi->id;
insert_vi_for_tree (decl, vi);
@@ -5760,7 +5771,8 @@ create_variable_info_for (tree decl, const char *name)
|| vi->only_restrict_pointers)
{
varinfo_t rvi
- = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
+ = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
+ true);
/* ??? For now exclude reads from globals as restrict sources
if those are not (indirectly) from incoming parameters. */
rvi->is_restrict_var = false;
@@ -5854,7 +5866,7 @@ make_restrict_var_constraints (varinfo_t vi)
if (vi->may_have_pointers)
{
if (vi->only_restrict_pointers)
- make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
+ make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT", true);
else
make_copy_constraint (vi, nonlocal_id);
}
@@ -5881,7 +5893,7 @@ intra_create_variable_infos (struct function *fn)
varinfo_t p = lookup_vi_for_tree (t);
if (p == NULL)
{
- p = create_variable_info_for_1 (t, alias_get_name (t));
+ p = create_variable_info_for_1 (t, alias_get_name (t), false);
insert_vi_for_tree (t, p);
}
@@ -5894,7 +5906,7 @@ intra_create_variable_infos (struct function *fn)
varinfo_t vi;
tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
DECL_EXTERNAL (heapvar) = 1;
- vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS");
+ vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true);
vi->is_restrict_var = 1;
insert_vi_for_tree (heapvar, vi);
make_constraint_from (p, vi->id);
@@ -5903,13 +5915,13 @@ intra_create_variable_infos (struct function *fn)
}
if (restrict_pointer_p)
- make_constraint_from_global_restrict (p, "PARM_RESTRICT");
+ make_constraint_from_global_restrict (p, "PARM_RESTRICT", true);
else
{
for (; p; p = vi_next (p))
{
if (p->only_restrict_pointers)
- make_constraint_from_global_restrict (p, "PARM_RESTRICT");
+ make_constraint_from_global_restrict (p, "PARM_RESTRICT", true);
else if (p->may_have_pointers)
make_constraint_from (p, nonlocal_id);
}
@@ -6511,7 +6523,7 @@ init_base_vars (void)
/* Create the NULL variable, used to represent that a variable points
to NULL. */
- var_nothing = new_var_info (NULL_TREE, "NULL");
+ var_nothing = new_var_info (NULL_TREE, "NULL", false);
gcc_assert (var_nothing->id == nothing_id);
var_nothing->is_artificial_var = 1;
var_nothing->offset = 0;
@@ -6523,7 +6535,7 @@ init_base_vars (void)
/* Create the ANYTHING variable, used to represent that a variable
points to some unknown piece of memory. */
- var_anything = new_var_info (NULL_TREE, "ANYTHING");
+ var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
gcc_assert (var_anything->id == anything_id);
var_anything->is_artificial_var = 1;
var_anything->size = ~0;
@@ -6549,7 +6561,7 @@ init_base_vars (void)
/* Create the STRING variable, used to represent that a variable
points to a string literal. String literals don't contain
pointers so STRING doesn't point to anything. */
- var_string = new_var_info (NULL_TREE, "STRING");
+ var_string = new_var_info (NULL_TREE, "STRING", false);
gcc_assert (var_string->id == string_id);
var_string->is_artificial_var = 1;
var_string->offset = 0;
@@ -6560,7 +6572,7 @@ init_base_vars (void)
/* Create the ESCAPED variable, used to represent the set of escaped
memory. */
- var_escaped = new_var_info (NULL_TREE, "ESCAPED");
+ var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
gcc_assert (var_escaped->id == escaped_id);
var_escaped->is_artificial_var = 1;
var_escaped->offset = 0;
@@ -6570,7 +6582,7 @@ init_base_vars (void)
/* Create the NONLOCAL variable, used to represent the set of nonlocal
memory. */
- var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL");
+ var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
gcc_assert (var_nonlocal->id == nonlocal_id);
var_nonlocal->is_artificial_var = 1;
var_nonlocal->offset = 0;
@@ -6624,7 +6636,7 @@ init_base_vars (void)
/* Create the STOREDANYTHING variable, used to represent the set of
variables stored to *ANYTHING. */
- var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING");
+ var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
gcc_assert (var_storedanything->id == storedanything_id);
var_storedanything->is_artificial_var = 1;
var_storedanything->offset = 0;
@@ -6634,7 +6646,7 @@ init_base_vars (void)
/* Create the INTEGER variable, used to represent that a variable points
to what an INTEGER "points to". */
- var_integer = new_var_info (NULL_TREE, "INTEGER");
+ var_integer = new_var_info (NULL_TREE, "INTEGER", false);
gcc_assert (var_integer->id == integer_id);
var_integer->is_artificial_var = 1;
var_integer->size = ~0;
@@ -7300,7 +7312,7 @@ ipa_pta_execute (void)
gcc_assert (!node->clone_of);
vi = create_function_info_for (node->decl,
- alias_get_name (node->decl));
+ alias_get_name (node->decl), false);
node->call_for_symbol_thunks_and_aliases
(associate_varinfo_to_alias, vi, true);
}
--
1.9.1