[PATCH] Vectorizing Global Structures - Take 2

Renato Golin renato.golin at linaro.org
Thu Feb 14 08:39:54 PST 2013


On 12 February 2013 19:47, Arnold Schwaighofer <aschwaighofer at apple.com>wrote:

> 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.
>

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().

I'm guessing AA->alias(ThisLoc.getWithNewSize(VF*Size),
ThatLoc.getWithNewSize(VF*Size)); or something like that.



> 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.
>

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.


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).
>

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.


Note the difference between &A[i] , which is what
> Store->getPointerOperand() returns, and A which is what
> GetUnderlyingObject(Store->getPointerOperand()) returns.
>
> 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.
>

So, my idea was the following (braces indicate new behaviour):

* Store all write pointers (and respective stores)
* Store all read pointers (and respective loads)
(...)
* For each write (pointer, store) -> calculate underlying object
  * Have I seen it?
    * (Is it not a GlobalValue) [1] <- this simulates old behaviour for
what I don't care
      * bail
    * (does this store alias with other stores I have seen?) [2]
      * bail
* For each read -> calculate underlying object
  * Have I seen it being written to?
    * (Is it not a GlobalValue) [1] <- this simulates old behaviour for
what I don't care
      * bail
    * (does this load alias with other stores I have seen?) [2]
      * (bail)

[1] Not sure this is correct for all cases
[2] Updating the correct range

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.

This strikes me as very close to what you're suggesting...


I also believe that if you implement this, that alias analysis will tell
> you that you have possibly overlapping accesses in your example:
>
> struct {
> int a[100];
> int b[100];
> } S;
>
> because
>
> alias((&S.a[99], 4xsizeof(int)), &S.b[0], 4xsizeof(int)) == partial alias
>

That's great! So I can rely on AA to do the hard work for me, just need to
give it the correct Size.


cheers,
--renato

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130214/289027a6/attachment.html>


More information about the llvm-commits mailing list