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)

Reply via email to