aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authorDorit Nuzman <dorit@il.ibm.com>2006-08-10 12:07:22 +0000
committerDorit Nuzman <dorit@gcc.gnu.org>2006-08-10 12:07:22 +0000
commitcc0968b01cb62e4f843bb0d3c16a62454b94a4c4 (patch)
tree48285f9f7c641d9cc4879127dc49ff7ea3d12d07 /gcc/tree-ssa-alias.c
parent22a8ed6556f9d57d93f43b60da5198136890f9c7 (diff)
downloadgcc-cc0968b01cb62e4f843bb0d3c16a62454b94a4c4.zip
gcc-cc0968b01cb62e4f843bb0d3c16a62454b94a4c4.tar.gz
gcc-cc0968b01cb62e4f843bb0d3c16a62454b94a4c4.tar.bz2
re PR tree-optimization/26197 (ICE in is_old_name with vectorizer)
PR tree-optimization/26197 * tree-ssa-alias.c (new_type_alias): Takes additional argument. Calls get_ref_base_and_extent and overlap_subvar to add only relevant subvars as may-aliases. (add_may_alias_for_new_tag): New function, factored out of new_type_alias. * tree-vect-transform.c (vect_create_data_ref_ptr): Call new_type_alias with additional argument. * tree-flow.h (new_type_alias): Takes additional argument. From-SVN: r116060
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c122
1 files changed, 83 insertions, 39 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 1607c71..6bfa4bb 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2691,79 +2691,123 @@ is_aliased_with (tree tag, tree sym)
return false;
}
+/* The following is based on code in add_stmt_operand to ensure that the
+ same defs/uses/vdefs/vuses will be found after replacing a reference
+ to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value
+ is the address of var. Return a memtag for the ptr, after adding the
+ proper may_aliases to it (which are the aliases of var, if it has any,
+ or var itself). */
+
+static tree
+add_may_alias_for_new_tag (tree tag, tree var)
+{
+ var_ann_t v_ann = var_ann (var);
+ VEC(tree, gc) *aliases = v_ann->may_aliases;
+
+ /* Case 1: |aliases| == 1 */
+ if ((aliases != NULL)
+ && (VEC_length (tree, aliases) == 1))
+ {
+ tree ali = VEC_index (tree, aliases, 0);
+
+ if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG)
+ return ali;
+ }
+
+ /* Case 2: |aliases| == 0 */
+ if (aliases == NULL)
+ add_may_alias (tag, var);
+ else
+ {
+ /* Case 3: |aliases| > 1 */
+ unsigned i;
+ tree al;
+
+ for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
+ add_may_alias (tag, al);
+ }
+
+ return tag;
+}
/* Create a new symbol tag for PTR. Construct the may-alias list of this type
- tag so that it has the aliasing of VAR.
+ tag so that it has the aliasing of VAR, or of the relevant subvars of VAR
+ according to the location accessed by EXPR.
Note, the set of aliases represented by the new symbol tag are not marked
for renaming. */
void
-new_type_alias (tree ptr, tree var)
+new_type_alias (tree ptr, tree var, tree expr)
{
var_ann_t p_ann = var_ann (ptr);
tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
- var_ann_t v_ann = var_ann (var);
tree tag;
subvar_t svars;
+ tree ali = NULL_TREE;
+ HOST_WIDE_INT offset, size, maxsize;
+ tree ref;
gcc_assert (p_ann->symbol_mem_tag == NULL_TREE);
gcc_assert (!MTAG_P (var));
+ ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize);
+ gcc_assert (ref);
+
+ tag = create_memory_tag (tag_type, true);
+ p_ann->symbol_mem_tag = tag;
+
/* Add VAR to the may-alias set of PTR's new symbol tag. If VAR has
subvars, add the subvars to the tag instead of the actual var. */
if (var_can_have_subvars (var)
&& (svars = get_subvars_for_var (var)))
{
subvar_t sv;
-
- tag = create_memory_tag (tag_type, true);
- p_ann->symbol_mem_tag = tag;
+ VEC (tree, heap) *overlaps = NULL;
+ unsigned int len;
for (sv = svars; sv; sv = sv->next)
- add_may_alias (tag, sv->var);
- }
- else
- {
- /* The following is based on code in add_stmt_operand to ensure that the
- same defs/uses/vdefs/vuses will be found after replacing a reference
- to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value
- is the address of var. */
- VEC(tree, gc) *aliases = v_ann->may_aliases;
-
- if ((aliases != NULL)
- && (VEC_length (tree, aliases) == 1))
{
- tree ali = VEC_index (tree, aliases, 0);
+ bool exact;
- if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG)
+ if (overlap_subvar (offset, maxsize, sv->var, &exact))
+ VEC_safe_push (tree, heap, overlaps, sv->var);
+ }
+ len = VEC_length (tree, overlaps);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nnumber of overlapping subvars = %u\n", len);
+ gcc_assert (len);
+
+ if (len == 1)
+ ali = add_may_alias_for_new_tag (tag, VEC_index (tree, overlaps, 0));
+ else if (len > 1)
+ {
+ unsigned int k;
+ tree sv_var;
+
+ for (k = 0; VEC_iterate (tree, overlaps, k, sv_var); k++)
{
- p_ann->symbol_mem_tag = ali;
- return;
- }
- }
-
- tag = create_memory_tag (tag_type, true);
- p_ann->symbol_mem_tag = tag;
-
- if (aliases == NULL)
- add_may_alias (tag, var);
- else
- {
- unsigned i;
- tree al;
+ ali = add_may_alias_for_new_tag (tag, sv_var);
- for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
- add_may_alias (tag, al);
+ if (ali != tag)
+ {
+ /* Can happen only if 'Case 1' of add_may_alias_for_new_tag
+ took place. Since more than one svar was found, we add
+ 'ali' as one of the may_aliases of the new tag. */
+ add_may_alias (tag, ali);
+ ali = tag;
+ }
+ }
}
- }
+ }
+ else
+ ali = add_may_alias_for_new_tag (tag, var);
+ p_ann->symbol_mem_tag = ali;
TREE_READONLY (tag) = TREE_READONLY (var);
MTAG_GLOBAL (tag) = is_global_var (var);
}
-
-
/* This represents the used range of a variable. */
typedef struct used_part