Improve the logic deciding if it is safe to hoist vector transfer read/write out of the loop. Change the logic to prevent hoisting operations if there are any unknown access to the memref in the loop no matter where the operation is. For other transfer read/write in the loop check if we can prove that they access disjoint memory and ignore them in this case.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Made a quick pass but I do not think the algorithm is complete atm: in order to check lack of aliasing you need to look at whether the static intervals between read/write pairs overlap.
Here the positive example only has trivial intervals (i.e. that reduce to a single point).
The testing itself would need at least these cases:
fail:
vector.transfer_write %u00, %memref1[%c0, %c0] : vector<2xf32>, memref<?x?xf32> vector.transfer_write %u01, %memref1[%c0 %c1] : vector<2xf32>, memref<?x?xf32>
success:
vector.transfer_write %u00, %memref1[%c0, %c0] : vector<2xf32>, memref<?x?xf32> vector.transfer_write %u01, %memref1[%c0 %c2] : vector<2xf32>, memref<?x?xf32>
You also want to distinguish between the dimensions that require interval analysis (i.e. the ones that become new vectors) and the ones that are just indexed (and that only need to be provably different across writes).
Thanks Nicolas. I addressed the review, please take another look to confirm that I got it right. Based on what you mentioned my understanding is that if any indices are different in the first ranks (from 0 to memrefRank-vectorRank) then the slices are disjoint for the rest of the ranks I check that the distance between the offset is smaller that the vector size (since I check that the vector types must match)
This looks good to me, there are more relaxations we can do in the future but we should be good for now.
Thanks, Thomas!
mlir/lib/Dialect/Linalg/Transforms/Hoisting.cpp | ||
---|---|---|
94 | Note memref may itself have a vector element type and we need to account for that. | |
112 | Great, thanks! | |
168 | typos: transfer_read/transfer_write ? | |
168–172 | Let's also check transferRead.getVectorType() == transferWrite.getVectorType(), I missed that in the original impl. | |
mlir/test/Dialect/Linalg/hoisting.mlir | ||
179 | // CHECK-SAME: (vector<3xf32>, vector<3xf32>, vector<4xf32>, vector<4xf32>) { here and below? |
Note memref may itself have a vector element type and we need to account for that.
I added xferOp.getLeadingMemRefRank() recently to more easily capture the dims that are just indexed.