1 //===- TestAccessAnalysis.cpp - Test affine access analysis utility -------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements a pass to test affine access analysis utilities.
11 //===----------------------------------------------------------------------===//
12 #include "mlir/Dialect/Affine/Analysis/LoopAnalysis.h"
13 #include "mlir/Dialect/Affine/Analysis/Utils.h"
14 #include "mlir/Dialect/Affine/LoopFusionUtils.h"
15 #include "mlir/Dialect/Func/IR/FuncOps.h"
16 #include "mlir/Pass/Pass.h"
18 #define PASS_NAME "test-affine-access-analysis"
21 using namespace mlir::affine
;
25 struct TestAccessAnalysis
26 : public PassWrapper
<TestAccessAnalysis
, OperationPass
<func::FuncOp
>> {
27 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAccessAnalysis
)
29 StringRef
getArgument() const final
{ return PASS_NAME
; }
30 StringRef
getDescription() const final
{
31 return "Tests affine memory access analysis utility";
34 void runOnOperation() override
;
39 /// Gathers all affine load/store ops in loop nest rooted at 'forOp' into
40 /// 'loadAndStoreOps'.
42 gatherLoadsAndStores(AffineForOp forOp
,
43 SmallVectorImpl
<Operation
*> &loadAndStoreOps
) {
44 forOp
.walk([&](Operation
*op
) {
45 if (isa
<AffineReadOpInterface
, AffineWriteOpInterface
>(op
))
46 loadAndStoreOps
.push_back(op
);
50 void TestAccessAnalysis::runOnOperation() {
51 SmallVector
<Operation
*> loadStores
;
52 SmallVector
<AffineForOp
> enclosingOps
;
53 // Go over all top-level affine.for ops and test each contained affine
54 // access's contiguity along every surrounding loop IV.
55 for (auto forOp
: getOperation().getOps
<AffineForOp
>()) {
57 gatherLoadsAndStores(forOp
, loadStores
);
58 for (Operation
*memOp
: loadStores
) {
60 getAffineForIVs(*memOp
, &enclosingOps
);
61 for (unsigned d
= 0, e
= enclosingOps
.size(); d
< e
; d
++) {
62 AffineForOp loop
= enclosingOps
[d
];
64 bool isContiguous
, isInvariant
;
65 if (auto read
= dyn_cast
<AffineReadOpInterface
>(memOp
)) {
67 isContiguousAccess(loop
.getInductionVar(), read
, &memRefDim
);
68 isInvariant
= isInvariantAccess(read
, loop
);
70 auto write
= cast
<AffineWriteOpInterface
>(memOp
);
72 isContiguousAccess(loop
.getInductionVar(), write
, &memRefDim
);
73 isInvariant
= isInvariantAccess(write
, loop
);
75 // Check for contiguity for the innermost memref dimension to avoid
76 // emitting too many diagnostics.
77 if (isContiguous
&& memRefDim
== 0)
78 memOp
->emitRemark("contiguous along loop ") << d
<< '\n';
80 memOp
->emitRemark("invariant along loop ") << d
<< '\n';
87 void registerTestAffineAccessAnalysisPass() {
88 PassRegistration
<TestAccessAnalysis
>();