Skip to content

Commit f82d307

Browse files
committed
[mlir][Affine] Remove single iteration affine.for ops in AffineLoopNormalize
This patch renames AffineParallelNormalize to AffineLoopNormalize to make it more generic and be able to hold more loop normalization transformations in the future for affine.for and affine.parallel ops. Eventually, it could also be extended to support scf.for and scf.parallel. As a starting point for affine.for, the patch also adds support for removing single iteration affine.for ops to the the pass. Differential Revision: https://reviews.llvm.org/D90267
1 parent c0a922b commit f82d307

File tree

5 files changed

+53
-17
lines changed

5 files changed

+53
-17
lines changed

mlir/include/mlir/Dialect/Affine/Passes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ createAffineLoopInvariantCodeMotionPass();
3535
/// ops.
3636
std::unique_ptr<OperationPass<FuncOp>> createAffineParallelizePass();
3737

38-
/// Normalize affine.parallel ops so that lower bounds are 0 and steps are 1.
39-
std::unique_ptr<OperationPass<FuncOp>> createAffineParallelNormalizePass();
38+
/// Apply normalization transformations to affine loop-like ops.
39+
std::unique_ptr<OperationPass<FuncOp>> createAffineLoopNormalizePass();
4040

4141
/// Performs packing (or explicit copying) of accessed memref regions into
4242
/// buffers in the specified faster memory space through either pointwise copies

mlir/include/mlir/Dialect/Affine/Passes.td

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,9 @@ def AffineParallelize : FunctionPass<"affine-parallelize"> {
120120
let constructor = "mlir::createAffineParallelizePass()";
121121
}
122122

123-
def AffineParallelNormalize : FunctionPass<"affine-parallel-normalize"> {
124-
let summary = "Normalize affine.parallel ops so that lower bounds are 0 and "
125-
"steps are 1";
126-
let constructor = "mlir::createAffineParallelNormalizePass()";
123+
def AffineLoopNormalize : FunctionPass<"affine-loop-normalize"> {
124+
let summary = "Apply normalization transformations to affine loop-like ops";
125+
let constructor = "mlir::createAffineLoopNormalizePass()";
127126
}
128127

129128
def SimplifyAffineStructures : FunctionPass<"simplify-affine-structures"> {

mlir/lib/Dialect/Affine/Transforms/AffineParallelNormalize.cpp renamed to mlir/lib/Dialect/Affine/Transforms/AffineLoopNormalize.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1-
//===- AffineParallelNormalize.cpp - AffineParallelNormalize Pass ---------===//
1+
//===- AffineLoopNormalize.cpp - AffineLoopNormalize Pass -----------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file implements a normalizer for affine parallel loops.
9+
// This file implements a normalizer for affine loop-like ops.
1010
//
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "PassDetail.h"
1414
#include "mlir/Dialect/Affine/IR/AffineOps.h"
1515
#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
1616
#include "mlir/Dialect/Affine/Passes.h"
17+
#include "mlir/Dialect/Affine/Utils.h"
1718
#include "mlir/IR/PatternMatch.h"
19+
#include "mlir/Transforms/LoopUtils.h"
1820

1921
using namespace mlir;
2022

21-
void normalizeAffineParallel(AffineParallelOp op) {
23+
void mlir::normalizeAffineParallel(AffineParallelOp op) {
2224
AffineMap lbMap = op.lowerBoundsMap();
2325
SmallVector<int64_t, 8> steps = op.getSteps();
2426
// No need to do any work if the parallel op is already normalized.
@@ -77,20 +79,36 @@ void normalizeAffineParallel(AffineParallelOp op) {
7779
op.setUpperBounds(ranges.getOperands(), newUpperMap);
7880
}
7981

82+
/// Normalization transformations for affine.for ops. For now, it only removes
83+
/// single iteration loops. We may want to consider separating redundant loop
84+
/// elimitation from loop bound normalization, if needed in the future.
85+
static void normalizeAffineFor(AffineForOp op) {
86+
if (succeeded(promoteIfSingleIteration(op)))
87+
return;
88+
89+
// TODO: Normalize loop bounds.
90+
}
91+
8092
namespace {
8193

8294
/// Normalize affine.parallel ops so that lower bounds are 0 and steps are 1.
8395
/// As currently implemented, this pass cannot fail, but it might skip over ops
8496
/// that are already in a normalized form.
85-
struct AffineParallelNormalizePass
86-
: public AffineParallelNormalizeBase<AffineParallelNormalizePass> {
97+
struct AffineLoopNormalizePass
98+
: public AffineLoopNormalizeBase<AffineLoopNormalizePass> {
8799

88-
void runOnFunction() override { getFunction().walk(normalizeAffineParallel); }
100+
void runOnFunction() override {
101+
getFunction().walk([](Operation *op) {
102+
if (auto affineParallel = dyn_cast<AffineParallelOp>(op))
103+
normalizeAffineParallel(affineParallel);
104+
else if (auto affineFor = dyn_cast<AffineForOp>(op))
105+
normalizeAffineFor(affineFor);
106+
});
107+
}
89108
};
90109

91110
} // namespace
92111

93-
std::unique_ptr<OperationPass<FuncOp>>
94-
mlir::createAffineParallelNormalizePass() {
95-
return std::make_unique<AffineParallelNormalizePass>();
112+
std::unique_ptr<OperationPass<FuncOp>> mlir::createAffineLoopNormalizePass() {
113+
return std::make_unique<AffineLoopNormalizePass>();
96114
}

mlir/lib/Dialect/Affine/Transforms/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
add_mlir_dialect_library(MLIRAffineTransforms
22
AffineDataCopyGeneration.cpp
33
AffineLoopInvariantCodeMotion.cpp
4+
AffineLoopNormalize.cpp
45
AffineParallelize.cpp
5-
AffineParallelNormalize.cpp
66
LoopTiling.cpp
77
LoopUnroll.cpp
88
LoopUnrollAndJam.cpp

mlir/test/Dialect/Affine/affine-parallel-normalize.mlir renamed to mlir/test/Dialect/Affine/affine-loop-normalize.mlir

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: mlir-opt %s -affine-parallel-normalize -split-input-file | FileCheck %s
1+
// RUN: mlir-opt %s -affine-loop-normalize -split-input-file | FileCheck %s
22

33
// Normalize steps to 1 and lower bounds to 0.
44

@@ -23,3 +23,22 @@ func @normalize_parallel() {
2323
}
2424
return
2525
}
26+
27+
// -----
28+
29+
// Check that single iteration loop is removed and its body is promoted to the
30+
// parent block.
31+
32+
// CHECK-LABEL: func @single_iteration_loop
33+
func @single_iteration_loop(%in: memref<1xf32>, %out: memref<1xf32>) {
34+
affine.for %i = 0 to 1 {
35+
%1 = affine.load %in[%i] : memref<1xf32>
36+
affine.store %1, %out[%i] : memref<1xf32>
37+
}
38+
return
39+
}
40+
41+
// CHECK-NOT: affine.for
42+
// CHECK: affine.load
43+
// CHECK-NEXT: affine.store
44+
// CHECK-NEXT: return

0 commit comments

Comments
 (0)