X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-sccvn.c;h=2027357fd6329ba327677cbfe54b8a95b6df0537;hb=b74c019cc5ae3f52f30a39bff4d7a50417bdef74;hp=4ee4e39afcd243bf454aab55db3e45e225e401b0;hpb=3918bd18c71849a8b403e45299f6da682e97705b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 4ee4e39afcd..2027357fd63 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -324,7 +324,7 @@ vn_constant_eq (const void *p1, const void *p2) } /* Hash table hash function for vn_constant_t. */ - + static hashval_t vn_constant_hash (const void *p1) { @@ -358,11 +358,11 @@ get_or_alloc_constant_value_id (tree constant) { 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); @@ -379,7 +379,7 @@ get_or_alloc_constant_value_id (tree constant) 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 @@ -554,25 +554,16 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) && 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: @@ -585,8 +576,6 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) case CONST_DECL: case RESULT_DECL: case SSA_NAME: - case EXC_PTR_EXPR: - case FILTER_EXPR: temp.op0 = ref; break; case ADDR_EXPR: @@ -697,8 +686,6 @@ ao_ref_init_from_vn_reference (ao_ref *ref, case PARM_DECL: case RESULT_DECL: case SSA_NAME: - case FILTER_EXPR: - case EXC_PTR_EXPR: *op0_p = op->op0; break; @@ -731,19 +718,17 @@ ao_ref_init_from_vn_reference (ao_ref *ref, 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; @@ -863,8 +848,8 @@ vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **ops, 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); @@ -995,7 +980,7 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult) *vnresult = (vn_reference_t)*slot; return ((vn_reference_t)*slot)->result; } - + return NULL_TREE; } @@ -1022,7 +1007,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *vr_) hash, NO_INSERT); if (slot) return *slot; - + return NULL; } @@ -1038,11 +1023,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) 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 @@ -1131,7 +1115,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) 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))) @@ -1139,13 +1123,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) 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); @@ -1171,7 +1156,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) /* 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. */ @@ -1348,7 +1335,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type, 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. */ @@ -1362,7 +1349,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type, /* 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; @@ -1429,7 +1416,7 @@ vn_nary_op_eq (const void *p1, const void *p2) 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; @@ -1533,7 +1520,7 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code, 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; @@ -1561,7 +1548,7 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code, *slot = vno1; return vno1; - + } /* Insert OP into the current hash table with a value number of @@ -1976,6 +1963,12 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt) 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. */ @@ -2988,12 +2981,12 @@ init_scc_vn (void) 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. */ @@ -3080,7 +3073,7 @@ set_hashtable_value_ids (void) table. */ FOR_EACH_HTAB_ELEMENT (valid_info->nary, - vno, vn_nary_op_t, hi) + vno, vn_nary_op_t, hi) { if (vno->result) { @@ -3092,7 +3085,7 @@ set_hashtable_value_ids (void) } FOR_EACH_HTAB_ELEMENT (valid_info->phis, - vp, vn_phi_t, hi) + vp, vn_phi_t, hi) { if (vp->result) { @@ -3104,7 +3097,7 @@ set_hashtable_value_ids (void) } FOR_EACH_HTAB_ELEMENT (valid_info->references, - vr, vn_reference_t, hi) + vr, vn_reference_t, hi) { if (vr->result) { @@ -3125,7 +3118,7 @@ run_scc_vn (bool may_insert_arg) size_t i; tree param; bool changed = true; - + may_insert = may_insert_arg; init_scc_vn (); @@ -3157,7 +3150,7 @@ run_scc_vn (bool may_insert_arg) } /* Initialize the value ids. */ - + for (i = 1; i < num_ssa_names; ++i) { tree name = ssa_name (i); @@ -3171,7 +3164,7 @@ run_scc_vn (bool may_insert_arg) 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) { @@ -3192,9 +3185,9 @@ run_scc_vn (bool may_insert_arg) } } } - + set_hashtable_value_ids (); - + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Value numbers:\n"); @@ -3220,7 +3213,7 @@ run_scc_vn (bool may_insert_arg) /* 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; }