Skip to content

Commit 99f6885

Browse files
committed
Create a helper function to avoid code duplication
1 parent 24acbf9 commit 99f6885

File tree

2 files changed

+33
-69
lines changed

2 files changed

+33
-69
lines changed

mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,31 @@ static Value vectorizeOperand(Value operand, VectorizationState &state) {
11851185
return nullptr;
11861186
}
11871187

1188+
/// Returns true if any vectorized loop IV drives more than one index.
1189+
static bool isIVMappedToMultipleIndices(
1190+
ArrayRef<Value> indices,
1191+
const DenseMap<Operation *, unsigned> &loopToVectorDim) {
1192+
for (auto &kvp : loopToVectorDim) {
1193+
AffineForOp forOp = cast<AffineForOp>(kvp.first);
1194+
// Find which indices are invariant w.r.t. this loop IV.
1195+
auto invariants =
1196+
affine::getInvariantAccesses(forOp.getInductionVar(), indices);
1197+
// Count how many vary (i.e. are not invariant).
1198+
unsigned nonInvariant = 0;
1199+
for (Value idx : indices)
1200+
if (!invariants.count(idx))
1201+
++nonInvariant;
1202+
// Bail if more than one index varies for this single loop IV.
1203+
if (nonInvariant > 1) {
1204+
LLVM_DEBUG(dbgs() << "[early‑vect] Bail out: IV "
1205+
<< forOp.getInductionVar() << " drives " << nonInvariant
1206+
<< " indices\n");
1207+
return true;
1208+
}
1209+
}
1210+
return false;
1211+
}
1212+
11881213
/// Vectorizes an affine load with the vectorization strategy in 'state' by
11891214
/// generating a 'vector.transfer_read' op with the proper permutation map
11901215
/// inferred from the indices of the load. The new 'vector.transfer_read' is
@@ -1217,21 +1242,9 @@ static Operation *vectorizeAffineLoad(AffineLoadOp loadOp,
12171242
indices.append(mapOperands.begin(), mapOperands.end());
12181243
}
12191244

1220-
for (auto &kvp : state.vecLoopToVecDim) {
1221-
AffineForOp forOp = cast<AffineForOp>(kvp.first);
1222-
auto invariants =
1223-
affine::getInvariantAccesses(forOp.getInductionVar(), indices);
1224-
unsigned nonInvariant = 0;
1225-
for (Value idx : indices)
1226-
if (!invariants.count(idx))
1227-
++nonInvariant;
1228-
if (nonInvariant > 1) {
1229-
LLVM_DEBUG(dbgs() << "\n[early-vect] Bail out: loop IV "
1230-
<< forOp.getInductionVar() << " drives " << nonInvariant
1231-
<< " indices (must be ≤1)\n");
1232-
return nullptr;
1233-
}
1234-
}
1245+
if (isIVMappedToMultipleIndices(indices, state.vecLoopToVecDim))
1246+
return nullptr;
1247+
12351248
// Compute permutation map using the information of new vector loops.
12361249
auto permutationMap = makePermutationMap(state.builder.getInsertionBlock(),
12371250
indices, state.vecLoopToVecDim);
@@ -1277,21 +1290,9 @@ static Operation *vectorizeAffineStore(AffineStoreOp storeOp,
12771290
else
12781291
indices.append(mapOperands.begin(), mapOperands.end());
12791292

1280-
for (auto &kvp : state.vecLoopToVecDim) {
1281-
AffineForOp forOp = cast<AffineForOp>(kvp.first);
1282-
auto invariants =
1283-
affine::getInvariantAccesses(forOp.getInductionVar(), indices);
1284-
unsigned nonInvariant = 0;
1285-
for (Value idx : indices)
1286-
if (!invariants.count(idx))
1287-
++nonInvariant;
1288-
if (nonInvariant > 1) {
1289-
LLVM_DEBUG(dbgs() << "\n[early-vect] Bail out: loop IV "
1290-
<< forOp.getInductionVar() << " drives " << nonInvariant
1291-
<< " indices (must be ≤1)\n");
1292-
return nullptr;
1293-
}
1294-
}
1293+
if (isIVMappedToMultipleIndices(indices, state.vecLoopToVecDim))
1294+
return nullptr;
1295+
12951296
// Compute permutation map using the information of new vector loops.
12961297
auto permutationMap = makePermutationMap(state.builder.getInsertionBlock(),
12971298
indices, state.vecLoopToVecDim);

mlir/test/Dialect/Affine/SuperVectorize/vectorize_unsupported.mlir

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func.func @unparallel_loop_reduction_unsupported(%in: memref<256x512xf32>, %out:
1515
#map = affine_map<(d0)[s0] -> (d0 mod s0)>
1616
#map1 = affine_map<(d0)[s0] -> (d0 floordiv s0)>
1717

18-
func.func @single_loop_unrolling_2D_access_pattern_storeOp(%arg0: index) -> memref<2x2xf32> {
18+
func.func @iv_mapped_to_multiple_indices_unsupported(%arg0: index) -> memref<2x2xf32> {
1919
%c2 = arith.constant 2 : index
2020
%cst = arith.constant 1.0 : f32
2121
%alloc = memref.alloc() : memref<2x2xf32>
@@ -32,48 +32,11 @@ func.func @single_loop_unrolling_2D_access_pattern_storeOp(%arg0: index) -> memr
3232
// CHECK: #[[$ATTR_0:.+]] = affine_map<(d0)[s0] -> (d0 floordiv s0)>
3333
// CHECK: #[[$ATTR_1:.+]] = affine_map<(d0)[s0] -> (d0 mod s0)>
3434

35-
// CHECK-LABEL: func.func @single_loop_unrolling_2D_access_pattern_storeOp(
35+
// CHECK-LABEL: func.func @iv_mapped_to_multiple_indices_unsupported(
3636
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index) -> memref<2x2xf32> {
3737
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
38-
// CHECK: %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
39-
// CHECK: %[[VAL_3:.*]] = memref.alloc() : memref<2x2xf32>
4038
// CHECK: affine.for %[[VAL_4:.*]] = 0 to 4 {
4139
// CHECK: %[[VAL_5:.*]] = affine.apply #[[$ATTR_0]](%[[VAL_4]]){{\[}}%[[VAL_1]]]
4240
// CHECK: %[[VAL_6:.*]] = affine.apply #[[$ATTR_1]](%[[VAL_4]]){{\[}}%[[VAL_1]]]
43-
// CHECK: affine.store %[[VAL_2]], %[[VAL_3]]{{\[}}%[[VAL_5]], %[[VAL_6]]] : memref<2x2xf32>
4441
// CHECK: }
45-
// CHECK: return %[[VAL_3]] : memref<2x2xf32>
46-
// CHECK: }
47-
48-
// -----
49-
50-
#map = affine_map<(d0)[s0] -> (d0 mod s0)>
51-
#map1 = affine_map<(d0)[s0] -> (d0 floordiv s0)>
52-
53-
func.func @single_loop_unrolling_2D_access_pattern_loadOp(%arg0: index) -> memref<2x2xf32> {
54-
%c2 = arith.constant 2 : index
55-
%alloc = memref.alloc() : memref<2x2xf32>
56-
57-
affine.for %i = 0 to 4 {
58-
%row = affine.apply #map1(%i)[%c2]
59-
%col = affine.apply #map(%i)[%c2]
60-
%val = affine.load %alloc[%row, %col] : memref<2x2xf32>
61-
}
62-
63-
return %alloc : memref<2x2xf32>
64-
}
65-
66-
// CHECK: #[[$ATTR_0:.+]] = affine_map<(d0)[s0] -> (d0 floordiv s0)>
67-
// CHECK: #[[$ATTR_1:.+]] = affine_map<(d0)[s0] -> (d0 mod s0)>
68-
69-
// CHECK-LABEL: func.func @single_loop_unrolling_2D_access_pattern_loadOp(
70-
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index) -> memref<2x2xf32> {
71-
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
72-
// CHECK: %[[VAL_2:.*]] = memref.alloc() : memref<2x2xf32>
73-
// CHECK: affine.for %[[VAL_3:.*]] = 0 to 4 {
74-
// CHECK: %[[VAL_4:.*]] = affine.apply #[[$ATTR_0]](%[[VAL_3]]){{\[}}%[[VAL_1]]]
75-
// CHECK: %[[VAL_5:.*]] = affine.apply #[[$ATTR_1]](%[[VAL_3]]){{\[}}%[[VAL_1]]]
76-
// CHECK: %[[VAL_6:.*]] = affine.load %[[VAL_2]]{{\[}}%[[VAL_4]], %[[VAL_5]]] : memref<2x2xf32>
77-
// CHECK: }
78-
// CHECK: return %[[VAL_2]] : memref<2x2xf32>
7942
// CHECK: }

0 commit comments

Comments
 (0)