On Tue, 2 May 2017, Jakub Jelinek wrote: > On Tue, May 02, 2017 at 01:13:19PM +0200, Richard Biener wrote: > > On Sat, 29 Apr 2017, Jakub Jelinek wrote: > > > > > On Fri, Apr 21, 2017 at 04:42:03PM +0200, Richard Biener wrote: > > > > On April 21, 2017 4:06:59 PM GMT+02:00, Jakub Jelinek > > > > <ja...@redhat.com> wrote: > > > > >This patch attempts to implement the optimization mentioned in > > > > >http://gcc.gnu.org/ml/gcc-patches/2017-02/msg00945.html > > > > >If we know a (relatively small) value range for ARRAY_REF index > > > > >in constant array load and the values in the array for all the indexes > > > > >in the array are the same (and constant), we can just replace the load > > > > >with the constant. > > > > > > > > But this should be done during propagation (and thus can even produce a > > > > range rather than just a constant). > > > > > > True, I've changed the implementation to do that. > > > Except that it is only useful during propagation for integral or pointer > > > types, for anything else (and for pointers when not just doing NULL vs. > > > non-NULL vr) it is also performed during simplification (in that case > > > it requires operand_equal_p values). > > > > > > The patch also newly computes range for the index and range from the array > > > bounds (taking into account arrays at struct end) and intersects them, > > > plus takes into account that some iterators might have a couple of zero > > > LBS > > > bits (as computed by ccp). > > > > Hmm, while I can see how this helps I'd rather not do this in this way. > > (see PR80533 and my followup with a testcase which shows > > array_at_struct_end_p is wrong) Ideally we'd add asserts for array > > indices instead. Thus > > > > i_3 = ASSERT_EXPR <i_2, (unsigned)i_2 <= 3> > > .. = a[i_3]; > > > > which of course needs adjustment to -Warray-bounds to look at the > > range of the original SSA name (and in loops even that might degrade...). > > > > Was this necessary to get any reasonable results? > > Yes, it is very common that you end up with a VR that has negative min, or > very large max, but if the array is in the middle of a struct, or it is a > toplevel non-common array variable etc., which is quite common case, then > we still should be able to optimize it. > Adding extra ASSERT_EXPRs would work too, but wouldn't it be too expensive? > I mean there can be lots of array accesses with the same index, if we'd add > an ASSERT_EXPR for every case, VRP work could increase many times. It is > true that we'd be able to optimize: > int foo [5] = { 1, 2, 3, 4, 5 }; > void > foo (int i, int j) > { > if (j > 10) > { > foo[i] = 10; > if (i < 0 || i >= 5) > link_error (); > } > foo[i]++; > }
I don't think it's too expensive. Yes, you get one additional assert (and SSA name) per array index. My main gripe would be the affect on -Warray-bounds... > > If array_at_struct_end_p is wrong, it should be fixed ;) Indeed. It was originally meant to say false if you can trust TYPE_DOMAIN of the array but now it says false if there's some means to constrain the array size (the DECL_P path and now your STRING_CST one). But all callers afterwards just look at TYPE_DOMAIN ... > > Still given the high cost of get_array_ctor_element_at_index which > > does linear searching I'd add a few early-outs like > > > > base = get_base_address (rhs); > > ctor = ctor_for_folding (base); > > if (! ctor) > > return NULL_TREE; > > This one I can add easily. > > > I'd restructure the patch quite different, using for_each_index on the > > ref gather an array of index pointers (bail out on sth unhandled). > > Then I'd see if I have interesting ranges for them, if not, bail out. > > Also compute the size product of all ranges and test that against > > PARAM_MAX_VRP_CONSTANT_ARRAY_LOADS. Then store the minimum range > > value in the index places (temporarily) and use get_base_ref_and_extent to > > get at the constant "starting" offset. From there iterate using > > the remembered indices (remember the ref tree as well via for_each_index), > > directly adjusting the constant offset so you can feed > > fold_ctor_reference the constant offsets of all elements that need to > > be considered. As optimization fold_ctor_reference would know how > > to start from the "last" offset (much refactoring would need to be > > done here given nested ctors and multiple indices I guess). > > But for this, don't you want to take it over? I can try. Is there a PR for this? > I agree that the current implementation is not very efficient and that is > why it is also limited to that small number of iterations. > As many cases just aren't able to use the valueize callback, handling > arbitrary numbers of non-constant indexes would be harder. Sure. I'd have expected you simply handle ARRAY_REF of a VAR_DECL and nothing else ;) Richard.