enum tree_code, tree, tree *);
static tree vn_lookup_simplify_result (gimple_match_op *);
static vn_reference_t vn_reference_lookup_or_insert_for_pieces
- (tree, alias_set_type, alias_set_type, tree,
+ (tree, alias_set_type, alias_set_type, poly_int64, poly_int64, tree,
vec<vn_reference_op_s, va_heap>, tree);
/* Return whether there is value numbering information for a given SSA name. */
vn_reference_op_compute_hash (vro, hstate);
}
}
+ /* Do not hash vr1->offset or vr1->max_size, we want to get collisions
+ to be able to identify compatible results. */
result = hstate.end ();
/* ??? We would ICE later if we hash instead of adding that in. */
if (vr1->vuse)
if (vr1->vuse != vr2->vuse)
return false;
+ /* The offset/max_size used for the ao_ref during lookup has to be
+ the same. */
+ if (maybe_ne (vr1->offset, vr2->offset)
+ || maybe_ne (vr1->max_size, vr2->max_size))
+ {
+ /* But nothing known in the prevailing entry is OK to be used. */
+ if (maybe_ne (vr1->offset, 0) || known_size_p (vr1->max_size))
+ return false;
+ }
+
/* If the operands are the same we are done. */
if (vr1->operands == vr2->operands)
return true;
vec<vn_reference_op_s> &operands
= saved_operands.exists () ? saved_operands : vr->operands;
return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
+ vr->offset, vr->max_size,
vr->type, operands, val);
}
vn_reference_lookup_or_insert_for_pieces (tree vuse,
alias_set_type set,
alias_set_type base_set,
+ poly_int64 offset,
+ poly_int64 max_size,
tree type,
vec<vn_reference_op_s,
va_heap> operands,
vr1.type = type;
vr1.set = set;
vr1.base_set = base_set;
+ vr1.offset = offset;
+ vr1.max_size = max_size;
vr1.hashcode = vn_reference_compute_hash (&vr1);
if (vn_reference_lookup_1 (&vr1, &result))
return result;
+
if (TREE_CODE (value) == SSA_NAME)
value_id = VN_INFO (value)->value_id;
else
value_id = get_or_alloc_constant_value_id (value);
- return vn_reference_insert_pieces (vuse, set, base_set, type,
- operands.copy (), value, value_id);
+ return vn_reference_insert_pieces (vuse, set, base_set, offset, max_size,
+ type, operands.copy (), value, value_id);
}
/* Return a value-number for RCODE OPS... either by looking up an existing
return (void *)-1;
}
*ref = r;
+ vr->offset = r.offset;
+ vr->max_size = r.max_size;
/* Do not update last seen VUSE after translating. */
data->last_vuse_ptr = NULL;
if (maybe_ne (ref->size, r.size))
return (void *)-1;
*ref = r;
+ vr->offset = r.offset;
+ vr->max_size = r.max_size;
/* Do not update last seen VUSE after translating. */
data->last_vuse_ptr = NULL;
vr1.type = type;
vr1.set = set;
vr1.base_set = base_set;
+ /* We can pretend there's no extra info fed in since the ao_refs offset
+ and max_size are computed only from the VN reference ops. */
+ vr1.offset = 0;
+ vr1.max_size = -1;
vr1.hashcode = vn_reference_compute_hash (&vr1);
if ((cst = fully_constant_vn_reference_p (&vr1)))
return cst;
ao_ref_init (&op_ref, op);
vr1.set = ao_ref_alias_set (&op_ref);
vr1.base_set = ao_ref_base_alias_set (&op_ref);
+ vr1.offset = 0;
+ vr1.max_size = -1;
vr1.hashcode = vn_reference_compute_hash (&vr1);
if (mask == NULL_TREE)
if (tree cst = fully_constant_vn_reference_p (&vr1))
if (!valueized_anything
|| !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
vr1.type, ops_for_ref))
- ao_ref_init (&r, op);
+ {
+ ao_ref_init (&r, op);
+ /* Record the extra info we're getting from the full ref. */
+ ao_ref_base (&r);
+ vr1.offset = r.offset;
+ vr1.max_size = r.max_size;
+ }
vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
last_vuse_ptr, kind, tbaa_p, mask,
redundant_store_removal_p);
vr->punned = false;
vr->set = 0;
vr->base_set = 0;
+ vr->offset = 0;
+ vr->max_size = -1;
vr->hashcode = vn_reference_compute_hash (vr);
vn_reference_lookup_1 (vr, vnresult);
}
ao_ref_init (&op_ref, op);
vr1->set = ao_ref_alias_set (&op_ref);
vr1->base_set = ao_ref_base_alias_set (&op_ref);
+ /* Specifically use an unknown extent here, we're not doing any lookup
+ and assume the caller didn't either (or it went VARYING). */
+ vr1->offset = 0;
+ vr1->max_size = -1;
vr1->hashcode = vn_reference_compute_hash (vr1);
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
vr1->result_vdef = vdef;
vn_reference_t
vn_reference_insert_pieces (tree vuse, alias_set_type set,
- alias_set_type base_set, tree type,
+ alias_set_type base_set,
+ poly_int64 offset, poly_int64 max_size, tree type,
vec<vn_reference_op_s> operands,
tree result, unsigned int value_id)
vr1->punned = false;
vr1->set = set;
vr1->base_set = base_set;
+ vr1->offset = offset;
+ vr1->max_size = max_size;
vr1->hashcode = vn_reference_compute_hash (vr1);
if (result && TREE_CODE (result) == SSA_NAME)
result = SSA_VAL (result);
vr2->type = vr1.type;
vr2->punned = vr1.punned;
vr2->set = vr1.set;
+ vr2->offset = vr1.offset;
+ vr2->max_size = vr1.max_size;
vr2->base_set = vr1.base_set;
vr2->hashcode = vr1.hashcode;
vr2->result = lhs;