diff options
author | Andrey Belevantsev <abel@ispras.ru> | 2009-04-15 16:03:24 +0000 |
---|---|---|
committer | Andrey Belevantsev <abel@ispras.ru> | 2009-04-15 16:03:24 +0000 |
commit | 7a55d6004e438471c7e498d6cb5eda49fea39062 (patch) | |
tree | 08f209de3650b4422588826083cda7cdb943cce0 | |
parent | f14bb9a322f156955156fa1e042e406a251d6e73 (diff) |
* alias.c (true_dependence): Do not use the result
of memrefs_conflict_p call for judging whether to call the oracle.
(canon_true_dependence, write_dependence_p): Likewise.
* alias-export.c (uids_to_decls, part_repr_to_part,
part_repr_to_pta): New pointer maps.
(handle_free_aliases): Free them.
(mark_conflict_stack_vars): New.
(find_pta_info): Remove and inline in ...
(unshare_and_record_pta_info): ... here. Call mark_conflict_stack_vars
when recording points-to solution.
(map_uid_to_decl, map_decl_to_representative,
map_decl_to_bitmap): New.
(record_stack_var_partition_for): Use them.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/alias-export@146128 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/alias-export.c | 156 | ||||
-rw-r--r-- | gcc/alias.c | 24 | ||||
-rw-r--r-- | gcc/ssaexpand.h | 60 |
4 files changed, 224 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 845b9ab0209..6ca302dd06f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2009-04-15 Andrey Belevantsev <abel@ispras.ru> + + * alias.c (true_dependence): Do not use the result + of memrefs_conflict_p call for judging whether to call the oracle. + (canon_true_dependence, write_dependence_p): Likewise. + * alias-export.c (uids_to_decls, part_repr_to_part, + part_repr_to_pta): New pointer maps. + (handle_free_aliases): Free them. + (mark_conflict_stack_vars): New. + (find_pta_info): Remove and inline in ... + (unshare_and_record_pta_info): ... here. Call mark_conflict_stack_vars + when recording points-to solution. + (map_uid_to_decl, map_decl_to_representative, + map_decl_to_bitmap): New. + (record_stack_var_partition_for): Use them. + 2009-04-14 Andrey Belevantsev <abel@ispras.ru> Apply expand from SSA patch. diff --git a/gcc/alias-export.c b/gcc/alias-export.c index d50b75f762a..f4b4169fc9b 100644 --- a/gcc/alias-export.c +++ b/gcc/alias-export.c @@ -53,6 +53,18 @@ static struct pointer_map_t *exprs_to_ptas = NULL; /* The map of decls to stack partitions. */ static struct pointer_map_t *decls_to_stack = NULL; +/* The map of decl uids to decl pointers. This is needed because points-to sets + have only decl uids. */ +static struct pointer_map_t *uids_to_decls = NULL; + +/* The map of partition representative decls to bitmaps that are + unified points-to sets for pointer decls. */ +static struct pointer_map_t *part_repr_to_pta = NULL; + +/* The map of partition representative decls to bitmaps that have + set bits corresponding to decl uids of a partition. */ +static struct pointer_map_t *part_repr_to_part = NULL; + /* Return the pointer on which REF access is based, or NULL, if there's no such thing. */ static tree @@ -72,17 +84,45 @@ get_pointer_from_ref (tree ref) return NULL; } -/* Find the points-to set for ORIG_EXPR. */ -static struct ptr_info_def * -find_pta_info (tree orig_expr) +/* Change points-to set for POINTER in PID so that it would + have all conflicting stack vars. */ +static void +mark_conflict_stack_vars (tree pointer ATTRIBUTE_UNUSED, struct ptr_info_def *pid) { - tree pointer; + bitmap_iterator bi; + unsigned i; + bitmap temp; + tree *pdecl; - pointer = get_pointer_from_ref (orig_expr); - if (! pointer - || TREE_CODE (pointer) != SSA_NAME) - return NULL; - return SSA_NAME_PTR_INFO (pointer); + if (!decls_to_stack) + return; + + /* If pointer points to one of partition vars, make it point to all + of them. */ + if (pid->pt.vars) + { + temp = BITMAP_ALLOC (NULL); + EXECUTE_IF_SET_IN_BITMAP (pid->pt.vars, 0, i, bi) + if ((pdecl = (tree *) pointer_map_contains (uids_to_decls, + (void *) (size_t) i))) + { + pdecl = (tree *) pointer_map_contains (decls_to_stack, *pdecl); + gcc_assert (pdecl); + bitmap_ior_into (temp, + *((bitmap *) pointer_map_contains (part_repr_to_part, + *pdecl))); + } + bitmap_ior_into (pid->pt.vars, temp); + BITMAP_FREE (temp); + } + + /* If pointer got paritioned itself, make its points-to set a union + of all the partition vars' points-to sets. */ + if ((pdecl = (tree *) pointer_map_contains (decls_to_stack, pointer))) + { + temp = *((bitmap *) pointer_map_contains (part_repr_to_pta, *pdecl)); + bitmap_ior_into (pid->pt.vars, temp); + } } /* Record the final points-to set and returns orig expr. */ @@ -90,20 +130,24 @@ tree unshare_and_record_pta_info (tree orig_expr) { struct ptr_info_def **ppid, *pid; - tree old_expr = orig_expr; + tree pointer, old_expr; /* No point saving anything for calls. */ if (TREE_CODE (orig_expr) == CALL_EXPR) return NULL; - - pid = find_pta_info (orig_expr); - orig_expr = unshare_expr (orig_expr); + old_expr = orig_expr; + orig_expr = unshare_expr (orig_expr); if (flag_ddg_export) replace_var_in_datarefs (old_expr, orig_expr); - if (!pid) + pointer = get_pointer_from_ref (orig_expr); + if (! pointer + || TREE_CODE (pointer) != SSA_NAME + || (pid = SSA_NAME_PTR_INFO (pointer)) == NULL) return orig_expr; + + mark_conflict_stack_vars (pointer, pid); if (!exprs_to_ptas) exprs_to_ptas = pointer_map_create (); @@ -113,15 +157,83 @@ unshare_and_record_pta_info (tree orig_expr) return orig_expr; } -/* Save stack partitions. */ -void -record_stack_var_partition_for (tree decl, tree part_decl) +/* Record the uid mapping for DECL. */ +static void +map_uid_to_decl (tree decl) +{ + if (DECL_P (decl)) + { + if (!uids_to_decls) + uids_to_decls = pointer_map_create (); + *((tree *) pointer_map_insert (uids_to_decls, + (void *) (size_t) DECL_UID (decl))) = decl; + } +} + +/* Record the DECL mapping to its PART_DECL representative. */ +static void +map_decl_to_representative (tree decl, tree part_decl) { if (!decls_to_stack) decls_to_stack = pointer_map_create (); *((tree *) pointer_map_insert (decls_to_stack, decl)) = part_decl; } +/* Create a bitmap in PMAP associated with DECL and return it. */ +static bitmap +map_decl_to_bitmap (struct pointer_map_t **pmap, tree decl) +{ + bitmap temp = NULL, *ptemp; + + if (!*pmap) + *pmap = pointer_map_create (); + ptemp = (bitmap *) pointer_map_contains (*pmap, decl); + if (ptemp) + { + temp = *ptemp; + gcc_assert (temp); + } + else + { + temp = BITMAP_ALLOC (NULL); + *((bitmap *) pointer_map_insert (*pmap, decl)) = temp; + } + + return temp; +} + +/* Save stack partitions. DECL has PART_DECL as a representative. + Also, create pta bitmaps so that alias analysis is not confused later. */ +void +record_stack_var_partition_for (tree decl, tree part_decl) +{ + bitmap temp; + + /* First, record that decl has part_decl as a representative, and their uids. */ + map_decl_to_representative (decl, part_decl); + map_uid_to_decl (decl); + map_uid_to_decl (part_decl); + + /* Second, create a bitmap that represents all partition. */ + temp = map_decl_to_bitmap (&part_repr_to_part, part_decl); + if (DECL_P (part_decl)) + bitmap_set_bit (temp, DECL_UID (part_decl)); + if (DECL_P (decl)) + bitmap_set_bit (temp, DECL_UID (decl)); + + /* Third, when decl is a pointer, we need to do the same + for points-to sets. */ + if (TREE_CODE (decl) == SSA_NAME + && SSA_NAME_PTR_INFO (decl)) + { + temp = map_decl_to_bitmap (&part_repr_to_pta, part_decl); + if (TREE_CODE (part_decl) == SSA_NAME + && SSA_NAME_PTR_INFO (part_decl)) + bitmap_ior_into (temp, SSA_NAME_PTR_INFO (part_decl)->pt.vars); + bitmap_ior_into (temp, SSA_NAME_PTR_INFO (decl)->pt.vars); + } +} + /* Return the ptr-info-def structure for given expression. */ struct ptr_info_def * get_exported_ptr_info (tree expr) @@ -461,6 +573,16 @@ handle_free_aliases (void) pointer_map_destroy (decls_to_stack); decls_to_stack = NULL; } + if (part_repr_to_pta) + { + pointer_map_destroy (part_repr_to_pta); + part_repr_to_pta = NULL; + } + if (part_repr_to_part) + { + pointer_map_destroy (part_repr_to_part); + part_repr_to_part = NULL; + } if (gimple_df_escaped.vars) { BITMAP_FREE (gimple_df_escaped.vars); diff --git a/gcc/alias.c b/gcc/alias.c index d9fe3ac7e43..a3f2eff0dfe 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -2264,7 +2264,6 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, { rtx x_addr, mem_addr; rtx base; - int memret; if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -2311,12 +2310,11 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, x_addr = canon_rtx (x_addr); mem_addr = canon_rtx (mem_addr); - if (! (memret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0))) + if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) return 0; - if (memret != 2 - && ! query_alias_export_info (x, mem, 1)) + if (! query_alias_export_info (x, mem, 1)) return 0; if (aliases_everything_p (x)) @@ -2347,7 +2345,6 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, const_rtx x, bool (*varies) (const_rtx, bool)) { rtx x_addr; - int memret; if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -2382,12 +2379,11 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, return 0; x_addr = canon_rtx (x_addr); - if (! (memret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0))) + if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) return 0; - if (memret != 2 - && ! query_alias_export_info (x, mem, 1)) + if (! query_alias_export_info (x, mem, 1)) return 0; if (aliases_everything_p (x)) @@ -2416,7 +2412,6 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) rtx x_addr, mem_addr; const_rtx fixed_scalar; rtx base; - int memret; if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -2462,12 +2457,11 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) x_addr = canon_rtx (x_addr); mem_addr = canon_rtx (mem_addr); - if (! (memret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0))) + if (! memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) return 0; - if (memret != 2 - && ! query_alias_export_info (x, mem, 1)) + if (! query_alias_export_info (x, mem, 1)) return 0; fixed_scalar diff --git a/gcc/ssaexpand.h b/gcc/ssaexpand.h new file mode 100644 index 00000000000..60beb14e055 --- /dev/null +++ b/gcc/ssaexpand.h @@ -0,0 +1,60 @@ +/* Routines for expanding from SSA form to RTL. + Copyright (C) 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, 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 _SSAEXPAND_H +#define _SSAEXPAND_H 1 + +#include "tree-ssa-live.h" + +struct ssaexpand +{ + var_map map; + gimple *values; + rtx *partition_to_pseudo; + void *elim_graph; +}; + +extern struct ssaexpand SA; + +static inline rtx +get_rtx_for_ssa_name (tree exp) +{ + int p = partition_find (SA.map->var_partition, SSA_NAME_VERSION (exp)); + if (SA.map->partition_to_view) + p = SA.map->partition_to_view[p]; + gcc_assert (p != NO_PARTITION); + return SA.partition_to_pseudo[p]; +} + +static inline gimple +get_gimple_for_ssa_name (tree exp) +{ + int v = SSA_NAME_VERSION (exp); + if (SA.values) + return SA.values[v]; + return NULL; +} + +/* In tree-outof-ssa.c. */ +void finish_out_of_ssa (struct ssaexpand *sa); +unsigned int rewrite_out_of_ssa (struct ssaexpand *sa); +void expand_phi_nodes (struct ssaexpand *sa); + +#endif |