summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-copy.c')
-rw-r--r--gcc/tree-ssa-copy.c83
1 files changed, 51 insertions, 32 deletions
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