<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 14, 2013, at 10:39 AM, Renato Golin <<a href="mailto:renato.golin@linaro.org">renato.golin@linaro.org</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">On 12 February 2013 19:47, Arnold Schwaighofer <span dir="ltr"><<a href="mailto:aschwaighofer@apple.com" target="_blank">aschwaighofer@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word">Alias analysis is not dependence analysis and as such it does not know about strides. It will only answer questions such as "Does access to location A and access to location B possibly alias". The Location object encapsulates how big our access is and the address we are accessing.<br>
</div></blockquote><div><br></div><div style="">AFAICS, the Location for a pointer has Size of the pointer's type. So a Location would have to have its Size changed after we have used getLocation().</div><div style="">
<br></div><div style="">I'm guessing AA->alias(ThisLoc.getWithNewSize(VF*Size), ThatLoc.getWithNewSize(VF*Size)); or something like that.</div><div style=""><br></div></div></div></div></blockquote><div><br></div>Probably, I would have to look at the details myself. But this looks reasonable.</div><div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div style=""> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><div></div><div>The existing analysis in the loop vectorizer is conservative and will say if there is both a load and store to A via two different pointers (for example &A[i], &A[i+1] it will give up.<br>
</div></div></blockquote><div><br></div><div style="">Ok, now I see the extension of the current implementation. Maybe I should be worrying with array alias first, though I have a feeling that the implementation is very similar, if not identical, to the global structures, by using AA with the correct stride.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word">
<div>If we add a query using alias analysis (we now allow several accesses of a common underlying object) we need to look at all accesses &X[…] for possible aliasing with &A[i] where X == A. (This is assuming we insert dynamic checks for unknown objects).<br>
</div></div></blockquote><div><br></div><div style="">First I want to not rely on RT checks. I was hoping that AA would tell me "don't know" if it couldn't tell and I'd then bail.</div><div><br></div></div></div></div></blockquote><div><br></div>The existing implementation already relies on runtime checks (it has to make sure that an unknown object and a known object do not overlap). Yes, AA will conservatively return MayAlias/PartialAlias if it does not know two objects. You just have to make sure that you actually query it with that unknown object.</div><div><br></div><div>Say you have three access in your program: one has underlying object A, one has underlying object B, and one has an unknown underlying object U. If you just rely on AA, you have to query both pairs ((Access A), (Access O)) and ((Access B), (Access O)).</div><div><br></div><div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>
<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>
Note the difference between &A[i] , which is what Store->getPointerOperand() returns, and A which is what GetUnderlyingObject(Store->getPointerOperand()) returns.<br></div><div><br></div><div>If we see a store to &A[i] we now need to look at all other memory accesses to see whether they alias with it. In the multimap you only store &A[i] so you can't query for all  other objects accessing A.</div>
</div></blockquote><div><br></div><div style="">So, my idea was the following (braces indicate new behaviour):<br></div><div style=""><br></div><div style="">* Store all write pointers (and respective stores)</div><div style="">* Store all read pointers (and respective loads)<br>
</div><div style="">(...)</div><div style="">* For each write (pointer, store) -> calculate underlying object</div><div style="">  * Have I seen it?</div><div style="">    * (Is it not a GlobalValue) [1] <- this simulates old behaviour for what I don't care</div>
<div style="">      * bail</div><div style="">    * (does this store alias with other stores I have seen?) [2]</div><div style="">      * bail</div><div style=""><div>* For each read -> calculate underlying object</div><div>  * Have I seen it being written to?</div>
<div>    * (Is it not a GlobalValue) [1] <- this simulates old behaviour for what I don't care</div><div>      * bail</div><div>    * (does this load alias with other stores I have seen?) [2]</div><div>      * (bail)</div>
<div><br></div></div><div style="">[1] Not sure this is correct for all cases</div></div></div></div></blockquote>   I think it  should be.</div><div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div style="">[2] Updating the correct range</div></div></div></div></blockquote>    What do mean by updating the correct range.<br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div style="">The point here being that I'll only check aliasing of location of the stores and loads based on the fact that I already found that their underlying objects might alias, which means that all other cases will go unnoticed.</div>
<div style=""><br></div><div style="">This strikes me as very close to what you're suggesting…</div></div></div></div></blockquote><div><br></div><div>Yes this looks right.</div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto;">
<div style="word-wrap:break-word"><div>I also believe that if you implement this, that alias analysis will tell you that you have possibly overlapping accesses in your example:<br></div><div><br></div><div>struct {</div><div>
int a[100];</div><div>int b[100];</div><div>} S;</div><div><br></div><div>because</div><div><br></div><div>alias((&S.a[99], 4xsizeof(int)), &S.b[0], 4xsizeof(int)) == partial alias</div></div></blockquote><div><br>
</div><div style="">That's great! So I can rely on AA to do the hard work for me, just need to give it the correct Size.</div><div><br></div><div><br></div></div></div></div></blockquote><div><br></div>I think you read to quickly :). Partial alias is bad. You want NoAlias. I am warning that if we use alias analysis the way we have to we might not get the answer we would like to see.</div><div><br></div><div>Because the unvectorized code looks like:</div><div><br></div><div>for (i in 0..99):</div><div>  access(S.a[i], sizeof(int)) </div><div><br></div><div>and we have to change the size of the access</div><div><br></div><div>  access(S.a[i], sizeof(int)*VF))</div><div><br></div><div>AA will analyze address computations (it looks at the existing IR which still has the scalar bounds):</div><div><br></div><div>(&S.a[0.99], sizeof(int)*VF) and (&S.b[0], sizeof(int)*VF)</div><div><br></div><div>and there is an overlap due to the increased access size.</div><div><br></div><div><br></div><div><br></div><div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra">cheers,</div><div class="gmail_extra">--renato</div><div class="gmail_extra">
<br></div><div class="gmail_extra" style="">PS: Having separated ReadWrites and WriteObject makes me search every write to every write N times, which is not efficient. I'll try to mitigate that once I know that at least the algorithm is correct.</div>
</div>
</blockquote></div><br></body></html>