-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang] Improve disjoint/identical slices recognition in opt-bufferization. #119780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -159,28 +159,162 @@ containsReadOrWriteEffectOn(const mlir::MemoryEffects::EffectInstance &effect, | |||||
| return mlir::AliasResult::NoAlias; | ||||||
| } | ||||||
|
|
||||||
| // Returns true if the given array references represent identical | ||||||
| // or completely disjoint array slices. The callers may use this | ||||||
| // method when the alias analysis reports an alias of some kind, | ||||||
| // so that we can run Fortran specific analysis on the array slices | ||||||
| // to see if they are identical or disjoint. Note that the alias | ||||||
| // analysis are not able to give such an answer about the references. | ||||||
| static bool areIdenticalOrDisjointSlices(mlir::Value ref1, mlir::Value ref2) { | ||||||
| // Helper class for analyzing two array slices represented | ||||||
| // by two hlfir.designate operations. | ||||||
| class ArraySectionAnalyzer { | ||||||
| public: | ||||||
| // The result of the analyzis is one of the values below. | ||||||
| enum class SlicesOverlapKind { | ||||||
| // Slices overlap is unknown. | ||||||
| Unknown, | ||||||
| // Slices are definitely disjoint. | ||||||
| DefinitelyIdentical, | ||||||
| // Slices are definitely identical. | ||||||
| DefinitelyDisjoint, | ||||||
| // Slices may be either disjoint or identical, | ||||||
| // i.e. there is definitely no partial overlap. | ||||||
| EitherIdenticalOrDisjoint | ||||||
| }; | ||||||
|
|
||||||
| // Analyzes two hlfir.designate results and returns the overlap kind. | ||||||
| // The callers may use this method when the alias analysis reports | ||||||
| // an alias of some kind, so that we can run Fortran specific analysis | ||||||
| // on the array slices to see if they are identical or disjoint. | ||||||
| // Note that the alias analysis are not able to give such an answer | ||||||
| // about the references. | ||||||
| static SlicesOverlapKind analyze(mlir::Value ref1, mlir::Value ref2); | ||||||
|
|
||||||
| private: | ||||||
| struct SectionDesc { | ||||||
| // An array section is described by <lb, ub, stride> tuple. | ||||||
| // If the designator's subscript is not a triple, then | ||||||
| // the section descriptor is constructed as <lb, nullptr, nullptr>. | ||||||
| mlir::Value lb, ub, stride; | ||||||
|
|
||||||
| SectionDesc(mlir::Value lb, mlir::Value ub, mlir::Value stride) | ||||||
| : lb(lb), ub(ub), stride(stride) { | ||||||
| assert(lb && "lower bound or index must be specified"); | ||||||
| normalize(); | ||||||
| } | ||||||
|
|
||||||
| // Normalize the section descriptor: | ||||||
| // 1. If UB is nullptr, then it is set to LB. | ||||||
| // 2. If LB==UB, then stride does not matter, | ||||||
| // so it is reset to nullptr. | ||||||
| // 3. If STRIDE==1, then it is reset to nullptr. | ||||||
| void normalize() { | ||||||
| if (!ub) | ||||||
| ub = lb; | ||||||
| if (lb == ub) | ||||||
| stride = nullptr; | ||||||
| if (stride) | ||||||
| if (auto val = fir::getIntIfConstant(stride)) | ||||||
| if (*val == 1) | ||||||
| stride = nullptr; | ||||||
| } | ||||||
|
|
||||||
| bool operator==(const SectionDesc &other) const { | ||||||
| return lb == other.lb && ub == other.ub && stride == other.stride; | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| // Given an operand_iterator over the indices operands, | ||||||
| // read the subscript values and return them as SectionDesc | ||||||
| // updating the iterator. If isTriplet is true, | ||||||
| // the subscript is a triplet, and the result is <lb, ub, stride>. | ||||||
| // Otherwise, the subscript is a scalar index, and the result | ||||||
| // is <index, nullptr, nullptr>. | ||||||
| static SectionDesc readSectionDesc(mlir::Operation::operand_iterator &it, | ||||||
| bool isTriplet) { | ||||||
| if (isTriplet) | ||||||
| return {*it++, *it++, *it++}; | ||||||
| return {*it++, nullptr, nullptr}; | ||||||
| } | ||||||
|
|
||||||
| // Return the ordered lower and upper bounds of the section. | ||||||
| // If stride is known to be non-negative, then the ordered | ||||||
| // bounds match the <lb, ub> of the descriptor. | ||||||
| // If stride is known to be negative, then the ordered | ||||||
| // bounds are <ub, lb> of the descriptor. | ||||||
| // If stride is unknown, we cannot deduce any order, | ||||||
| // so the result is <nullptr, nullptr> | ||||||
| static std::pair<mlir::Value, mlir::Value> | ||||||
| getOrderedBounds(const SectionDesc &desc) { | ||||||
| mlir::Value stride = desc.stride; | ||||||
| // Null stride means stride-1. | ||||||
|
||||||
| // Null stride means stride-1. | |
| // Null stride means stride=1. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.