diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-20 12:55:27 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-20 12:55:27 +0000 |
commit | 588db50c8cf2c2ea081b2be7c1c3bc5452cdef20 (patch) | |
tree | 3ba8f3c264cdf88b5f924b21cfa9f2ac097744d5 /gcc/ipa-polymorphic-call.c | |
parent | 80d0198b739660305da17e12072578b7a99cb777 (diff) | |
download | gcc-588db50c8cf2c2ea081b2be7c1c3bc5452cdef20.zip gcc-588db50c8cf2c2ea081b2be7c1c3bc5452cdef20.tar.gz gcc-588db50c8cf2c2ea081b2be7c1c3bc5452cdef20.tar.bz2 |
poly_int: get_ref_base_and_extent
This patch changes the types of the bit offsets and sizes returned
by get_ref_base_and_extent to poly_int64.
There are some callers that can't sensibly operate on polynomial
offsets or handle cases where the offset and size aren't known
exactly. This includes the IPA devirtualisation code (since
there's no defined way of having vtables at variable offsets)
and some parts of the DWARF code. The patch therefore adds
a helper function get_ref_base_and_extent_hwi that either returns
exact HOST_WIDE_INT bit positions and sizes or returns a null
base to indicate failure.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* tree-dfa.h (get_ref_base_and_extent): Return the base, size and
max_size as poly_int64_pods rather than HOST_WIDE_INTs.
(get_ref_base_and_extent_hwi): Declare.
* tree-dfa.c (get_ref_base_and_extent): Return the base, size and
max_size as poly_int64_pods rather than HOST_WIDE_INTs.
(get_ref_base_and_extent_hwi): New function.
* cfgexpand.c (expand_debug_expr): Update call to
get_ref_base_and_extent.
* dwarf2out.c (add_var_loc_to_decl): Likewise.
* gimple-fold.c (get_base_constructor): Return the offset as a
poly_int64_pod rather than a HOST_WIDE_INT.
(fold_const_aggregate_ref_1): Track polynomial sizes and offsets.
* ipa-polymorphic-call.c
(ipa_polymorphic_call_context::set_by_invariant)
(extr_type_from_vtbl_ptr_store): Track polynomial offsets.
(ipa_polymorphic_call_context::ipa_polymorphic_call_context)
(check_stmt_for_type_change): Use get_ref_base_and_extent_hwi
rather than get_ref_base_and_extent.
(ipa_polymorphic_call_context::get_dynamic_type): Likewise.
* ipa-prop.c (ipa_load_from_parm_agg, compute_complex_assign_jump_func)
(get_ancestor_addr_info, determine_locally_known_aggregate_parts):
Likewise.
* ipa-param-manipulation.c (ipa_get_adjustment_candidate): Update
call to get_ref_base_and_extent.
* tree-sra.c (create_access, get_access_for_expr): Likewise.
* tree-ssa-alias.c (ao_ref_base, aliasing_component_refs_p)
(stmt_kills_ref_p): Likewise.
* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.
* tree-ssa-scopedtables.c (avail_expr_hash, equal_mem_array_ref_p):
Likewise.
* tree-ssa-sccvn.c (vn_reference_lookup_3): Likewise.
Use get_ref_base_and_extent_hwi rather than get_ref_base_and_extent
when calling native_encode_expr.
* tree-ssa-structalias.c (get_constraint_for_component_ref): Update
call to get_ref_base_and_extent.
(do_structure_copy): Use get_ref_base_and_extent_hwi rather than
get_ref_base_and_extent.
* var-tracking.c (track_expr_p): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255886
Diffstat (limited to 'gcc/ipa-polymorphic-call.c')
-rw-r--r-- | gcc/ipa-polymorphic-call.c | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 2978fa3..21ae70b 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -759,7 +759,7 @@ ipa_polymorphic_call_context::set_by_invariant (tree cst, tree otr_type, HOST_WIDE_INT off) { - HOST_WIDE_INT offset2, size, max_size; + poly_int64 offset2, size, max_size; bool reverse; tree base; @@ -772,7 +772,7 @@ ipa_polymorphic_call_context::set_by_invariant (tree cst, cst = TREE_OPERAND (cst, 0); base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse); - if (!DECL_P (base) || max_size == -1 || max_size != size) + if (!DECL_P (base) || !known_size_p (max_size) || maybe_ne (max_size, size)) return false; /* Only type inconsistent programs can have otr_type that is @@ -899,23 +899,21 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, base_pointer = walk_ssa_copies (base_pointer, &visited); if (TREE_CODE (base_pointer) == ADDR_EXPR) { - HOST_WIDE_INT size, max_size; - HOST_WIDE_INT offset2; + HOST_WIDE_INT offset2, size; bool reverse; tree base - = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0), - &offset2, &size, &max_size, &reverse); + = get_ref_base_and_extent_hwi (TREE_OPERAND (base_pointer, 0), + &offset2, &size, &reverse); + if (!base) + break; - if (max_size != -1 && max_size == size) - combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)), - offset + offset2, - true, - NULL /* Do not change outer type. */); + combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)), + offset + offset2, + true, + NULL /* Do not change outer type. */); /* If this is a varying address, punt. */ - if ((TREE_CODE (base) == MEM_REF || DECL_P (base)) - && max_size != -1 - && max_size == size) + if (TREE_CODE (base) == MEM_REF || DECL_P (base)) { /* We found dereference of a pointer. Type of the pointer and MEM_REF is meaningless, but we can look futher. */ @@ -1181,7 +1179,7 @@ static tree extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci, HOST_WIDE_INT *type_offset) { - HOST_WIDE_INT offset, size, max_size; + poly_int64 offset, size, max_size; tree lhs, rhs, base; bool reverse; @@ -1263,17 +1261,23 @@ extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci, } return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE; } - if (offset != tci->offset - || size != POINTER_SIZE - || max_size != POINTER_SIZE) + if (maybe_ne (offset, tci->offset) + || maybe_ne (size, POINTER_SIZE) + || maybe_ne (max_size, POINTER_SIZE)) { if (dump_file) - fprintf (dump_file, " wrong offset %i!=%i or size %i\n", - (int)offset, (int)tci->offset, (int)size); - return offset + POINTER_SIZE <= tci->offset - || (max_size != -1 - && tci->offset + POINTER_SIZE > offset + max_size) - ? error_mark_node : NULL; + { + fprintf (dump_file, " wrong offset "); + print_dec (offset, dump_file); + fprintf (dump_file, "!=%i or size ", (int) tci->offset); + print_dec (size, dump_file); + fprintf (dump_file, "\n"); + } + return (known_le (offset + POINTER_SIZE, tci->offset) + || (known_size_p (max_size) + && known_gt (tci->offset + POINTER_SIZE, + offset + max_size)) + ? error_mark_node : NULL); } } @@ -1403,7 +1407,7 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data) { tree op = walk_ssa_copies (gimple_call_arg (stmt, 0)); tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); - HOST_WIDE_INT offset = 0, size, max_size; + HOST_WIDE_INT offset = 0; bool reverse; if (dump_file) @@ -1415,14 +1419,15 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data) /* See if THIS parameter seems like instance pointer. */ if (TREE_CODE (op) == ADDR_EXPR) { - op = get_ref_base_and_extent (TREE_OPERAND (op, 0), &offset, - &size, &max_size, &reverse); - if (size != max_size || max_size == -1) + HOST_WIDE_INT size; + op = get_ref_base_and_extent_hwi (TREE_OPERAND (op, 0), + &offset, &size, &reverse); + if (!op) { tci->speculative++; return csftc_abort_walking_p (tci->speculative); } - if (op && TREE_CODE (op) == MEM_REF) + if (TREE_CODE (op) == MEM_REF) { if (!tree_fits_shwi_p (TREE_OPERAND (op, 1))) { @@ -1578,7 +1583,6 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance, if (gimple_code (call) == GIMPLE_CALL) { tree ref = gimple_call_fn (call); - HOST_WIDE_INT offset2, size, max_size; bool reverse; if (TREE_CODE (ref) == OBJ_TYPE_REF) @@ -1608,10 +1612,11 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance, && !SSA_NAME_IS_DEFAULT_DEF (ref) && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))) { + HOST_WIDE_INT offset2, size; tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref)); tree base_ref - = get_ref_base_and_extent (ref_exp, &offset2, &size, - &max_size, &reverse); + = get_ref_base_and_extent_hwi (ref_exp, &offset2, + &size, &reverse); /* Finally verify that what we found looks like read from OTR_OBJECT or from INSTANCE with offset OFFSET. */ |