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.cc81
1 files changed, 39 insertions, 42 deletions
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 481ab8b..f7f50c3 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -3998,6 +3998,41 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set,
return NULL_TREE;
}
+/* When OPERANDS is an ADDR_EXPR that can be possibly expressed as a
+ POINTER_PLUS_EXPR return true and fill in its operands in OPS. */
+
+bool
+vn_pp_nary_for_addr (const vec<vn_reference_op_s>& operands, tree ops[2])
+{
+ gcc_assert (operands[0].opcode == ADDR_EXPR
+ && operands.last ().opcode == SSA_NAME);
+ poly_int64 off = 0;
+ vn_reference_op_t vro;
+ unsigned i;
+ for (i = 1; operands.iterate (i, &vro); ++i)
+ {
+ if (vro->opcode == SSA_NAME)
+ break;
+ else if (known_eq (vro->off, -1))
+ break;
+ off += vro->off;
+ }
+ if (i == operands.length () - 1
+ && maybe_ne (off, 0)
+ /* Make sure we the offset we accumulated in a 64bit int
+ fits the address computation carried out in target
+ offset precision. */
+ && (off.coeffs[0]
+ == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
+ {
+ gcc_assert (operands[i-1].opcode == MEM_REF);
+ ops[0] = operands[i].op0;
+ ops[1] = wide_int_to_tree (sizetype, off);
+ return true;
+ }
+ return false;
+}
+
/* Lookup OP in the current hash table, and return the resulting value
number if it exists in the hash table. Return NULL_TREE if it does
not exist in the hash table or if the result field of the structure
@@ -4034,28 +4069,9 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
&& operands[0].opcode == ADDR_EXPR
&& operands.last ().opcode == SSA_NAME)
{
- poly_int64 off = 0;
- vn_reference_op_t vro;
- unsigned i;
- for (i = 1; operands.iterate (i, &vro); ++i)
+ tree ops[2];
+ if (vn_pp_nary_for_addr (operands, ops))
{
- if (vro->opcode == SSA_NAME)
- break;
- else if (known_eq (vro->off, -1))
- break;
- off += vro->off;
- }
- if (i == operands.length () - 1
- /* Make sure we the offset we accumulated in a 64bit int
- fits the address computation carried out in target
- offset precision. */
- && (off.coeffs[0]
- == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
- {
- gcc_assert (operands[i-1].opcode == MEM_REF);
- tree ops[2];
- ops[0] = operands[i].op0;
- ops[1] = wide_int_to_tree (sizetype, off);
tree res = vn_nary_op_lookup_pieces (2, POINTER_PLUS_EXPR,
TREE_TYPE (op), ops, NULL);
if (res)
@@ -4178,28 +4194,9 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
&& operands[0].opcode == ADDR_EXPR
&& operands.last ().opcode == SSA_NAME)
{
- poly_int64 off = 0;
- vn_reference_op_t vro;
- unsigned i;
- for (i = 1; operands.iterate (i, &vro); ++i)
+ tree ops[2];
+ if (vn_pp_nary_for_addr (operands, ops))
{
- if (vro->opcode == SSA_NAME)
- break;
- else if (known_eq (vro->off, -1))
- break;
- off += vro->off;
- }
- if (i == operands.length () - 1
- /* Make sure we the offset we accumulated in a 64bit int
- fits the address computation carried out in target
- offset precision. */
- && (off.coeffs[0]
- == sext_hwi (off.coeffs[0], TYPE_PRECISION (sizetype))))
- {
- gcc_assert (operands[i-1].opcode == MEM_REF);
- tree ops[2];
- ops[0] = operands[i].op0;
- ops[1] = wide_int_to_tree (sizetype, off);
vn_nary_op_insert_pieces (2, POINTER_PLUS_EXPR,
TREE_TYPE (op), ops, result,
VN_INFO (result)->value_id);