On Wed, May 3, 2017 at 10:49 AM, Richard Biener
<[email protected]> wrote:
> On Tue, May 2, 2017 at 7:06 PM, Bin.Cheng <[email protected]> wrote:
>> On Mon, Apr 24, 2017 at 11:34 AM, Richard Biener
>> <[email protected]> wrote:
>>> On Tue, Apr 18, 2017 at 12:41 PM, Bin Cheng <[email protected]> wrote:
>>>> Hi,
>>>> For now, we check validity of offset by computing the maximum offset then
>>>> checking if
>>>> offset is smaller than the max offset. This is inaccurate, for example,
>>>> some targets
>>>> may require offset to be aligned by power of 2. This patch introduces new
>>>> interface
>>>> checking validity of offset. It also buffers rtx among different calls.
>>>>
>>>> Is it OK?
>>>
>>> - static vec<HOST_WIDE_INT> max_offset_list;
>>> -
>>> + auto_vec<rtx> addr_list;
>>> as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
>>> mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
>>>
>>> - num = max_offset_list.length ();
>>> + num = addr_list.length ();
>>> list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
>>> if (list_index >= num)
>>>
>>> num here is always zero and thus the compare is always true.
>>>
>>> + addr_list.safe_grow_cleared (list_index + MAX_MACHINE_MODE);
>>> + for (; num < addr_list.length (); num++)
>>> + addr_list[num] = NULL;
>>>
>>> the loop is now redundant (safe_grow_cleared)
>>>
>>> + addr = addr_list[list_index];
>>> + if (!addr)
>>> {
>>>
>>> always true again...
>>>
>>> I wonder if you really indented to drop 'static' from addr_list?
>>> There's no caching
>>> across function calls.
>> Right, the redundancy is because I tried to cache across function
>> calls with declarations like:
>> static unsigned num = 0;
>> static GTY ((skip)) rtx *addr_list = NULL;
>> But this doesn't work, the addr_list[list_index] still gets corrupted
>> somehow.
>
> Well, you need GTY (()), not GTY((skip)) on them. Not sure if it works
> for function-scope decls, you have to check. Look at whether a GC
> root is created for the variable in gt-tree-ssa-loop-ivopts.h (need to tweak
> GTFILES in the makefile plus include that generated file). tree-ssa-address.c
> uses a global root for mem_addr_template_list for example.
Thanks for helping, patch updated.
Bootstrap and test on x86_64. Is it OK?
Thanks,
bin
2017-05-02 Bin Cheng <[email protected]>
* Makefile.in (GTFILES): Add tree-ssa-loop-ivopts.c.
* tree-ssa-loop-ivopts.c (compute_max_addr_offset): Delete.
(addr_list, addr_offset_valid_p): New.
(split_address_groups): Check offset validity with above function.
(gt-tree-ssa-loop-ivopts.h): Include.
>>>
>>>
>>>
>>>> Thanks,
>>>> bin
>>>> 2017-04-11 Bin Cheng <[email protected]>
>>>>
>>>> * tree-ssa-loop-ivopts.c (compute_max_addr_offset): Delete.
>>>> (addr_offset_valid_p): New function.
>>>> (split_address_groups): Check offset validity with above function.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2411671..97259ac 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2484,7 +2484,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h
$(srcdir)/coretypes.h \
$(srcdir)/gimple-ssa.h \
$(srcdir)/tree-chkp.c \
$(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
- $(srcdir)/tree-cfg.c \
+ $(srcdir)/tree-cfg.c $(srcdir)/tree-ssa-loop-ivopts.c \
$(srcdir)/tree-dfa.c \
$(srcdir)/tree-iterator.c $(srcdir)/gimple-expr.c \
$(srcdir)/tree-chrec.h \
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 7caa40d..203b272 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2460,67 +2460,36 @@ find_interesting_uses_outside (struct ivopts_data
*data, edge exit)
}
}
-/* Compute maximum offset of [base + offset] addressing mode
- for memory reference represented by USE. */
+/* Return TRUE if OFFSET is within the range of [base + offset] addressing
+ mode for memory reference represented by USE. */
-static HOST_WIDE_INT
-compute_max_addr_offset (struct iv_use *use)
+static GTY (()) vec<rtx, va_gc> *addr_list;
+
+static bool
+addr_offset_valid_p (struct iv_use *use, HOST_WIDE_INT offset)
{
- int width;
rtx reg, addr;
- HOST_WIDE_INT i, off;
- unsigned list_index, num;
- addr_space_t as;
- machine_mode mem_mode, addr_mode;
- static vec<HOST_WIDE_INT> max_offset_list;
-
- as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
- mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
+ unsigned list_index;
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
+ machine_mode addr_mode, mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
- num = max_offset_list.length ();
list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
- if (list_index >= num)
- {
- max_offset_list.safe_grow (list_index + MAX_MACHINE_MODE);
- for (; num < max_offset_list.length (); num++)
- max_offset_list[num] = -1;
- }
+ if (list_index >= vec_safe_length (addr_list))
+ vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE);
- off = max_offset_list[list_index];
- if (off != -1)
- return off;
-
- addr_mode = targetm.addr_space.address_mode (as);
- reg = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
- addr = gen_rtx_fmt_ee (PLUS, addr_mode, reg, NULL_RTX);
-
- width = GET_MODE_BITSIZE (addr_mode) - 1;
- if (width > (HOST_BITS_PER_WIDE_INT - 1))
- width = HOST_BITS_PER_WIDE_INT - 1;
-
- for (i = width; i > 0; i--)
+ addr = (*addr_list)[list_index];
+ if (!addr)
{
- off = (HOST_WIDE_INT_1U << i) - 1;
- XEXP (addr, 1) = gen_int_mode (off, addr_mode);
- if (memory_address_addr_space_p (mem_mode, addr, as))
- break;
-
- /* For some strict-alignment targets, the offset must be naturally
- aligned. Try an aligned offset if mem_mode is not QImode. */
- off = (HOST_WIDE_INT_1U << i);
- if (off > GET_MODE_SIZE (mem_mode) && mem_mode != QImode)
- {
- off -= GET_MODE_SIZE (mem_mode);
- XEXP (addr, 1) = gen_int_mode (off, addr_mode);
- if (memory_address_addr_space_p (mem_mode, addr, as))
- break;
- }
+ addr_mode = targetm.addr_space.address_mode (as);
+ reg = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
+ addr = gen_rtx_fmt_ee (PLUS, addr_mode, reg, NULL_RTX);
+ (*addr_list)[list_index] = addr;
}
- if (i == 0)
- off = 0;
+ else
+ addr_mode = GET_MODE (addr);
- max_offset_list[list_index] = off;
- return off;
+ XEXP (addr, 1) = gen_int_mode (offset, addr_mode);
+ return (memory_address_addr_space_p (mem_mode, addr, as));
}
/* Comparison function to sort group in ascending order of addr_offset. */
@@ -2599,14 +2568,12 @@ static void
split_address_groups (struct ivopts_data *data)
{
unsigned int i, j;
- HOST_WIDE_INT max_offset = -1;
-
- /* Reset max offset to split all small groups. */
- if (split_small_address_groups_p (data))
- max_offset = 0;
+ /* Always split group. */
+ bool split_p = split_small_address_groups_p (data);
for (i = 0; i < data->vgroups.length (); i++)
{
+ struct iv_group *new_group = NULL;
struct iv_group *group = data->vgroups[i];
struct iv_use *use = group->vuses[0];
@@ -2615,29 +2582,29 @@ split_address_groups (struct ivopts_data *data)
if (group->vuses.length () == 1)
continue;
- if (max_offset != 0)
- max_offset = compute_max_addr_offset (use);
+ gcc_assert (group->type == USE_ADDRESS);
- for (j = 1; j < group->vuses.length (); j++)
+ for (j = 1; j < group->vuses.length ();)
{
struct iv_use *next = group->vuses[j];
+ HOST_WIDE_INT offset = next->addr_offset - use->addr_offset;
- /* Only uses with offset that can fit in offset part against
- the first use can be grouped together. */
- if (next->addr_offset - use->addr_offset
- > (unsigned HOST_WIDE_INT) max_offset)
- break;
+ /* 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 (!new_group)
+ new_group = record_group (data, group->type);
+ group->vuses.ordered_remove (j);
+ new_group->vuses.safe_push (next);
+ continue;
+ }
next->id = j;
next->group_id = group->id;
- }
- /* Split group. */
- if (j < group->vuses.length ())
- {
- struct iv_group *new_group = record_group (data, group->type);
- new_group->vuses.safe_splice (group->vuses);
- new_group->vuses.block_remove (0, j);
- group->vuses.truncate (j);
+ j++;
}
}
}
@@ -7854,3 +7821,5 @@ tree_ssa_iv_optimize (void)
tree_ssa_iv_optimize_finalize (&data);
}
+
+#include "gt-tree-ssa-loop-ivopts.h"