summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mlir/include/mlir/Transforms/LoopUtils.h9
-rw-r--r--mlir/lib/Transforms/LoopFusion.cpp11
-rw-r--r--mlir/lib/Transforms/LoopTiling.cpp6
-rw-r--r--mlir/lib/Transforms/Utils/LoopUtils.cpp16
4 files changed, 27 insertions, 15 deletions
diff --git a/mlir/include/mlir/Transforms/LoopUtils.h b/mlir/include/mlir/Transforms/LoopUtils.h
index f1e7b503769..2aecdceff7f 100644
--- a/mlir/include/mlir/Transforms/LoopUtils.h
+++ b/mlir/include/mlir/Transforms/LoopUtils.h
@@ -37,14 +37,23 @@ class Value;
/// Unrolls this for operation completely if the trip count is known to be
/// constant. Returns failure otherwise.
LogicalResult loopUnrollFull(AffineForOp forOp);
+
/// Unrolls this for operation by the specified unroll factor. Returns failure
/// if the loop cannot be unrolled either due to restrictions or due to invalid
/// unroll factors.
LogicalResult loopUnrollByFactor(AffineForOp forOp, uint64_t unrollFactor);
+
/// Unrolls this loop by the specified unroll factor or its trip count,
/// whichever is lower.
LogicalResult loopUnrollUpToFactor(AffineForOp forOp, uint64_t unrollFactor);
+/// Get perfectly nested sequence of loops starting at root of loop nest
+/// (the first op being another AffineFor, and the second op - a terminator).
+/// A loop is perfectly nested iff: the first op in the loop's body is another
+/// AffineForOp, and the second op is a terminator).
+void getPerfectlyNestedLoops(SmallVectorImpl<AffineForOp> &nestedLoops,
+ AffineForOp root);
+
/// Unrolls and jams this loop by the specified factor. Returns success if the
/// loop is successfully unroll-jammed.
LogicalResult loopUnrollJamByFactor(AffineForOp forOp,
diff --git a/mlir/lib/Transforms/LoopFusion.cpp b/mlir/lib/Transforms/LoopFusion.cpp
index 2ed159ca647..39ed5a100a1 100644
--- a/mlir/lib/Transforms/LoopFusion.cpp
+++ b/mlir/lib/Transforms/LoopFusion.cpp
@@ -1062,18 +1062,9 @@ computeLoopInterchangePermutation(ArrayRef<Operation *> ops,
// pushing loop carried dependence to a greater depth in the loop nest.
static void sinkSequentialLoops(MemRefDependenceGraph::Node *node) {
assert(node->op->isa<AffineForOp>());
- // Get perfectly nested sequence of loops starting at root of loop nest
- // (the first op being another AffineFor, and the second op - a terminator).
- // TODO(andydavis,bondhugula) Share this with similar code in loop tiling.
SmallVector<AffineForOp, 4> loops;
AffineForOp curr = node->op->cast<AffineForOp>();
- loops.push_back(curr);
- auto *currBody = curr.getBody();
- while (currBody->begin() == std::prev(currBody->end(), 2) &&
- (curr = curr.getBody()->front().dyn_cast<AffineForOp>())) {
- loops.push_back(curr);
- currBody = curr.getBody();
- }
+ getPerfectlyNestedLoops(loops, curr);
if (loops.size() < 2)
return;
diff --git a/mlir/lib/Transforms/LoopTiling.cpp b/mlir/lib/Transforms/LoopTiling.cpp
index 956d50ec26f..c215fa34172 100644
--- a/mlir/lib/Transforms/LoopTiling.cpp
+++ b/mlir/lib/Transforms/LoopTiling.cpp
@@ -270,11 +270,7 @@ static void getTileableBands(Function &f,
// (inclusive).
auto getMaximalPerfectLoopNest = [&](AffineForOp root) {
SmallVector<AffineForOp, 6> band;
- AffineForOp currInst = root;
- do {
- band.push_back(currInst);
- } while (currInst.getBody()->getOperations().size() == 2 &&
- (currInst = currInst.getBody()->front().dyn_cast<AffineForOp>()));
+ getPerfectlyNestedLoops(band, root);
bands->push_back(band);
};
diff --git a/mlir/lib/Transforms/Utils/LoopUtils.cpp b/mlir/lib/Transforms/Utils/LoopUtils.cpp
index 2b17f4b84fa..1e9697a9ad5 100644
--- a/mlir/lib/Transforms/Utils/LoopUtils.cpp
+++ b/mlir/lib/Transforms/Utils/LoopUtils.cpp
@@ -353,6 +353,22 @@ LogicalResult mlir::instBodySkew(AffineForOp forOp, ArrayRef<uint64_t> shifts,
return success();
}
+/// Get perfectly nested sequence of loops starting at root of loop nest
+/// (the first op being another AffineFor, and the second op - a terminator).
+/// A loop is perfectly nested iff: the first op in the loop's body is another
+/// AffineForOp, and the second op is a terminator).
+void mlir::getPerfectlyNestedLoops(SmallVectorImpl<AffineForOp> &nestedLoops,
+ AffineForOp root) {
+ AffineForOp curr = root;
+ nestedLoops.push_back(curr);
+ auto *currBody = curr.getBody();
+ while (currBody->begin() == std::prev(currBody->end(), 2) &&
+ (curr = curr.getBody()->front().dyn_cast<AffineForOp>())) {
+ nestedLoops.push_back(curr);
+ currBody = curr.getBody();
+ }
+}
+
/// Unrolls this loop completely.
LogicalResult mlir::loopUnrollFull(AffineForOp forOp) {
Optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);
OpenPOWER on IntegriCloud