From: Richard Sandiford Date: Wed, 30 May 2018 06:31:47 +0000 (+0000) Subject: Use poly_int tree accessors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6e246559b842b9fc561f5ce6eefa08912dd4f7fd;p=gcc.git Use poly_int tree accessors This patch generalises various places that used hwi tree accessors so that they can handle poly_ints instead. In many cases these changes are by inspection rather than because something had shown them to be necessary. I think the alias.c part is a minor bug fix: previously we used fits_uhwi_p for a signed HOST_WIDE_INT (which the caller does treat as signed rather than unsigned). We also checked whether each individual offset overflowed but didn't check whether the sum did. 2018-05-30 Richard Sandiford gcc/ * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p and wi::to_poly_offset. Add the current offset and then check whether the sum fits, rather than using an unchecked addition of a checked term. Check for a shwi rather than a uhwi. * expr.c (get_bit_range): Use tree_to_poly_uint64. (store_constructor): Use poly_int_tree_p. (expand_expr_real_1): Likewise. * function.c (assign_temp): Likewise. * fold-const.c (const_binop): Use poly_int_tree_p and wi::to_poly_offset. (fold_indirect_ref_1): Likewise. Use multiple_p to attempt an exact division. * ipa-icf-gimple.c (func_checker::compare_operand): Use to_poly_offset for MEM offsets. * ipa-icf.c (sem_variable::equals): Likewise. * stor-layout.c (compute_record_mode): Use poly_int_tree_p. * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use wi::to_poly_offset for BIT_FIELD_REF offsets. (vn_reference_maybe_forwprop_address): Use poly_int_tree_p and wi::to_poly_offset. * var-tracking.c (emit_note_insn_var_location): Use tree_to_poly_uint64. From-SVN: r260914 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9d89aa1754..51958e8c3b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2018-05-30 Richard Sandiford + + * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p + and wi::to_poly_offset. Add the current offset and then check + whether the sum fits, rather than using an unchecked addition of + a checked term. Check for a shwi rather than a uhwi. + * expr.c (get_bit_range): Use tree_to_poly_uint64. + (store_constructor): Use poly_int_tree_p. + (expand_expr_real_1): Likewise. + * function.c (assign_temp): Likewise. + * fold-const.c (const_binop): Use poly_int_tree_p and + wi::to_poly_offset. + (fold_indirect_ref_1): Likewise. Use multiple_p to attempt an exact + division. + * ipa-icf-gimple.c (func_checker::compare_operand): Use + to_poly_offset for MEM offsets. + * ipa-icf.c (sem_variable::equals): Likewise. + * stor-layout.c (compute_record_mode): Use poly_int_tree_p. + * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use + wi::to_poly_offset for BIT_FIELD_REF offsets. + (vn_reference_maybe_forwprop_address): Use poly_int_tree_p and + wi::to_poly_offset. + * var-tracking.c (emit_note_insn_var_location): Use + tree_to_poly_uint64. + 2018-05-29 Jim Wilson * config/riscv/riscv.c (riscv_interrupt_type): Fix comment typo. diff --git a/gcc/alias.c b/gcc/alias.c index 74032f8503b..40c74a07a46 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -2698,22 +2698,22 @@ adjust_offset_for_component_ref (tree x, bool *known_p, { tree xoffset = component_ref_field_offset (x); tree field = TREE_OPERAND (x, 1); - if (TREE_CODE (xoffset) != INTEGER_CST) + if (!poly_int_tree_p (xoffset)) { *known_p = false; return; } - offset_int woffset - = (wi::to_offset (xoffset) + poly_offset_int woffset + = (wi::to_poly_offset (xoffset) + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)) - >> LOG2_BITS_PER_UNIT)); - if (!wi::fits_uhwi_p (woffset)) + >> LOG2_BITS_PER_UNIT) + + *offset); + if (!woffset.to_shwi (offset)) { *known_p = false; return; } - *offset += woffset.to_uhwi (); x = TREE_OPERAND (x, 0); } diff --git a/gcc/expr.c b/gcc/expr.c index 51fbc326000..1fa32275fdf 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4913,7 +4913,7 @@ get_bit_range (poly_uint64_pod *bitstart, poly_uint64_pod *bitend, tree exp, else *bitstart = *bitpos - bitoffset; - *bitend = *bitstart + tree_to_uhwi (DECL_SIZE (repr)) - 1; + *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1; } /* Returns true if ADDR is an ADDR_EXPR of a DECL that does not reside @@ -6521,12 +6521,10 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, continue; mode = TYPE_MODE (elttype); - if (mode == BLKmode) - bitsize = (tree_fits_uhwi_p (TYPE_SIZE (elttype)) - ? tree_to_uhwi (TYPE_SIZE (elttype)) - : -1); - else + if (mode != BLKmode) bitsize = GET_MODE_BITSIZE (mode); + else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize)) + bitsize = -1; if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR) { @@ -10249,11 +10247,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { poly_int64 offset = mem_ref_offset (exp).force_shwi (); base = TREE_OPERAND (base, 0); + poly_uint64 type_size; if (known_eq (offset, 0) && !reverse - && tree_fits_uhwi_p (TYPE_SIZE (type)) - && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), - tree_to_uhwi (TYPE_SIZE (type)))) + && poly_int_tree_p (TYPE_SIZE (type), &type_size) + && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size)) return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base), target, tmode, modifier); if (TYPE_MODE (type) == BLKmode) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3258aad44be..6f80f1b1d69 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1611,10 +1611,10 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) return NULL_TREE; case POINTER_DIFF_EXPR: - if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST) + if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2)) { - offset_int res = wi::sub (wi::to_offset (arg1), - wi::to_offset (arg2)); + poly_offset_int res = (wi::to_poly_offset (arg1) + - wi::to_poly_offset (arg2)); return force_fit_type (type, res, 1, TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); } @@ -14202,13 +14202,12 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) tree min_val = size_zero_node; if (type_domain && TYPE_MIN_VALUE (type_domain)) min_val = TYPE_MIN_VALUE (type_domain); - offset_int off = wi::to_offset (op01); - offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type)); - offset_int remainder; - off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder); - if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST) + poly_uint64 type_size, index; + if (poly_int_tree_p (min_val) + && poly_int_tree_p (TYPE_SIZE_UNIT (type), &type_size) + && multiple_p (const_op01, type_size, &index)) { - off = off + wi::to_offset (min_val); + poly_offset_int off = index + wi::to_poly_offset (min_val); op01 = wide_int_to_tree (sizetype, off); return build4_loc (loc, ARRAY_REF, type, op00, op01, NULL_TREE, NULL_TREE); diff --git a/gcc/function.c b/gcc/function.c index 61515e38e47..6b9fd597d41 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -978,25 +978,26 @@ assign_temp (tree type_or_decl, int memory_required, if (mode == BLKmode || memory_required) { - HOST_WIDE_INT size = int_size_in_bytes (type); + poly_int64 size; rtx tmp; - /* Zero sized arrays are GNU C extension. Set size to 1 to avoid - problems with allocating the stack space. */ - if (size == 0) - size = 1; - /* Unfortunately, we don't yet know how to allocate variable-sized temporaries. However, sometimes we can find a fixed upper limit on the size, so try that instead. */ - else if (size == -1) + if (!poly_int_tree_p (TYPE_SIZE_UNIT (type), &size)) size = max_int_size_in_bytes (type); + /* Zero sized arrays are a GNU C extension. Set size to 1 to avoid + problems with allocating the stack space. */ + if (known_eq (size, 0)) + size = 1; + /* The size of the temporary may be too large to fit into an integer. */ /* ??? Not sure this should happen except for user silliness, so limit this to things that aren't compiler-generated temporaries. The rest of the time we'll die in assign_stack_temp_for_type. */ - if (decl && size == -1 + if (decl + && !known_size_p (size) && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST) { error ("size of variable %q+D is too large", decl); diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c index 161080c77bc..6a5d1e96941 100644 --- a/gcc/ipa-icf-gimple.c +++ b/gcc/ipa-icf-gimple.c @@ -463,7 +463,7 @@ func_checker::compare_operand (tree t1, tree t2) return return_false_with_msg (""); /* Type of the offset on MEM_REF does not matter. */ - return wi::to_offset (y1) == wi::to_offset (y2); + return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2)); } case COMPONENT_REF: { diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 37e63fc2ba8..5a1e13560d6 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -1983,8 +1983,8 @@ sem_variable::equals (tree t1, tree t2) /* Type of the offset on MEM_REF does not matter. */ return return_with_debug (sem_variable::equals (x1, x2) - && wi::to_offset (y1) - == wi::to_offset (y2)); + && known_eq (wi::to_poly_offset (y1), + wi::to_poly_offset (y2))); } case ADDR_EXPR: case FDESC_EXPR: diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 81f75a5eb72..dd08165e606 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1838,9 +1838,11 @@ compute_record_mode (tree type) /* If we only have one real field; use its mode if that mode's size matches the type's size. This only applies to RECORD_TYPE. This does not apply to unions. */ - if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode - && tree_fits_uhwi_p (TYPE_SIZE (type)) - && known_eq (GET_MODE_BITSIZE (mode), tree_to_uhwi (TYPE_SIZE (type)))) + poly_uint64 type_size; + if (TREE_CODE (type) == RECORD_TYPE + && mode != VOIDmode + && poly_int_tree_p (TYPE_SIZE (type), &type_size) + && known_eq (GET_MODE_BITSIZE (mode), type_size)) ; else mode = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1).else_blk (); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 62015fda929..4e946ba7baf 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -999,7 +999,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, /* And now the usual component-reference style ops. */ case BIT_FIELD_REF: - offset += wi::to_offset (op->op1); + offset += wi::to_poly_offset (op->op1); break; case COMPONENT_REF: @@ -1265,10 +1265,10 @@ vn_reference_maybe_forwprop_address (vec *ops, ptroff = gimple_assign_rhs2 (def_stmt); if (TREE_CODE (ptr) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr) - || TREE_CODE (ptroff) != INTEGER_CST) + || !poly_int_tree_p (ptroff)) return false; - off += wi::to_offset (ptroff); + off += wi::to_poly_offset (ptroff); op->op0 = ptr; } diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 2b21da3dfce..16e1ea8f997 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -8665,7 +8665,6 @@ emit_note_insn_var_location (variable **varp, emit_note_data *data) bool complete; enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED; HOST_WIDE_INT last_limit; - tree type_size_unit; HOST_WIDE_INT offsets[MAX_VAR_PARTS]; rtx loc[MAX_VAR_PARTS]; tree decl; @@ -8816,8 +8815,9 @@ emit_note_insn_var_location (variable **varp, emit_note_data *data) } ++n_var_parts; } - type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl)); - if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit)) + poly_uint64 type_size_unit + = tree_to_poly_uint64 (TYPE_SIZE_UNIT (TREE_TYPE (decl))); + if (maybe_lt (poly_uint64 (last_limit), type_size_unit)) complete = false; if (! flag_var_tracking_uninit)