This is an archive of the discontinued LLVM Phabricator instance.

GVN-hoist: fix store past load dependence analysis (PR30216)
ClosedPublic

Authored by sebpop on Sep 13 2016, 11:46 AM.

Details

Summary

To hoist stores past loads, we used to search for potential
conflicting loads on the hoisting path by following a MemorySSA
def-def link from the store to be hoisted to the previous
defining memory access, and from there we followed the def-use
chains to all the uses that occur on the hoisting path. The
problem is that the def-def link may point to a store that does
not alias with the store to be hoisted, and so the loads that are
walked may not alias with the store to be hoisted, and even as in
the testcase of PR30216, the loads that may alias with the store
to be hoisted are not visited.

The current patch visits all loads on the path from the store to
be hoisted to the hoisting position and uses the alias analysis
to ask whether the store may alias the load. I was not able to
use the MemorySSA functionality to ask for whether load and
store are clobbered: I'm not sure which function to call, so I
used a call to AA->isNoAlias().

Store past store is still working as before using a MemorySSA
query: I added an extra test to pr30216.ll to make sure store
past store does not regress.

Diff Detail

Event Timeline

sebpop updated this revision to Diff 71210.Sep 13 2016, 11:46 AM
sebpop retitled this revision from to GVN-hoist: fix store past load dependence analysis (PR30216).
sebpop updated this object.
sebpop added a reviewer: dberlin.
sebpop added a subscriber: llvm-commits.
gberry added a subscriber: gberry.Sep 13 2016, 12:10 PM

I ran into the lack of an interface for this query in MemorySSA as well in the EarlyCSE changes I was working on. I think what you want is to be able to call instructionClobbersQuery() since that knows about special intrinsics and meta-data as well.

On Thu, Sep 15, 2016 at 11:11 AM, Daniel Berlin <dberlin@dberlin.org> wrote:

Sadly, I think this will fail when the use-opt limit is hit.

What about committing the patch that I already sent:

The current patch visits all loads on the path from the store to
be hoisted to the hoisting position and uses the alias analysis
to ask whether the store may alias the load.

I think the patch is already quite efficient in terms of compile time
because we limit the hoist distance to avoid register pressure issues.
Because the number of instructions on the path is bounded, we
will also have the bounds on the number of alias questions asked.

Danny, is it okay to commit the patch as it is?

dberlin accepted this revision.Sep 20 2016, 1:10 PM
dberlin edited edge metadata.

Fix these, otherwise looks fine

llvm/lib/Transforms/Scalar/GVNHoist.cpp
339

Rather than repeatedly call firstInBB, can't you just set a boolean when you hit OldPt?

347

Ditto. If it's the same BB, the before relationship is entirely controlled by whether you have hit NewPt or not.

This revision is now accepted and ready to land.Sep 20 2016, 1:10 PM
sebpop added inline comments.Sep 22 2016, 8:14 AM
llvm/lib/Transforms/Scalar/GVNHoist.cpp
339

This assumes that "for (const MemoryAccess &MA : *Acc)" iterates through memory accesses in the same order as they appear in the instruction stream. If this property holds, I could replace the "continue" with a "break": there are no other mem accesses to check after OldPt.

347

Yes, for this one I can use a bool.

sebpop updated this revision to Diff 72176.Sep 22 2016, 8:31 AM
sebpop edited edge metadata.

Updated to address the comments from Danny.

sebpop updated this revision to Diff 72179.Sep 22 2016, 8:35 AM

Added back the testcase that I missed to git add in the previous commit.

This revision was automatically updated to reflect the committed changes.