}
/* Hash table hash function for vn_constant_t. */
-
+
static hashval_t
vn_constant_hash (const void *p1)
{
{
void **slot;
vn_constant_t vc = XNEW (struct vn_constant_s);
-
+
vc->hashcode = vn_hash_constant_with_type (constant);
vc->constant = constant;
slot = htab_find_slot_with_hash (constant_to_value_id, vc,
- vc->hashcode, INSERT);
+ vc->hashcode, INSERT);
if (*slot)
{
free (vc);
bool
value_id_constant_p (unsigned int v)
{
- return bitmap_bit_p (constant_value_ids, v);
+ return bitmap_bit_p (constant_value_ids, v);
}
/* Compare two reference operands P1 and P2 for equality. Return true if
&& TREE_CODE (DECL_CONTEXT (temp.op0)) == UNION_TYPE
&& integer_zerop (DECL_FIELD_OFFSET (temp.op0))
&& integer_zerop (DECL_FIELD_BIT_OFFSET (temp.op0))
- && host_integerp (TYPE_SIZE (TREE_TYPE (temp.op0)), 0))
- temp.op0 = TYPE_SIZE (TREE_TYPE (temp.op0));
+ && host_integerp (DECL_SIZE (temp.op0), 0))
+ temp.op0 = DECL_SIZE (temp.op0);
break;
case ARRAY_RANGE_REF:
case ARRAY_REF:
/* Record index as operand. */
temp.op0 = TREE_OPERAND (ref, 1);
- /* Record even constant lower bounds. */
- if (TREE_OPERAND (ref, 2))
- temp.op1 = TREE_OPERAND (ref, 2);
- else
- {
- tree domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
- if (domain
- && TYPE_MIN_VALUE (domain)
- && !integer_zerop (TYPE_MIN_VALUE (domain)))
- temp.op1 = TYPE_MIN_VALUE (domain);
- }
- temp.op2 = TREE_OPERAND (ref, 3);
+ /* Always record lower bounds and element size. */
+ temp.op1 = array_ref_low_bound (ref);
+ temp.op2 = array_ref_element_size (ref);
break;
case STRING_CST:
case INTEGER_CST:
case CONST_DECL:
case RESULT_DECL:
case SSA_NAME:
- case EXC_PTR_EXPR:
- case FILTER_EXPR:
temp.op0 = ref;
break;
case ADDR_EXPR:
case PARM_DECL:
case RESULT_DECL:
case SSA_NAME:
- case FILTER_EXPR:
- case EXC_PTR_EXPR:
*op0_p = op->op0;
break;
case ARRAY_RANGE_REF:
case ARRAY_REF:
- /* Same for ARRAY_REFs. We do not have access to the array
- type here, but we recorded the lower bound in op1. */
- if (op->op2
- || !host_integerp (op->op0, 0)
- || (op->op1 && !host_integerp (op->op1, 0))
- || !host_integerp (TYPE_SIZE (op->type), 1))
+ /* We recorded the lower bound and the element size. */
+ if (!host_integerp (op->op0, 0)
+ || !host_integerp (op->op1, 0)
+ || !host_integerp (op->op2, 0))
max_size = -1;
else
{
HOST_WIDE_INT hindex = TREE_INT_CST_LOW (op->op0);
- if (op->op1)
- hindex -= TREE_INT_CST_LOW (op->op1);
- hindex *= TREE_INT_CST_LOW (TYPE_SIZE (op->type));
+ hindex -= TREE_INT_CST_LOW (op->op1);
+ hindex *= TREE_INT_CST_LOW (op->op2);
+ hindex *= BITS_PER_UNIT;
offset += hindex;
}
break;
if ((dom = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (op->op0, 0))))
&& TYPE_MIN_VALUE (dom))
aref.op0 = TYPE_MIN_VALUE (dom);
- aref.op1 = NULL_TREE;
- aref.op2 = NULL_TREE;
+ aref.op1 = aref.op0;
+ aref.op2 = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (op->op0)));
VEC_safe_push (vn_reference_op_s, heap, mem, &aref);
}
copy_reference_ops_from_ref (TREE_OPERAND (op->op0, 0), &mem);
*vnresult = (vn_reference_t)*slot;
return ((vn_reference_t)*slot)->result;
}
-
+
return NULL_TREE;
}
hash, NO_INSERT);
if (slot)
return *slot;
-
+
return NULL;
}
gimple def_stmt = SSA_NAME_DEF_STMT (vuse);
tree fndecl;
tree base;
- HOST_WIDE_INT offset, size, maxsize;
+ HOST_WIDE_INT offset, maxsize;
base = ao_ref_base (ref);
offset = ref->offset;
- size = ref->size;
maxsize = ref->max_size;
/* If we cannot constrain the size of the reference we cannot
copy_reference_ops_from_ref (gimple_assign_lhs (def_stmt), &lhs);
i = VEC_length (vn_reference_op_s, vr->operands) - 1;
j = VEC_length (vn_reference_op_s, lhs) - 1;
- while (j >= 0
+ while (j >= 0 && i >= 0
&& vn_reference_op_eq (VEC_index (vn_reference_op_s,
vr->operands, i),
VEC_index (vn_reference_op_s, lhs, j)))
i--;
j--;
}
+
+ VEC_free (vn_reference_op_s, heap, lhs);
/* 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
try handling outermost VIEW_CONVERT_EXPRs. */
if (j != -1)
return (void *)-1;
- VEC_free (vn_reference_op_s, heap, lhs);
/* Now re-write REF to be based on the rhs of the assignment. */
copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs);
/* Adjust *ref from the new operands. */
if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands))
return (void *)-1;
- gcc_assert (ref->size == r.size);
+ /* This can happen with bitfields. */
+ if (ref->size != r.size)
+ return (void *)-1;
*ref = r;
/* Keep looking for the adjusted *REF / VR pair. */
slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
INSERT);
-
+
/* At this point we should have all the things inserted that we have
seen before, and we should never try inserting something that
already exists. */
/* Compute and return the hash value for nary operation VBO1. */
-inline hashval_t
+hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
hashval_t hash = 0;
tree
vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
tree type, tree op0, tree op1, tree op2,
- tree op3, vn_nary_op_t *vnresult)
+ tree op3, vn_nary_op_t *vnresult)
{
void **slot;
struct vn_nary_op_s vno1;
tree type, tree op0,
tree op1, tree op2, tree op3,
tree result,
- unsigned int value_id)
+ unsigned int value_id)
{
void **slot;
vn_nary_op_t vno1;
*slot = vno1;
return vno1;
-
+
}
/* Insert OP into the current hash table with a value number of
bool changed = false;
tree result = vn_reference_lookup (op, gimple_vuse (stmt), true, NULL);
+ /* If we have a VCE, try looking up its operand as it might be stored in
+ a different type. */
+ if (!result && TREE_CODE (op) == VIEW_CONVERT_EXPR)
+ result = vn_reference_lookup (TREE_OPERAND (op, 0), gimple_vuse (stmt),
+ true, NULL);
+
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
type-mismatch here via creating a VIEW_CONVERT_EXPR. */
sccstack = NULL;
constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq,
free);
-
+
constant_value_ids = BITMAP_ALLOC (NULL);
-
+
next_dfs_num = 1;
next_value_id = 1;
-
+
vn_ssa_aux_table = VEC_alloc (vn_ssa_aux_t, heap, num_ssa_names + 1);
/* VEC_alloc doesn't actually grow it to the right size, it just
preallocates the space to do so. */
table. */
FOR_EACH_HTAB_ELEMENT (valid_info->nary,
- vno, vn_nary_op_t, hi)
+ vno, vn_nary_op_t, hi)
{
if (vno->result)
{
}
FOR_EACH_HTAB_ELEMENT (valid_info->phis,
- vp, vn_phi_t, hi)
+ vp, vn_phi_t, hi)
{
if (vp->result)
{
}
FOR_EACH_HTAB_ELEMENT (valid_info->references,
- vr, vn_reference_t, hi)
+ vr, vn_reference_t, hi)
{
if (vr->result)
{
size_t i;
tree param;
bool changed = true;
-
+
may_insert = may_insert_arg;
init_scc_vn ();
}
/* Initialize the value ids. */
-
+
for (i = 1; i < num_ssa_names; ++i)
{
tree name = ssa_name (i);
else if (is_gimple_min_invariant (info->valnum))
info->value_id = get_or_alloc_constant_value_id (info->valnum);
}
-
+
/* Propagate until they stop changing. */
while (changed)
{
}
}
}
-
+
set_hashtable_value_ids ();
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Value numbers:\n");
/* Return the maximum value id we have ever seen. */
unsigned int
-get_max_value_id (void)
+get_max_value_id (void)
{
return next_value_id;
}