aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 669d0b1..a6ee501 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3037,6 +3037,73 @@ set_ssa_val_to (tree from, tree to)
== get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
&& coff == toff))
{
+ /* If we equate two SSA names we have to make the side-band info
+ of the leader conservative (and remember whatever original value
+ was present). */
+ if (TREE_CODE (to) == SSA_NAME)
+ {
+ if (INTEGRAL_TYPE_P (TREE_TYPE (to))
+ && SSA_NAME_RANGE_INFO (to))
+ {
+ if (SSA_NAME_IS_DEFAULT_DEF (to)
+ || dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (from)),
+ gimple_bb (SSA_NAME_DEF_STMT (to))))
+ /* Keep the info from the dominator. */
+ ;
+ else if (SSA_NAME_IS_DEFAULT_DEF (from)
+ || dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (to)),
+ gimple_bb (SSA_NAME_DEF_STMT (from))))
+ {
+ /* Save old info. */
+ if (! VN_INFO (to)->info.range_info)
+ VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to);
+ /* Use that from the dominator. */
+ SSA_NAME_RANGE_INFO (to) = SSA_NAME_RANGE_INFO (from);
+ }
+ else
+ {
+ /* Save old info. */
+ if (! VN_INFO (to)->info.range_info)
+ VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to);
+ /* Rather than allocating memory and unioning the info
+ just clear it. */
+ SSA_NAME_RANGE_INFO (to) = NULL;
+ }
+ }
+ else if (POINTER_TYPE_P (TREE_TYPE (to))
+ && SSA_NAME_PTR_INFO (to))
+ {
+ if (SSA_NAME_IS_DEFAULT_DEF (to)
+ || dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (from)),
+ gimple_bb (SSA_NAME_DEF_STMT (to))))
+ /* Keep the info from the dominator. */
+ ;
+ else if (SSA_NAME_IS_DEFAULT_DEF (from)
+ || dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (to)),
+ gimple_bb (SSA_NAME_DEF_STMT (from))))
+ {
+ /* Save old info. */
+ if (! VN_INFO (to)->info.ptr_info)
+ VN_INFO (to)->info.ptr_info = SSA_NAME_PTR_INFO (to);
+ /* Use that from the dominator. */
+ SSA_NAME_PTR_INFO (to) = SSA_NAME_PTR_INFO (from);
+ }
+ else
+ {
+ /* Save old info. */
+ if (! VN_INFO (to)->info.ptr_info)
+ VN_INFO (to)->info.ptr_info = SSA_NAME_PTR_INFO (to);
+ /* Rather than allocating memory and unioning the info
+ just clear it. */
+ SSA_NAME_PTR_INFO (to) = NULL;
+ }
+ }
+ }
+
VN_INFO (from)->valnum = to;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " (changed)\n");
@@ -4152,9 +4219,17 @@ free_scc_vn (void)
{
tree name = ssa_name (i);
if (name
- && has_VN_INFO (name)
- && VN_INFO (name)->needs_insertion)
- release_ssa_name (name);
+ && has_VN_INFO (name))
+ {
+ if (VN_INFO (name)->needs_insertion)
+ release_ssa_name (name);
+ else if (POINTER_TYPE_P (TREE_TYPE (name))
+ && VN_INFO (name)->info.ptr_info)
+ SSA_NAME_PTR_INFO (name) = VN_INFO (name)->info.ptr_info;
+ else if (INTEGRAL_TYPE_P (TREE_TYPE (name))
+ && VN_INFO (name)->info.range_info)
+ SSA_NAME_RANGE_INFO (name) = VN_INFO (name)->info.range_info;
+ }
}
obstack_free (&vn_ssa_aux_obstack, NULL);
vn_ssa_aux_table.release ();