This patch makes ivopts handle polynomial address offsets
when recording potential IV uses.
2017-10-23 Richard Sandiford
Alan Hayward
David Sherwood
gcc/
* tree-ssa-loop-ivopts.c (iv_use::addr_offset): Change from
an unsigned HOST_WIDE_INT to a poly_uint64_pod.
(group_compare_offset): Update accordingly.
(split_small_address_groups_p): Likewise.
(record_use): Take addr_offset as a poly_uint64 rather than
an unsigned HOST_WIDE_INT.
(strip_offset): Return the offset as a poly_uint64 rather than
an unsigned HOST_WIDE_INT.
(record_group_use, split_address_groups): Track polynomial offsets.
(add_iv_candidate_for_use): Likewise.
(addr_offset_valid_p): Take the offset as a poly_int64 rather
than a HOST_WIDE_INT.
(strip_offset_1): Return the offset as a poly_int64 rather than
a HOST_WIDE_INT.
Index: gcc/tree-ssa-loop-ivopts.c
===
--- gcc/tree-ssa-loop-ivopts.c 2017-10-23 17:17:03.208794553 +0100
+++ gcc/tree-ssa-loop-ivopts.c 2017-10-23 17:22:22.298641645 +0100
@@ -367,7 +367,7 @@ struct iv_use
tree *op_p; /* The place where it occurs. */
tree addr_base; /* Base address with const offset stripped. */
- unsigned HOST_WIDE_INT addr_offset;
+ poly_uint64_pod addr_offset;
/* Const offset stripped from base address. */
};
@@ -1508,7 +1508,7 @@ find_induction_variables (struct ivopts_
static struct iv_use *
record_use (struct iv_group *group, tree *use_p, struct iv *iv,
gimple *stmt, enum use_type type, tree addr_base,
- unsigned HOST_WIDE_INT addr_offset)
+ poly_uint64 addr_offset)
{
struct iv_use *use = XCNEW (struct iv_use);
@@ -1553,7 +1553,7 @@ record_invariant (struct ivopts_data *da
}
static tree
-strip_offset (tree expr, unsigned HOST_WIDE_INT *offset);
+strip_offset (tree expr, poly_uint64 *offset);
/* Record a group of TYPE. */
@@ -1580,7 +1580,7 @@ record_group_use (struct ivopts_data *da
{
tree addr_base = NULL;
struct iv_group *group = NULL;
- unsigned HOST_WIDE_INT addr_offset = 0;
+ poly_uint64 addr_offset = 0;
/* Record non address type use in a new group. */
if (type == USE_ADDRESS && iv->base_object)
@@ -2514,7 +2514,7 @@ find_interesting_uses_outside (struct iv
static GTY (()) vec *addr_list;
static bool
-addr_offset_valid_p (struct iv_use *use, HOST_WIDE_INT offset)
+addr_offset_valid_p (struct iv_use *use, poly_int64 offset)
{
rtx reg, addr;
unsigned list_index;
@@ -2548,10 +2548,7 @@ group_compare_offset (const void *a, con
const struct iv_use *const *u1 = (const struct iv_use *const *) a;
const struct iv_use *const *u2 = (const struct iv_use *const *) b;
- if ((*u1)->addr_offset != (*u2)->addr_offset)
-return (*u1)->addr_offset < (*u2)->addr_offset ? -1 : 1;
- else
-return 0;
+ return compare_sizes_for_sort ((*u1)->addr_offset, (*u2)->addr_offset);
}
/* Check if small groups should be split. Return true if no group
@@ -2582,7 +2579,8 @@ split_small_address_groups_p (struct ivo
gcc_assert (group->type == USE_ADDRESS);
if (group->vuses.length () == 2)
{
- if (group->vuses[0]->addr_offset > group->vuses[1]->addr_offset)
+ if (compare_sizes_for_sort (group->vuses[0]->addr_offset,
+ group->vuses[1]->addr_offset) > 0)
std::swap (group->vuses[0], group->vuses[1]);
}
else
@@ -2594,7 +2592,7 @@ split_small_address_groups_p (struct ivo
distinct = 1;
for (pre = group->vuses[0], j = 1; j < group->vuses.length (); j++)
{
- if (group->vuses[j]->addr_offset != pre->addr_offset)
+ if (may_ne (group->vuses[j]->addr_offset, pre->addr_offset))
{
pre = group->vuses[j];
distinct++;
@@ -2635,13 +2633,13 @@ split_address_groups (struct ivopts_data
for (j = 1; j < group->vuses.length ();)
{
struct iv_use *next = group->vuses[j];
- HOST_WIDE_INT offset = next->addr_offset - use->addr_offset;
+ poly_int64 offset = next->addr_offset - use->addr_offset;
/* Split group if aksed to, or the offset against the first
use can't fit in offset part of addressing mode. IV uses
having the same offset are still kept in one group. */
- if (offset != 0 &&
- (split_p || !addr_offset_valid_p (use, offset)))
+ if (maybe_nonzero (offset)
+ && (split_p || !addr_offset_valid_p (use, offset)))
{
if (!new_group)
new_group = record_group (data, group->type);
@@ -2702,12 +2700,13 @@ find_interesting_uses (struct ivopts_dat
static tree
strip_offset_1 (tree