aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-05-30 06:31:47 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-05-30 06:31:47 +0000
commit6e246559b842b9fc561f5ce6eefa08912dd4f7fd (patch)
tree34d36011aa1f1b4d6e8fba4506d1fcf929336859
parentbb3976df48aecf734211898d6d954dc8ebed0713 (diff)
downloadgcc-6e246559b842b9fc561f5ce6eefa08912dd4f7fd.zip
gcc-6e246559b842b9fc561f5ce6eefa08912dd4f7fd.tar.gz
gcc-6e246559b842b9fc561f5ce6eefa08912dd4f7fd.tar.bz2
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 <richard.sandiford@linaro.org> 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
-rw-r--r--gcc/ChangeLog25
-rw-r--r--gcc/alias.c12
-rw-r--r--gcc/expr.c16
-rw-r--r--gcc/fold-const.c17
-rw-r--r--gcc/function.c17
-rw-r--r--gcc/ipa-icf-gimple.c2
-rw-r--r--gcc/ipa-icf.c4
-rw-r--r--gcc/stor-layout.c8
-rw-r--r--gcc/tree-ssa-sccvn.c6
-rw-r--r--gcc/var-tracking.c6
10 files changed, 69 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c9d89aa..51958e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,28 @@
+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.
diff --git a/gcc/alias.c b/gcc/alias.c
index 74032f8..40c74a0 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 51fbc32..1fa3227 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 3258aad..6f80f1b 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 61515e3..6b9fd59 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 161080c..6a5d1e9 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 37e63fc..5a1e135 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 81f75a5..dd08165 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 62015fd..4e946ba 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<vn_reference_op_s> *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 2b21da3..16e1ea8 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)