On Wed 2025-07-30 12:41:09, Richard Biener wrote:
> 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.

Ah, right.  I was under the impression that I'm splitting out all the restrict
logic.  But now I see that there are functions like
make_constraint_from_restrict() so the restrict handling is coupled more
tightly with the rest of pta.

Alright, then my current plans are to just split out the constraint building
and then start working on the Steensgaard solver.

Thanks,
Filip Kastl

> 
> > 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