+2018-05-30 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * 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 <jimw@sifive.com>
* config/riscv/riscv.c (riscv_interrupt_type): Fix comment typo.
{
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);
}
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
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)
{
{
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)
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));
}
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);
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);
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:
{
/* 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:
/* 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 ();
/* 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:
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;
}
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;
}
++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)