Add handle_param parameter to create_variable_info_for_1
2015-10-26 Tom de Vries <tom@codesourcery.com>
* tree-ssa-structalias.c (restrict_pointed_var): New static variable.
* (insert_restrict_pointed_var, lookup_restrict_pointed_var): New
function.
(create_variable_info_for_1): Add and handle handle_param parameter.
(create_variable_info_for): Call create_variable_info_for_1 with extra
arg.
(intra_create_variable_infos): Same. Handle case that
lookup_restrict_pointed_var (p) is not NULL.
---
gcc/tree-ssa-structalias.c | 73 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 63 insertions(+), 10 deletions(-)
@@ -5606,12 +5606,45 @@ check_for_overlaps (vec<fieldoff_s> fieldstack)
return false;
}
+/* Map from restrict pointer variable info to restrict var variable info. */
+
+static hash_map<varinfo_t, varinfo_t> *restrict_pointed_var = NULL;
+
+/* Insert VI2 as the restrict var for VI in the restrict_pointed_var map. */
+
+static void
+insert_restrict_pointed_var (varinfo_t vi, varinfo_t vi2)
+{
+ if (restrict_pointed_var == NULL)
+ restrict_pointed_var = new hash_map<varinfo_t, varinfo_t>;
+
+ bool mapped = restrict_pointed_var->put (vi, vi2);
+ gcc_assert (!mapped);
+}
+
+/* Find the restrict var for restrict pointer VI in the restrict_pointed_var
+ map. If VI does not exist in the map, return NULL, otherwise, return the
+ varinfo we found. */
+
+static varinfo_t
+lookup_restrict_pointed_var (varinfo_t vi)
+{
+ if (restrict_pointed_var == NULL)
+ return NULL;
+ varinfo_t *slot = restrict_pointed_var->get (vi);
+ if (slot == NULL)
+ return NULL;
+
+ return *slot;
+}
+
+
/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
This will also create any varinfo structures necessary for fields
- of DECL. */
+ of DECL. DECL is a function parameter if HANDLE_PARAM is set. */
static varinfo_t
-create_variable_info_for_1 (tree decl, const char *name)
+create_variable_info_for_1 (tree decl, const char *name, bool handle_param)
{
varinfo_t vi, newvi;
tree decl_type = TREE_TYPE (decl);
@@ -5687,6 +5720,17 @@ create_variable_info_for_1 (tree decl, const char *name)
if (POINTER_TYPE_P (TREE_TYPE (decl))
&& TYPE_RESTRICT (TREE_TYPE (decl)))
vi->only_restrict_pointers = 1;
+ if (vi->only_restrict_pointers
+ && handle_param)
+ {
+ varinfo_t rvi;
+ tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
+ DECL_EXTERNAL (heapvar) = 1;
+ rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", false);
+ rvi->is_restrict_var = 1;
+ insert_vi_for_tree (heapvar, rvi);
+ insert_restrict_pointed_var (vi, rvi);
+ }
fieldstack.release ();
return vi;
}
@@ -5738,7 +5782,7 @@ create_variable_info_for_1 (tree decl, const char *name)
static unsigned int
create_variable_info_for (tree decl, const char *name)
{
- varinfo_t vi = create_variable_info_for_1 (decl, name);
+ varinfo_t vi = create_variable_info_for_1 (decl, name, false);
unsigned int id = vi->id;
insert_vi_for_tree (decl, vi);
@@ -5880,7 +5924,8 @@ 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),
+ recursive_restrict_p);
insert_vi_for_tree (t, p);
}
@@ -5890,12 +5935,17 @@ intra_create_variable_infos (struct function *fn)
in the first/last subfield of the object. */
if (recursive_restrict_p)
{
- 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->is_restrict_var = 1;
- insert_vi_for_tree (heapvar, vi);
+ varinfo_t vi = lookup_restrict_pointed_var (p);
+ if (vi == NULL)
+ {
+ tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
+ DECL_EXTERNAL (heapvar) = 1;
+ vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", false);
+ vi->is_restrict_var = 1;
+ insert_vi_for_tree (heapvar, vi);
+ insert_restrict_pointed_var (p, vi);
+ p->only_restrict_pointers = 1;
+ }
make_constraint_from (p, vi->id);
make_restrict_var_constraints (vi);
continue;
@@ -5915,6 +5965,9 @@ intra_create_variable_infos (struct function *fn)
}
}
+ delete restrict_pointed_var;
+ restrict_pointed_var = NULL;
+
/* Add a constraint for a result decl that is passed by reference. */
if (DECL_RESULT (fn->decl)
&& DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
--
1.9.1