On Sun, May 12, 2019 at 2:51 PM Marc Glisse <marc.gli...@inria.fr> wrote: > > On Sun, 12 May 2019, Richard Sandiford wrote: > > > Marc Glisse <marc.gli...@inria.fr> writes: > >> Hello, > >> > >> this patch lets gcc know that if a pointer existed before the call to > >> malloc, the result of malloc cannot alias it. This is a bit ad hoc and > >> fragile. A small improvement would be, when the 2 statements are in the > >> same bb but in the wrong order, to check if there is any statement in > >> between that might prevent from reordering them. But that's more > >> complicated, and the patch as it is already does help. > >> > >> I expect people may not like the call to a function from > >> tree-ssa-loop-niter too much, but it is convenient. And if someone > >> improves it, they will likely have to rewrite something not quite > >> equivalent to stmt_dominates_stmt_p. > > > > It has linear complexity for statements in the same block though. > > Ah, true. I should anyway test that the second statement is malloc > (cheaper) before checking for domination, but even then that could be used > to create a quadratic behavior :-(
I also think the oracle queries shouldn't encompany such expensive pieces... > > (reassoc_stmt_dominates_stmt_p avoids that, but relies on uids > > being up-to-date.) > > This function is called from all over the place. Unless there is a simple > test to check if uids are safe to use (reassoc_in_progress?), that's going > to be a problem. I find it surprising that this information is so hard to > get to... Stopping stmt_dominates_stmt_p after walking 128 statements > doesn't feel like a great solution. But without controlling the pass where > this happens, I don't see any good solution. It would be great if that > non-aliasing property could be recorded in the points-to information, then > I could set it from a pass I control, but I somehow got the impression > that it wouldn't work. Maybe I should try to understand PTA better to make > sure. In princple PTA should know the aliasing cannot happen but possibly the info is either lost or the IL is too obfuscated at the point it gets computed. (hello C++...) So at ldist time I see # PT = null { D.47989 } (escaped, escaped heap) # ALIGN = 8, MISALIGN = 0 # USE = nonlocal null { D.47989 } (escaped, escaped heap) # CLB = nonlocal null { D.47989 } (escaped, escaped heap) _27 = malloc (8192); good. The interesting loop is the following where the allocation PTA is good and _4 intersect because they include ESCAPED. This is because _27 itself escapes and PTA not being flow-sensitive. I don't see an easy way to improve things here but dislike the stmt walking very much. That is, the proper solution is to re-write PTA in some way. <bb 4> [local count: 2866890688]: # PT = nonlocal escaped null # __first_13 = PHI <_4(12), __first_23(13)> # PT = null { D.47989 } (escaped, escaped heap) # ALIGN = 8, MISALIGN = 0 # __cur_12 = PHI <_27(12), __cur_24(13)> # PT = nonlocal escaped null _20 = MEM[(int * const &)__first_13 clique 2 base 0]; MEM[(int * &)__first_13 clique 2 base 0] = 0B; MEM[(struct &)__cur_12 clique 3 base 1] ={v} {CLOBBER}; MEM[(struct _Head_base *)__cur_12 clique 3 base 1]._M_head_impl = _20; # PT = nonlocal escaped null _22 = MEM[(int * &)__first_13]; if (_22 != 0B) goto <bb 5>; [53.47%] else goto <bb 16>; [46.53%] <bb 16> [local count: 1333964241]: goto <bb 6>; [100.00%] <bb 5> [local count: 1532926450]: *_22 ={v} {CLOBBER}; # USE = nonlocal null { D.47989 } (escaped, escaped heap) # CLB = nonlocal null { D.47989 } (escaped, escaped heap) operator delete (_22, 4); <bb 6> [local count: 2866890691]: MEM[(struct &)__first_13] ={v} {CLOBBER}; # PT = nonlocal escaped __first_23 = __first_13 + 8; # PT = { D.47989 } (escaped, escaped heap) # ALIGN = 8, MISALIGN = 0 __cur_24 = __cur_12 + 8; if (_9 == __first_23) goto <bb 7>; [11.00%] else goto <bb 13>; [89.00%] <bb 13> [local count: 2551532717]: goto <bb 4>; [100.00%] > -- > Marc Glisse