Hi,
What do you think, Richi? Ok to push? I wanted to split out this smaller
portion before moving onto splitting out the constraint building. After that,
I think I'll be done with splitting.
I'm running bootstrap and regtest on x86_64 linux to make sure I didn't break
something.
Cheers,
Filip Kastl
-- 8< --
This patch continues my effort to split tree-ssa-structalias.cc into
smaller parts. The patch splits out the part that handles restrict
pointers. That is a small part (only ~300 lines of code).
gcc/ChangeLog:
* Makefile.in: Add gimple-ssa-pta-restrict.o.
* tree-ssa-structalias.cc (create_variable_info_for): Move the
forward declaration around.
(alias_get_name): Move the forward declaration around.
(type_can_have_subvars): Move the forward declaration around.
(make_param_constraints): Move the forward declaration around.
(insert_vi_for_tree): Give external linkage.
(lookup_vi_for_tree): Give external linkage.
(get_vi_for_tree): Give external linkage.
(struct vls_data): Move into gimple-ssa-pta-restrict.cc.
(visit_loadstore): Move into gimple-ssa-pta-restrict.cc.
(struct msdi_data): Move into gimple-ssa-pta-restrict.cc.
(maybe_set_dependence_info): Move into
gimple-ssa-pta-restrict.cc.
(clear_dependence_clique): Move into gimple-ssa-pta-restrict.cc.
(compute_dependence_clique): Move into
gimple-ssa-pta-restrict.cc.
* tree-ssa-structalias.h (insert_vi_for_tree): Declare in the
header.
(lookup_vi_for_tree): Declare in the header.
(get_vi_for_tree): Declare in the header.
* gimple-ssa-pta-restrict.cc: New file.
* gimple-ssa-pta-restrict.h: New file.
Signed-off-by: Filip Kastl <[email protected]>
---
gcc/Makefile.in | 1 +
gcc/gimple-ssa-pta-restrict.cc | 296 +++++++++++++++++++++++++++
gcc/gimple-ssa-pta-restrict.h | 30 +++
gcc/tree-ssa-structalias.cc | 357 +++++----------------------------
gcc/tree-ssa-structalias.h | 5 +
5 files changed, 383 insertions(+), 306 deletions(-)
create mode 100644 gcc/gimple-ssa-pta-restrict.cc
create mode 100644 gcc/gimple-ssa-pta-restrict.h
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7314a3b4225..5456f94e2ba 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1796,6 +1796,7 @@ OBJS = \
tree-ssa-strlen.o \
tree-ssa-structalias.o \
pta-andersen.o \
+ gimple-ssa-pta-restrict.o \
tree-ssa-tail-merge.o \
tree-ssa-ter.o \
tree-ssa-threadbackward.o \
diff --git a/gcc/gimple-ssa-pta-restrict.cc b/gcc/gimple-ssa-pta-restrict.cc
new file mode 100644
index 00000000000..73d5e72fe77
--- /dev/null
+++ b/gcc/gimple-ssa-pta-restrict.cc
@@ -0,0 +1,296 @@
+/* Tree based points-to analysis - restrict keyword logic
+ Copyright (C) 2005-2025 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <[email protected]>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "ssa.h"
+#include "tree-pretty-print.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+
+#include "tree-ssa-structalias.h"
+
+using namespace pointer_analysis;
+
+struct vls_data
+{
+ unsigned short clique;
+ bool escaped_p;
+ bitmap rvars;
+};
+
+/* Mark "other" loads and stores as belonging to CLIQUE and with
+ base zero. */
+
+static bool
+visit_loadstore (gimple *, tree base, tree ref, void *data)
+{
+ unsigned short clique = ((vls_data *) data)->clique;
+ bitmap rvars = ((vls_data *) data)->rvars;
+ bool escaped_p = ((vls_data *) data)->escaped_p;
+ if (TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ {
+ tree ptr = TREE_OPERAND (base, 0);
+ if (TREE_CODE (ptr) == SSA_NAME)
+ {
+ /* For parameters, get at the points-to set for the actual parm
+ decl. */
+ if (SSA_NAME_IS_DEFAULT_DEF (ptr)
+ && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
+ || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
+ ptr = SSA_NAME_VAR (ptr);
+
+ /* We need to make sure 'ptr' doesn't include any of
+ the restrict tags we added bases for in its points-to set. */
+ varinfo_t vi = lookup_vi_for_tree (ptr);
+ if (! vi)
+ return false;
+
+ vi = get_varinfo (var_rep[vi->id]);
+ if (bitmap_intersect_p (rvars, vi->solution)
+ || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
+ return false;
+ }
+
+ /* Do not overwrite existing cliques (that includes clique, base
+ pairs we just set). */
+ if (MR_DEPENDENCE_CLIQUE (base) == 0)
+ {
+ MR_DEPENDENCE_CLIQUE (base) = clique;
+ MR_DEPENDENCE_BASE (base) = 0;
+ }
+ }
+
+ /* For plain decl accesses see whether they are accesses to globals
+ and rewrite them to MEM_REFs with { clique, 0 }. */
+ if (VAR_P (base)
+ && is_global_var (base)
+ /* ??? We can't rewrite a plain decl with the walk_stmt_load_store
+ ops callback. */
+ && base != ref)
+ {
+ tree *basep = &ref;
+ while (handled_component_p (*basep))
+ basep = &TREE_OPERAND (*basep, 0);
+ gcc_assert (VAR_P (*basep));
+ tree ptr = build_fold_addr_expr (*basep);
+ tree zero = build_int_cst (TREE_TYPE (ptr), 0);
+ *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
+ MR_DEPENDENCE_CLIQUE (*basep) = clique;
+ MR_DEPENDENCE_BASE (*basep) = 0;
+ }
+
+ return false;
+}
+
+struct msdi_data {
+ tree ptr;
+ unsigned short *clique;
+ unsigned short *last_ruid;
+ varinfo_t restrict_var;
+};
+
+/* If BASE is a MEM_REF then assign a clique, base pair to it, updating
+ CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA.
+ Return whether dependence info was assigned to BASE. */
+
+static bool
+maybe_set_dependence_info (gimple *, tree base, tree, void *data)
+{
+ tree ptr = ((msdi_data *)data)->ptr;
+ unsigned short &clique = *((msdi_data *)data)->clique;
+ unsigned short &last_ruid = *((msdi_data *)data)->last_ruid;
+ varinfo_t restrict_var = ((msdi_data *)data)->restrict_var;
+ if ((TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ && TREE_OPERAND (base, 0) == ptr)
+ {
+ /* Do not overwrite existing cliques. This avoids overwriting dependence
+ info inlined from a function with restrict parameters inlined
+ into a function with restrict parameters. This usually means we
+ prefer to be precise in innermost loops. */
+ if (MR_DEPENDENCE_CLIQUE (base) == 0)
+ {
+ if (clique == 0)
+ {
+ if (cfun->last_clique == 0)
+ cfun->last_clique = 1;
+ clique = 1;
+ }
+ if (restrict_var->ruid == 0)
+ restrict_var->ruid = ++last_ruid;
+ MR_DEPENDENCE_CLIQUE (base) = clique;
+ MR_DEPENDENCE_BASE (base) = restrict_var->ruid;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Clear dependence info for the clique DATA. */
+
+static bool
+clear_dependence_clique (gimple *, tree base, tree, void *data)
+{
+ unsigned short clique = (uintptr_t)data;
+ if ((TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ && MR_DEPENDENCE_CLIQUE (base) == clique)
+ {
+ MR_DEPENDENCE_CLIQUE (base) = 0;
+ MR_DEPENDENCE_BASE (base) = 0;
+ }
+
+ return false;
+}
+
+namespace pointer_analysis {
+
+/* Compute the set of independent memory references based on restrict
+ tags and their conservative propagation to the points-to sets. */
+
+void
+compute_dependence_clique (void)
+{
+ /* First clear the special "local" clique. */
+ basic_block bb;
+ if (cfun->last_clique != 0)
+ FOR_EACH_BB_FN (bb, cfun)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
+ clear_dependence_clique,
+ clear_dependence_clique);
+ }
+
+ unsigned short clique = 0;
+ unsigned short last_ruid = 0;
+ bitmap rvars = BITMAP_ALLOC (NULL);
+ bool escaped_p = false;
+ for (unsigned i = 0; i < num_ssa_names; ++i)
+ {
+ tree ptr = ssa_name (i);
+ if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
+ continue;
+
+ /* Avoid all this when ptr is not dereferenced? */
+ tree p = ptr;
+ if (SSA_NAME_IS_DEFAULT_DEF (ptr)
+ && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
+ || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
+ p = SSA_NAME_VAR (ptr);
+ varinfo_t vi = lookup_vi_for_tree (p);
+ if (!vi)
+ continue;
+ vi = get_varinfo (var_rep[vi->id]);
+ bitmap_iterator bi;
+ unsigned j;
+ varinfo_t restrict_var = NULL;
+ EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
+ {
+ varinfo_t oi = get_varinfo (j);
+ if (oi->head != j)
+ oi = get_varinfo (oi->head);
+ if (oi->is_restrict_var)
+ {
+ if (restrict_var
+ && restrict_var != oi)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "found restrict pointed-to "
+ "for ");
+ print_generic_expr (dump_file, ptr);
+ fprintf (dump_file, " but not exclusively\n");
+ }
+ restrict_var = NULL;
+ break;
+ }
+ restrict_var = oi;
+ }
+ /* NULL is the only other valid points-to entry. */
+ else if (oi->id != nothing_id)
+ {
+ restrict_var = NULL;
+ break;
+ }
+ }
+ /* Ok, found that ptr must(!) point to a single(!) restrict
+ variable. */
+ /* ??? PTA isn't really a proper propagation engine to compute
+ this property.
+ ??? We could handle merging of two restricts by unifying them. */
+ if (restrict_var)
+ {
+ /* Now look at possible dereferences of ptr. */
+ imm_use_iterator ui;
+ gimple *use_stmt;
+ bool used = false;
+ msdi_data data = { ptr, &clique, &last_ruid, restrict_var };
+ FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
+ used |= walk_stmt_load_store_ops (use_stmt, &data,
+ maybe_set_dependence_info,
+ maybe_set_dependence_info);
+ if (used)
+ {
+ /* Add all subvars to the set of restrict pointed-to set. */
+ for (unsigned sv = restrict_var->head; sv != 0;
+ sv = get_varinfo (sv)->next)
+ bitmap_set_bit (rvars, sv);
+ varinfo_t escaped = get_varinfo (var_rep[escaped_id]);
+ if (bitmap_bit_p (escaped->solution, restrict_var->id))
+ escaped_p = true;
+ }
+ }
+ }
+
+ if (clique != 0)
+ {
+ /* Assign the BASE id zero to all accesses not based on a restrict
+ pointer. That way they get disambiguated against restrict
+ accesses but not against each other. */
+ /* ??? For restricts derived from globals (thus not incoming
+ parameters) we can't restrict scoping properly thus the following
+ is too aggressive there. For now we have excluded those globals from
+ getting into the MR_DEPENDENCE machinery. */
+ vls_data data = { clique, escaped_p, rvars };
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, cfun)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ walk_stmt_load_store_ops (stmt, &data,
+ visit_loadstore, visit_loadstore);
+ }
+ }
+
+ BITMAP_FREE (rvars);
+}
+
+} // namespace pointer_analysis
diff --git a/gcc/gimple-ssa-pta-restrict.h b/gcc/gimple-ssa-pta-restrict.h
new file mode 100644
index 00000000000..c4cd79f64d4
--- /dev/null
+++ b/gcc/gimple-ssa-pta-restrict.h
@@ -0,0 +1,30 @@
+/* Tree based points-to analysis - restrict keyword logic
+ Copyright (C) 2005-2025 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <[email protected]>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GIMPLE_SSA_PTA_RESTRICT
+#define GIMPLE_SSA_PTA_RESTRICT
+
+namespace pointer_analysis {
+
+void compute_dependence_clique (void);
+
+} // namespace pointer_analysis
+
+#endif /* GIMPLE_SSA_PTA_RESTRICT */
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index 0035e50c62c..1975a02091d 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -50,6 +50,7 @@
#include "tree-ssa-structalias.h"
#include "pta-andersen.h"
+#include "gimple-ssa-pta-restrict.h"
/* The idea behind this analyzer is to generate set constraints from the
program, then solve the resulting constraints in order to generate the
@@ -204,6 +205,17 @@
And probably more. */
+using namespace pointer_analysis;
+
+/* Map from trees to variable infos. */
+static hash_map<tree, varinfo_t> *vi_for_tree;
+
+static unsigned int create_variable_info_for (tree, const char *, bool);
+static const char * alias_get_name (tree);
+static unsigned int create_variable_info_for (tree, const char *, bool);
+static inline bool type_can_have_subvars (const_tree);
+static void make_param_constraints (varinfo_t);
+
namespace pointer_analysis {
/* Used for points-to sets. */
@@ -219,9 +231,6 @@ vec<varinfo_t> varmap;
/* List of constraints that we use to build the constraint graph from. */
vec<constraint_t> constraints;
-/* Map from trees to variable infos. */
-static hash_map<tree, varinfo_t> *vi_for_tree;
-
/* The representative variable for a variable. The points-to solution for a
var can be found in its rep. Trivially, a var can be its own rep.
@@ -288,6 +297,45 @@ first_or_preceding_vi_for_offset (varinfo_t start,
return start;
}
+/* Insert ID as the variable id for tree T in the vi_for_tree map. */
+
+void
+insert_vi_for_tree (tree t, varinfo_t vi)
+{
+ gcc_assert (vi);
+ bool existed = vi_for_tree->put (t, vi);
+ gcc_assert (!existed);
+}
+
+/* Find the variable info for tree T in VI_FOR_TREE. If T does not
+ exist in the map, return NULL, otherwise, return the varinfo we found. */
+
+varinfo_t
+lookup_vi_for_tree (tree t)
+{
+ varinfo_t *slot = vi_for_tree->get (t);
+ if (slot == NULL)
+ return NULL;
+
+ return *slot;
+}
+
+/* Find the variable id for tree T in the map.
+ If T doesn't exist in the map, create an entry for it and return it. */
+
+varinfo_t
+get_vi_for_tree (tree t)
+{
+ varinfo_t *slot = vi_for_tree->get (t);
+ if (slot == NULL)
+ {
+ unsigned int id = create_variable_info_for (t, alias_get_name (t),
false);
+ return get_varinfo (id);
+ }
+
+ return *slot;
+}
+
/* Print out constraint C to FILE. */
void
@@ -538,16 +586,9 @@ debug_varmap (void)
} // namespace pointer_analysis
-using namespace pointer_analysis;
-
static bool use_field_sensitive = true;
static int in_ipa_mode = 0;
-static unsigned int create_variable_info_for (tree, const char *, bool);
-static varinfo_t lookup_vi_for_tree (tree);
-static inline bool type_can_have_subvars (const_tree);
-static void make_param_constraints (varinfo_t);
-
/* Pool of variable info structures. */
static object_allocator<variable_info> variable_info_pool
("Variable info pool");
@@ -711,29 +752,6 @@ new_constraint (const struct constraint_expr lhs,
return ret;
}
-/* Insert ID as the variable id for tree T in the vi_for_tree map. */
-
-static void
-insert_vi_for_tree (tree t, varinfo_t vi)
-{
- gcc_assert (vi);
- bool existed = vi_for_tree->put (t, vi);
- gcc_assert (!existed);
-}
-
-/* Find the variable info for tree T in VI_FOR_TREE. If T does not
- exist in the map, return NULL, otherwise, return the varinfo we found. */
-
-static varinfo_t
-lookup_vi_for_tree (tree t)
-{
- varinfo_t *slot = vi_for_tree->get (t);
- if (slot == NULL)
- return NULL;
-
- return *slot;
-}
-
/* Return a printable name for DECL. */
static const char *
@@ -768,22 +786,6 @@ alias_get_name (tree decl)
return res;
}
-/* Find the variable id for tree T in the map.
- If T doesn't exist in the map, create an entry for it and return it. */
-
-static varinfo_t
-get_vi_for_tree (tree t)
-{
- varinfo_t *slot = vi_for_tree->get (t);
- if (slot == NULL)
- {
- unsigned int id = create_variable_info_for (t, alias_get_name (t),
false);
- return get_varinfo (id);
- }
-
- return *slot;
-}
-
/* Get a scalar constraint expression for a new temporary variable. */
static struct constraint_expr
@@ -5323,263 +5325,6 @@ delete_points_to_sets (void)
obstack_free (&final_solutions_obstack, NULL);
}
-struct vls_data
-{
- unsigned short clique;
- bool escaped_p;
- bitmap rvars;
-};
-
-/* Mark "other" loads and stores as belonging to CLIQUE and with
- base zero. */
-
-static bool
-visit_loadstore (gimple *, tree base, tree ref, void *data)
-{
- unsigned short clique = ((vls_data *) data)->clique;
- bitmap rvars = ((vls_data *) data)->rvars;
- bool escaped_p = ((vls_data *) data)->escaped_p;
- if (TREE_CODE (base) == MEM_REF
- || TREE_CODE (base) == TARGET_MEM_REF)
- {
- tree ptr = TREE_OPERAND (base, 0);
- if (TREE_CODE (ptr) == SSA_NAME)
- {
- /* For parameters, get at the points-to set for the actual parm
- decl. */
- if (SSA_NAME_IS_DEFAULT_DEF (ptr)
- && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
- || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
- ptr = SSA_NAME_VAR (ptr);
-
- /* We need to make sure 'ptr' doesn't include any of
- the restrict tags we added bases for in its points-to set. */
- varinfo_t vi = lookup_vi_for_tree (ptr);
- if (! vi)
- return false;
-
- vi = get_varinfo (var_rep[vi->id]);
- if (bitmap_intersect_p (rvars, vi->solution)
- || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
- return false;
- }
-
- /* Do not overwrite existing cliques (that includes clique, base
- pairs we just set). */
- if (MR_DEPENDENCE_CLIQUE (base) == 0)
- {
- MR_DEPENDENCE_CLIQUE (base) = clique;
- MR_DEPENDENCE_BASE (base) = 0;
- }
- }
-
- /* For plain decl accesses see whether they are accesses to globals
- and rewrite them to MEM_REFs with { clique, 0 }. */
- if (VAR_P (base)
- && is_global_var (base)
- /* ??? We can't rewrite a plain decl with the walk_stmt_load_store
- ops callback. */
- && base != ref)
- {
- tree *basep = &ref;
- while (handled_component_p (*basep))
- basep = &TREE_OPERAND (*basep, 0);
- gcc_assert (VAR_P (*basep));
- tree ptr = build_fold_addr_expr (*basep);
- tree zero = build_int_cst (TREE_TYPE (ptr), 0);
- *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
- MR_DEPENDENCE_CLIQUE (*basep) = clique;
- MR_DEPENDENCE_BASE (*basep) = 0;
- }
-
- return false;
-}
-
-struct msdi_data {
- tree ptr;
- unsigned short *clique;
- unsigned short *last_ruid;
- varinfo_t restrict_var;
-};
-
-/* If BASE is a MEM_REF then assign a clique, base pair to it, updating
- CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA.
- Return whether dependence info was assigned to BASE. */
-
-static bool
-maybe_set_dependence_info (gimple *, tree base, tree, void *data)
-{
- tree ptr = ((msdi_data *)data)->ptr;
- unsigned short &clique = *((msdi_data *)data)->clique;
- unsigned short &last_ruid = *((msdi_data *)data)->last_ruid;
- varinfo_t restrict_var = ((msdi_data *)data)->restrict_var;
- if ((TREE_CODE (base) == MEM_REF
- || TREE_CODE (base) == TARGET_MEM_REF)
- && TREE_OPERAND (base, 0) == ptr)
- {
- /* Do not overwrite existing cliques. This avoids overwriting dependence
- info inlined from a function with restrict parameters inlined
- into a function with restrict parameters. This usually means we
- prefer to be precise in innermost loops. */
- if (MR_DEPENDENCE_CLIQUE (base) == 0)
- {
- if (clique == 0)
- {
- if (cfun->last_clique == 0)
- cfun->last_clique = 1;
- clique = 1;
- }
- if (restrict_var->ruid == 0)
- restrict_var->ruid = ++last_ruid;
- MR_DEPENDENCE_CLIQUE (base) = clique;
- MR_DEPENDENCE_BASE (base) = restrict_var->ruid;
- return true;
- }
- }
- return false;
-}
-
-/* Clear dependence info for the clique DATA. */
-
-static bool
-clear_dependence_clique (gimple *, tree base, tree, void *data)
-{
- unsigned short clique = (uintptr_t)data;
- if ((TREE_CODE (base) == MEM_REF
- || TREE_CODE (base) == TARGET_MEM_REF)
- && MR_DEPENDENCE_CLIQUE (base) == clique)
- {
- MR_DEPENDENCE_CLIQUE (base) = 0;
- MR_DEPENDENCE_BASE (base) = 0;
- }
-
- return false;
-}
-
-/* Compute the set of independend memory references based on restrict
- tags and their conservative propagation to the points-to sets. */
-
-static void
-compute_dependence_clique (void)
-{
- /* First clear the special "local" clique. */
- basic_block bb;
- if (cfun->last_clique != 0)
- FOR_EACH_BB_FN (bb, cfun)
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
- clear_dependence_clique,
- clear_dependence_clique);
- }
-
- unsigned short clique = 0;
- unsigned short last_ruid = 0;
- bitmap rvars = BITMAP_ALLOC (NULL);
- bool escaped_p = false;
- for (unsigned i = 0; i < num_ssa_names; ++i)
- {
- tree ptr = ssa_name (i);
- if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
- continue;
-
- /* Avoid all this when ptr is not dereferenced? */
- tree p = ptr;
- if (SSA_NAME_IS_DEFAULT_DEF (ptr)
- && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
- || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
- p = SSA_NAME_VAR (ptr);
- varinfo_t vi = lookup_vi_for_tree (p);
- if (!vi)
- continue;
- vi = get_varinfo (var_rep[vi->id]);
- bitmap_iterator bi;
- unsigned j;
- varinfo_t restrict_var = NULL;
- EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
- {
- varinfo_t oi = get_varinfo (j);
- if (oi->head != j)
- oi = get_varinfo (oi->head);
- if (oi->is_restrict_var)
- {
- if (restrict_var
- && restrict_var != oi)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "found restrict pointed-to "
- "for ");
- print_generic_expr (dump_file, ptr);
- fprintf (dump_file, " but not exclusively\n");
- }
- restrict_var = NULL;
- break;
- }
- restrict_var = oi;
- }
- /* NULL is the only other valid points-to entry. */
- else if (oi->id != nothing_id)
- {
- restrict_var = NULL;
- break;
- }
- }
- /* Ok, found that ptr must(!) point to a single(!) restrict
- variable. */
- /* ??? PTA isn't really a proper propagation engine to compute
- this property.
- ??? We could handle merging of two restricts by unifying them. */
- if (restrict_var)
- {
- /* Now look at possible dereferences of ptr. */
- imm_use_iterator ui;
- gimple *use_stmt;
- bool used = false;
- msdi_data data = { ptr, &clique, &last_ruid, restrict_var };
- FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
- used |= walk_stmt_load_store_ops (use_stmt, &data,
- maybe_set_dependence_info,
- maybe_set_dependence_info);
- if (used)
- {
- /* Add all subvars to the set of restrict pointed-to set. */
- for (unsigned sv = restrict_var->head; sv != 0;
- sv = get_varinfo (sv)->next)
- bitmap_set_bit (rvars, sv);
- varinfo_t escaped = get_varinfo (var_rep[escaped_id]);
- if (bitmap_bit_p (escaped->solution, restrict_var->id))
- escaped_p = true;
- }
- }
- }
-
- if (clique != 0)
- {
- /* Assign the BASE id zero to all accesses not based on a restrict
- pointer. That way they get disambiguated against restrict
- accesses but not against each other. */
- /* ??? For restricts derived from globals (thus not incoming
- parameters) we can't restrict scoping properly thus the following
- is too aggressive there. For now we have excluded those globals from
- getting into the MR_DEPENDENCE machinery. */
- vls_data data = { clique, escaped_p, rvars };
- basic_block bb;
- FOR_EACH_BB_FN (bb, cfun)
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- walk_stmt_load_store_ops (stmt, &data,
- visit_loadstore, visit_loadstore);
- }
- }
-
- BITMAP_FREE (rvars);
-}
-
/* Compute points-to information for every SSA_NAME pointer in the
current function and compute the transitive closure of escaped
variables to re-initialize the call-clobber states of local variables. */
diff --git a/gcc/tree-ssa-structalias.h b/gcc/tree-ssa-structalias.h
index 4104bad3499..7f3be31ff4f 100644
--- a/gcc/tree-ssa-structalias.h
+++ b/gcc/tree-ssa-structalias.h
@@ -198,6 +198,11 @@ varinfo_t first_vi_for_offset (varinfo_t start,
unsigned HOST_WIDE_INT offset);
varinfo_t first_or_preceding_vi_for_offset (varinfo_t start,
unsigned HOST_WIDE_INT offset);
+
+void insert_vi_for_tree (tree, varinfo_t);
+varinfo_t lookup_vi_for_tree (tree);
+varinfo_t get_vi_for_tree (tree);
+
void dump_constraint (FILE *file, constraint_t c);
void dump_constraints (FILE *file, int from);
void dump_solution_for_var (FILE *file, unsigned int var);
--
2.49.0