This is an archive of the discontinued LLVM Phabricator instance.

[Delinearization] Refactoring of fixed-size array delinearization
ClosedPublic

Authored by congzhe on May 1 2022, 4:42 PM.

Details

Summary

This is a follow-up patch to D122857 where we added delinearization of fixed-size arrays to loop cache analysis, which resulted in some duplicate code ("tryDelinearizeFixedSize()") in LoopCacheCost.cpp and DependenceAnalysis.cpp. Refactoring is done in this patch.

This patch refactors IndexedReference::tryDelinearizeFixedSize() out as tryDelinearizeFixedSizeImpl() and moves it to Delinearization.cpp, such that clients can reuse llvm::tryDelinearizeFixedSizeImpl() wherever they would like to delinearize fixed-size arrays. Currently it has two users, i.e., DependenceAnalysis.cpp and LoopCacheCost.cpp.

In DependenceAnalysis.cpp, tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn, SrcSubscripts, DstSubscripts) now calls tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts, SrcSizes) and tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts, DstSizes) to delinearize Src and Dst respectively, and does some clean-up work afterwards that is needed in dependence analysis. Similarly in LoopCacheCost.cpp, tryDelinearizeFixedSize() calls tryDelinearizeFixedSizeImpl() and does some clean-up work afterwards that is needed in loop cache analysis.

I'm looking forward to comments on this patch :)

Diff Detail

Event Timeline

congzhe created this revision.May 1 2022, 4:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 1 2022, 4:42 PM
congzhe requested review of this revision.May 1 2022, 4:42 PM
congzhe updated this revision to Diff 426317.May 1 2022, 4:54 PM
congzhe updated this revision to Diff 426318.May 1 2022, 5:02 PM
congzhe edited the summary of this revision. (Show Details)May 1 2022, 5:24 PM
congzhe added reviewers: Meinersbur, bmahjour, Restricted Project.
congzhe set the repository for this revision to rG LLVM Github Monorepo.
congzhe added a project: Restricted Project.
congzhe edited the summary of this revision. (Show Details)
bmahjour added inline comments.May 2 2022, 8:40 AM
llvm/lib/Analysis/DependenceAnalysis.cpp
3369–3373

[nit] '\p' is used to refer to function parameters when commenting on a function.
[nit] /// is not meant for comments inside a function.
[nit] SrcPtr -> Src
[nit] Src is mentioned but not Dst
[suggestion] assert that size of src and dst subscripts arrays are the same.
[comment] it would be better to assert that Src and Dst are GEP before casting, and SrcGEP and DstGEP should be typed as GEP instead of 'Value'. What do we gain by assuming that the Src and Dst are GEPs anyway?

llvm/lib/Analysis/LoopCacheAnalysis.cpp
358

[nit] use // for function internal comments

394

[nit] use // for function internal comments

congzhe updated this revision to Diff 426456.May 2 2022, 10:55 AM

Thanks for the comments, I've updated this patch accordingly.

llvm/lib/Analysis/DependenceAnalysis.cpp
3369–3373

Thanks for the comments!

Size of src and dst subscripts arrays are supposed to be the same if we reach this point. And I totally agree that it is worth adding an assertion to check that. I've added the assert accordingly.

You are right that Src and Dst do not need to be cast to GEPs (we did not gain anything). Now I've removed the cast.

Meinersbur added inline comments.May 2 2022, 2:59 PM
llvm/include/llvm/Analysis/Delinearization.h
128–129

"can be reused wherever needed with the llvm namespace" does not need documentation.

128–131

Could you explain the relation between Inst and AccessFn? One of them seems redundant because of the SrcBasePtr != SrcBase->getValue() check, i.e. one can be derived from the other.

llvm/lib/Analysis/Delinearization.cpp
528

Cannot assume that getPointerBase returns a SCEVUnknown.

SrcBase is only used down below, consider moving it there.

540

Subscripts.clear() should not be necessary, the caller is supposed to throw it away if returning false. We actually know that it is empty because getIndexExpressionsFromGEP has an assert for it. At least it is consistent that Sizes is not cleared too.

549

See above

llvm/lib/Analysis/DependenceAnalysis.cpp
3338

[nit]

congzhe updated this revision to Diff 428258.May 9 2022, 7:00 PM

Addressed reviewers' comments.

llvm/include/llvm/Analysis/Delinearization.h
128–129

Thanks, I've updated it accordingly.

128–131

Thanks, I've added some explanations about Inst and AccessFn here in the comment. Generally speaking AccessFn can indeed be derived from Inst, i.e., AccessFn = SE.getSCEVAtScope(getPointerOperand(Inst), LI->getLoopFor(Inst->getParent()));. It is not immediately doable to remove the arugment AccessFn though, because we would need LoopInfo *LI to be passed here in order to derive AccessFn from Inst, which brings another aspect of complexity. So I left the function declaration as it is for now.

llvm/lib/Analysis/Delinearization.cpp
528

Thanks, I've used SrcBase = dyn_cast<SCEVUnknown>(getPointerBase) instead, and made it bail out if SrcBase is NULL.

540

Thanks for the comment! I tried to remove Subscripts.clear(); but it failed a few lit tests:

LLVM :: Analysis/DDG/basic-loopnest.ll
LLVM :: Analysis/DependenceAnalysis/Coupled.ll
LLVM :: Analysis/DependenceAnalysis/DADelin.ll
LLVM :: Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll
LLVM :: Analysis/LoopCacheAnalysis/PowerPC/compute-cost.ll
LLVM :: Analysis/LoopCacheAnalysis/PowerPC/loads-store.ll
LLVM :: Analysis/LoopCacheAnalysis/PowerPC/matmul.ll
LLVM :: Analysis/LoopCacheAnalysis/PowerPC/single-store.ll
LLVM :: Analysis/LoopCacheAnalysis/PowerPC/stencil.ll

IMHO we may need to keep Subscripts.clear(). Different from Sizes which indeed gets cleared/thrown away by the caller (e.g., DependenceInfo::tryDelinearizeFixedSize()), Subscripts does not get cleared by tryDelinearizeFixedSize() (if it has only one element), and will be passed into DependenceInfo::tryDelinearizeParametricSize() and causes incorrect result.

There might be ways to further modify other places which would enable us to remove this Subscripts.clear();, but I thought we might keep it and avoid too much modification?

llvm/lib/Analysis/DependenceAnalysis.cpp
3338

Thanks, fixed it.

@Meinersbur Hi Michael, I'm wondering if you have further comments? I'd appreciate it if you could let me know your thoughts on my most recent update.

Meinersbur accepted this revision.Jun 1 2022, 2:06 PM

LGTM

llvm/lib/Analysis/Delinearization.cpp
540

It's something to be improved. I don't like the inconsistent handling when invalid. Either only return false and the caller is expected to handle this, or we unconditionally clear the array at the beginning so we know there is no junk data from a previous call.

Could you add a TODO?

This revision is now accepted and ready to land.Jun 1 2022, 2:06 PM
congzhe updated this revision to Diff 437437.Jun 15 2022, 9:22 PM

Updated to reflect Michael's final minor comment, will land it shortly.

This revision was landed with ongoing or failed builds.Jun 16 2022, 1:09 PM
This revision was automatically updated to reflect the committed changes.