diff options
Diffstat (limited to 'gcc/tree-ssa-copy.c')
-rw-r--r-- | gcc/tree-ssa-copy.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 5d96fae..0ddfa9c 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 |