From: Alina Sbirlea Date: Mon, 7 Jan 2019 18:40:27 +0000 (+0000) Subject: [MemorySSA] Extend the clobber walker with the option to skip the starting access. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aed2d64e3d078410372c7197db60dd9eae3057e3;p=llvm [MemorySSA] Extend the clobber walker with the option to skip the starting access. Summary: The option enables loop transformations to hoist accesses that do not have clobbers in the loop. If the clobber queries skips the starting access, the result may be outside the loop instead of the header Phi. Adding the walker that uses this option in a separate patch. Reviewers: george.burgess.iv Subscribers: sanjoy, jlebar, Prazek, llvm-commits Differential Revision: https://reviews.llvm.org/D55944 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350551 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/MemorySSA.cpp b/lib/Analysis/MemorySSA.cpp index 7c5cd163627..5df8e95626a 100644 --- a/lib/Analysis/MemorySSA.cpp +++ b/lib/Analysis/MemorySSA.cpp @@ -332,6 +332,7 @@ struct UpwardsMemoryQuery { // The MemoryAccess we actually got called with, used to test local domination const MemoryAccess *OriginalAccess = nullptr; Optional AR = MayAlias; + bool SkipSelfAccess = false; UpwardsMemoryQuery() = default; @@ -535,13 +536,13 @@ class ClobberWalker { /// /// This does not test for whether StopAt is a clobber UpwardsWalkResult - walkToPhiOrClobber(DefPath &Desc, - const MemoryAccess *StopAt = nullptr) const { + walkToPhiOrClobber(DefPath &Desc, const MemoryAccess *StopAt = nullptr, + const MemoryAccess *SkipStopAt = nullptr) const { assert(!isa(Desc.Last) && "Uses don't exist in my world"); for (MemoryAccess *Current : def_chain(Desc.Last)) { Desc.Last = Current; - if (Current == StopAt) + if (Current == StopAt || Current == SkipStopAt) return {Current, false, MayAlias}; if (auto *MD = dyn_cast(Current)) { @@ -619,9 +620,16 @@ class ClobberWalker { if (!VisitedPhis.insert({Node.Last, Node.Loc}).second) continue; - UpwardsWalkResult Res = walkToPhiOrClobber(Node, /*StopAt=*/StopWhere); + const MemoryAccess *SkipStopWhere = nullptr; + if (Query->SkipSelfAccess && Node.Loc == Query->StartingLoc) { + assert(isa(Query->OriginalAccess)); + SkipStopWhere = Query->OriginalAccess; + } + + UpwardsWalkResult Res = walkToPhiOrClobber(Node, /*StopAt=*/StopWhere, + /*SkipStopAt=*/SkipStopWhere); if (Res.IsKnownClobber) { - assert(Res.Result != StopWhere); + assert(Res.Result != StopWhere && Res.Result != SkipStopWhere); // If this wasn't a cache hit, we hit a clobber when walking. That's a // failure. TerminatedPath Term{Res.Result, PathIndex}; @@ -633,10 +641,13 @@ class ClobberWalker { continue; } - if (Res.Result == StopWhere) { + if (Res.Result == StopWhere || Res.Result == SkipStopWhere) { // We've hit our target. Save this path off for if we want to continue - // walking. - NewPaused.push_back(PathIndex); + // walking. If we are in the mode of skipping the OriginalAccess, and + // we've reached back to the OriginalAccess, do not save path, we've + // just looped back to self. + if (Res.Result != SkipStopWhere) + NewPaused.push_back(PathIndex); continue; }