aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-sccvn.cc')
-rw-r--r--gcc/tree-ssa-sccvn.cc78
1 files changed, 73 insertions, 5 deletions
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 00315d1..3884f0f 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -3573,7 +3573,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
try finding a match in one of the outer components and continue
stripping there. This happens when addresses of components get
forwarded into dereferences. */
- if (j > 0)
+ if (i > 0)
{
int temi = i - 1;
extra_off = vr->operands[i].off;
@@ -3598,7 +3598,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
temi--;
}
}
- if (!found && i > 0)
+ if (!found && j > 0)
{
int temj = j - 1;
extra_off = -lhs_ops[j].off;
@@ -3631,7 +3631,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
{
extra_off = vr->operands[i].off - lhs_ops[j].off;
i--, j--;
+ found = true;
}
+ /* If we did find a match we'd eventually append a MEM_REF
+ as component. Don't. */
+ if (!found)
+ return (void *)-1;
}
else
return (void *)-1;
@@ -3645,6 +3650,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
j--;
}
+ /* When we still didn't manage to strip off all components from
+ lhs_op, opportunistically continue for those we can handle
+ via extra_off. Note this is an attempt to fixup secondary
+ copies after we hit the !found && j == 0 case above. */
+ while (j != -1
+ && known_ne (lhs_ops[j].off, -1U))
+ {
+ extra_off += -lhs_ops[j].off;
+ j--;
+ }
+
/* i now points to the first additional op.
??? LHS may not be completely contained in VR, one or more
VIEW_CONVERT_EXPRs could be in its way. We could at least
@@ -5577,7 +5593,8 @@ visit_nary_op (tree lhs, gassign *stmt)
if (result)
{
bool changed = set_ssa_val_to (lhs, result);
- vn_nary_op_insert_stmt (stmt, result);
+ if (TREE_CODE (result) == SSA_NAME)
+ vn_nary_op_insert_stmt (stmt, result);
return changed;
}
}
@@ -5593,7 +5610,8 @@ visit_nary_op (tree lhs, gassign *stmt)
if (result)
{
bool changed = set_ssa_val_to (lhs, result);
- vn_nary_op_insert_stmt (stmt, result);
+ if (TREE_CODE (result) == SSA_NAME)
+ vn_nary_op_insert_stmt (stmt, result);
return changed;
}
}
@@ -5633,6 +5651,55 @@ visit_nary_op (tree lhs, gassign *stmt)
}
}
break;
+ case BIT_FIELD_REF:
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+ {
+ tree op0 = TREE_OPERAND (rhs1, 0);
+ gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0));
+ if (ass
+ && !gimple_has_volatile_ops (ass)
+ && vn_get_stmt_kind (ass) == VN_REFERENCE)
+ {
+ tree last_vuse = gimple_vuse (ass);
+ tree op = gimple_assign_rhs1 (ass);
+ /* Avoid building invalid and unexpected refs. */
+ if (TREE_CODE (op) != TARGET_MEM_REF
+ && TREE_CODE (op) != BIT_FIELD_REF
+ && TREE_CODE (op) != REALPART_EXPR
+ && TREE_CODE (op) != IMAGPART_EXPR)
+ {
+ tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1),
+ gimple_assign_rhs1 (ass),
+ TREE_OPERAND (rhs1, 1),
+ TREE_OPERAND (rhs1, 2));
+ tree result = vn_reference_lookup (op, gimple_vuse (ass),
+ default_vn_walk_kind,
+ NULL, true, &last_vuse);
+ if (result
+ && useless_type_conversion_p (type, TREE_TYPE (result)))
+ return set_ssa_val_to (lhs, result);
+ else if (result
+ && TYPE_SIZE (type)
+ && TYPE_SIZE (TREE_TYPE (result))
+ && operand_equal_p (TYPE_SIZE (type),
+ TYPE_SIZE (TREE_TYPE (result))))
+ {
+ gimple_match_op match_op (gimple_match_cond::UNCOND,
+ VIEW_CONVERT_EXPR,
+ type, result);
+ result = vn_nary_build_or_lookup (&match_op);
+ if (result)
+ {
+ bool changed = set_ssa_val_to (lhs, result);
+ if (TREE_CODE (result) == SSA_NAME)
+ vn_nary_op_insert_stmt (stmt, result);
+ return changed;
+ }
+ }
+ }
+ }
+ }
+ break;
case TRUNC_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;
@@ -5663,7 +5730,8 @@ visit_nary_op (tree lhs, gassign *stmt)
if (result)
{
bool changed = set_ssa_val_to (lhs, result);
- vn_nary_op_insert_stmt (stmt, result);
+ if (TREE_CODE (result) == SSA_NAME)
+ vn_nary_op_insert_stmt (stmt, result);
return changed;
}
}