summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/tree-ssa-alias.c13
-rw-r--r--gcc/tree-ssa-copy.c83
-rw-r--r--gcc/tree-ssa-copyrename.c15
-rw-r--r--gcc/tree-ssa.c6
-rw-r--r--gcc/tree-ssanames.c10
-rw-r--r--gcc/tree.h1
7 files changed, 119 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a563915de0..bd8785c902c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,31 @@
+2004-07-23 Diego Novillo <dnovillo@redhat.com>
+
+ PR tree-optimization/16688
+ PR tree-optimization/16689
+ * tree-ssa-alias.c (setup_pointers_and_addressables): Remove
+ unnecessary initialization of 'tag'.
+ (get_tmt_for): Check that the new type tag has the same alias
+ set as the pointed-to type.
+ (group_aliases): Only regular variables need to be removed
+ from the alias set of a name tag.
+ * tree-ssa-copy.c (may_propagate_copy): Do not allow copy
+ propagation if the two types are not compatible.
+ (merge_alias_info): Rename from replace_ssa_names_ann.
+ Add more checking.
+ (replace_exp_1): If both arguments are SSA_NAMEs, check that
+ the propagation can be done.
+ Only call merge_alias_info on pointers.
+ (propagate_value): Likewise.
+ * tree-ssa-copyrename.c: Include langhooks.h.
+ (copy_rename_partition_coalesce): Call replace_ssa_name_symbol
+ to do the merging.
+ Do not coalesce variables with incompatible types.
+ (rename_ssa_copies): Call replace_ssa_name_symbol.
+ * tree-ssa.c (verify_ssa_name): Verify that the SSA_NAME has
+ the same type as the underlying _DECL.
+ * tree-ssanames.c (replace_ssa_name_symbol): New function.
+ * tree.h (replace_ssa_name_symbol): Declare.
+
2004-07-23 Richard Henderson <rth@redhat.com>
PR c++/16277
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index a854b0bd897..fab9e027841 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1225,7 +1225,8 @@ group_aliases (struct alias_info *ai)
{
tree alias = VARRAY_TREE (aliases, j);
var_ann_t ann = var_ann (alias);
- if (ann->may_aliases)
+
+ if (ann->mem_tag_kind == NOT_A_TAG && ann->may_aliases)
{
tree new_alias;
@@ -1370,7 +1371,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
&& (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid)
|| bitmap_bit_p (ai->dereferenced_ptrs_load, v_ann->uid)))
{
- tree tag = v_ann->type_mem_tag;
+ tree tag;
var_ann_t t_ann;
/* If pointer VAR still doesn't have a memory tag associated
@@ -2170,6 +2171,14 @@ get_tmt_for (tree ptr, struct alias_info *ai)
ai->pointers[ai->num_pointers++] = alias_map;
}
+#if defined ENABLE_CHECKING
+ /* Make sure that the type tag has the same alias set as the
+ pointed-to type. */
+ if (tag_set != get_alias_set (tag))
+ abort ();
+#endif
+
+
return tag;
}
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 5d96fae8e5b..0ddfa9ce825 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -110,6 +110,8 @@ may_propagate_copy (tree dest, tree orig)
tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
if (mt_dest && mt_orig && mt_dest != mt_orig)
return false;
+ else if (!lang_hooks.types_compatible_p (type_d, type_o))
+ return false;
}
/* If the destination is a SSA_NAME for a virtual operand, then we have
@@ -152,41 +154,40 @@ may_propagate_copy (tree dest, tree orig)
return true;
}
-/* Given two SSA_NAMEs, replace the annotations for the one referred to by OP
- with VAR's annotations.
-
- If OP is a pointer, copy the memory tag used originally by OP into
- VAR. This is needed in cases where VAR had never been dereferenced in the
- program.
- If FOR_PROPAGATION is true, then perform additional checks to ensure
- that const/copy propagation of var for OP is valid. */
+/* Given two SSA_NAMEs pointers ORIG and NEW such that we are copy
+ propagating NEW into ORIG, consolidate aliasing information so that
+ they both share the same memory tags. */
static void
-replace_ssa_names_ann (tree op,
- tree var,
- bool for_propagation ATTRIBUTE_UNUSED)
+merge_alias_info (tree orig, tree new)
{
+ tree new_sym = SSA_NAME_VAR (new);
+ tree orig_sym = SSA_NAME_VAR (orig);
+ var_ann_t new_ann = var_ann (new_sym);
+ var_ann_t orig_ann = var_ann (orig_sym);
+
#if defined ENABLE_CHECKING
- if (for_propagation && !may_propagate_copy (op, var))
+ if (!POINTER_TYPE_P (TREE_TYPE (orig))
+ || !POINTER_TYPE_P (TREE_TYPE (new))
+ || !lang_hooks.types_compatible_p (TREE_TYPE (orig), TREE_TYPE (new)))
abort ();
-#endif
- /* If VAR doesn't have a memory tag, copy the one from the original
- operand. Also copy the dereferenced flags. */
- if (POINTER_TYPE_P (TREE_TYPE (op)))
- {
- var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
- var_ann_t orig_ann = var_ann (SSA_NAME_VAR (op));
-
- if (new_ann->type_mem_tag == NULL_TREE)
- new_ann->type_mem_tag = orig_ann->type_mem_tag;
- else if (orig_ann->type_mem_tag == NULL_TREE)
- orig_ann->type_mem_tag = new_ann->type_mem_tag;
- else if (new_ann->type_mem_tag != orig_ann->type_mem_tag)
- abort ();
- }
+ /* If the pointed-to alias sets are different, these two pointers
+ would never have the same memory tag. In this case, NEW should
+ not have been propagated into ORIG. */
+ if (get_alias_set (TREE_TYPE (TREE_TYPE (new_sym)))
+ != get_alias_set (TREE_TYPE (TREE_TYPE (orig_sym))))
+ abort ();
+#endif
+ /* Merge type-based alias info. */
+ if (new_ann->type_mem_tag == NULL_TREE)
+ new_ann->type_mem_tag = orig_ann->type_mem_tag;
+ else if (orig_ann->type_mem_tag == NULL_TREE)
+ orig_ann->type_mem_tag = new_ann->type_mem_tag;
+ else if (new_ann->type_mem_tag != orig_ann->type_mem_tag)
+ abort ();
}
@@ -196,12 +197,23 @@ replace_ssa_names_ann (tree op,
replacement is done to propagate a value or not. */
static void
-replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation)
+replace_exp_1 (use_operand_p op_p, tree val,
+ bool for_propagation ATTRIBUTE_UNUSED)
{
+ tree op = USE_FROM_PTR (op_p);
+
+#if defined ENABLE_CHECKING
+ if (for_propagation
+ && TREE_CODE (op) == SSA_NAME
+ && TREE_CODE (val) == SSA_NAME
+ && !may_propagate_copy (op, val))
+ abort ();
+#endif
+
if (TREE_CODE (val) == SSA_NAME)
{
- if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
- replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation);
+ if (TREE_CODE (op) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (op)))
+ merge_alias_info (op, val);
SET_USE (op_p, val);
}
else
@@ -233,10 +245,17 @@ propagate_value (use_operand_p op_p, tree val)
void
propagate_tree_value (tree *op_p, tree val)
{
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (val) == SSA_NAME
+ && TREE_CODE (*op_p) == SSA_NAME
+ && !may_propagate_copy (*op_p, val))
+ abort ();
+#endif
+
if (TREE_CODE (val) == SSA_NAME)
{
- if (TREE_CODE (*op_p) == SSA_NAME)
- replace_ssa_names_ann (*op_p, val, true);
+ if (TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
+ merge_alias_info (*op_p, val);
*op_p = val;
}
else
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index c65b8284de6..ac7c00aa06e 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
#include "tree-dump.h"
#include "tree-ssa-live.h"
#include "tree-pass.h"
+#include "langhooks.h"
extern void rename_ssa_copies (void);
@@ -247,16 +248,24 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
gimp2 = false;
}
+ /* Don't coalesce if the two variables aren't type compatible. */
+ if (!lang_hooks.types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
+ {
+ if (debug)
+ fprintf (debug, " : Incompatible types. No coalesce.\n");
+ return;
+ }
+
/* Merge the two partitions. */
p3 = partition_union (map->var_partition, p1, p2);
/* Set the root variable of the partition to the better choice, if there is
one. */
if (!gimp2)
- SSA_NAME_VAR (partition_to_var (map, p3)) = root2;
+ replace_ssa_name_symbol (partition_to_var (map, p3), root2);
else
if (!gimp1)
- SSA_NAME_VAR (partition_to_var (map, p3)) = root1;
+ replace_ssa_name_symbol (partition_to_var (map, p3), root1);
/* Update the various flag widgitry of the current base representative. */
ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
@@ -359,7 +368,7 @@ rename_ssa_copies (void)
fprintf (debug, "\n");
}
}
- SSA_NAME_VAR (var) = SSA_NAME_VAR (part_var);
+ replace_ssa_name_symbol (var, SSA_NAME_VAR (part_var));
}
delete_var_map (map);
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 6e92597f511..27b3a5b1bf0 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -118,6 +118,12 @@ verify_ssa_name (tree ssa_name, bool is_virtual)
return true;
}
+ if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
+ {
+ error ("Type mismatch between an SSA_NAME and its symbol.");
+ return true;
+ }
+
if (SSA_NAME_IN_FREE_LIST (ssa_name))
{
error ("Found an SSA_NAME that had been released into the free pool");
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 2785e530b3c..4e8985a4b21 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -249,4 +249,14 @@ release_defs (tree stmt)
release_ssa_name (V_MUST_DEF_OP (v_must_defs, i));
}
+
+/* Replace the symbol associated with SSA_NAME with SYM. */
+
+void
+replace_ssa_name_symbol (tree ssa_name, tree sym)
+{
+ SSA_NAME_VAR (ssa_name) = sym;
+ TREE_TYPE (ssa_name) = TREE_TYPE (sym);
+}
+
#include "gt-tree-ssanames.h"
diff --git a/gcc/tree.h b/gcc/tree.h
index 1962d72dff5..a5c0a2c2ad6 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2648,6 +2648,7 @@ extern tree make_ssa_name (tree, tree);
extern tree duplicate_ssa_name (tree, tree);
extern void release_ssa_name (tree);
extern void release_defs (tree);
+extern void replace_ssa_name_symbol (tree, tree);
#ifdef GATHER_STATISTICS
extern void ssanames_print_statistics (void);