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 <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); -- 2.49.0