On Wed, 30 Jul 2025, Filip Kastl wrote: > 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 don't think it is really a separate thing since it relies on the constraint processing and the bits you move are really the translation of the points-to result to SSA points-to, so belong to where the SSA pass is. > 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 <fka...@suse.cz> > --- > 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 <dber...@dberlin.org> > + > + 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 <dber...@dberlin.org> > + > + 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); > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)