Skip to content

Commit 3e638af

Browse files
committed
rerun ci
1 parent cbcfb86 commit 3e638af

File tree

4 files changed

+114
-117
lines changed

4 files changed

+114
-117
lines changed

mlir/include/mlir/Dialect/Affine/Analysis/LoopAnalysis.h

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "mlir/Support/LLVM.h"
1717
#include "llvm/ADT/ArrayRef.h"
18+
1819
#include <optional>
1920

2021
namespace mlir {
@@ -29,24 +30,6 @@ namespace affine {
2930
class AffineForOp;
3031
class NestedPattern;
3132

32-
/// Returns the trip count of the loop as an affine map with its corresponding
33-
/// operands if the latter is expressible as an affine expression, and nullptr
34-
/// otherwise. This method always succeeds as long as the lower bound is not a
35-
/// multi-result map. The trip count expression is simplified before returning.
36-
/// This method only utilizes map composition to construct lower and upper
37-
/// bounds before computing the trip count expressions
38-
void getTripCountMapAndOperands(AffineForOp forOp, AffineMap *map,
39-
SmallVectorImpl<Value> *operands);
40-
41-
/// Returns the trip count of the loop if it's a constant, std::nullopt
42-
/// otherwise. This uses affine expression analysis and is able to determine
43-
/// constant trip count in non-trivial cases.
44-
std::optional<uint64_t> getConstantTripCount(AffineForOp forOp);
45-
46-
/// Helper to replace uses of loop carried values (iter_args) and loop
47-
/// yield values while promoting single iteration affine.for ops.
48-
void replaceIterArgsAndYieldResults(AffineForOp forOp);
49-
5033
/// Returns the greatest known integral divisor of the trip count. Affine
5134
/// expression analysis is used (indirectly through getTripCount), and
5235
/// this method is thus able to determine non-trivial divisors.

mlir/include/mlir/Dialect/Affine/IR/AffineOps.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ class AffineDmaStartOp
117117
/// Returns the affine map used to access the source memref.
118118
AffineMap getSrcMap() { return getSrcMapAttr().getValue(); }
119119
AffineMapAttr getSrcMapAttr() {
120-
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getSrcMapAttrStrName()));
120+
return cast<AffineMapAttr>(
121+
*(*this)->getInherentAttr(getSrcMapAttrStrName()));
121122
}
122123

123124
/// Returns the source memref affine map indices for this DMA operation.
@@ -156,7 +157,8 @@ class AffineDmaStartOp
156157
/// Returns the affine map used to access the destination memref.
157158
AffineMap getDstMap() { return getDstMapAttr().getValue(); }
158159
AffineMapAttr getDstMapAttr() {
159-
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getDstMapAttrStrName()));
160+
return cast<AffineMapAttr>(
161+
*(*this)->getInherentAttr(getDstMapAttrStrName()));
160162
}
161163

162164
/// Returns the destination memref indices for this DMA operation.
@@ -185,7 +187,8 @@ class AffineDmaStartOp
185187
/// Returns the affine map used to access the tag memref.
186188
AffineMap getTagMap() { return getTagMapAttr().getValue(); }
187189
AffineMapAttr getTagMapAttr() {
188-
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getTagMapAttrStrName()));
190+
return cast<AffineMapAttr>(
191+
*(*this)->getInherentAttr(getTagMapAttrStrName()));
189192
}
190193

191194
/// Returns the tag memref indices for this DMA operation.
@@ -307,7 +310,8 @@ class AffineDmaWaitOp
307310
/// Returns the affine map used to access the tag memref.
308311
AffineMap getTagMap() { return getTagMapAttr().getValue(); }
309312
AffineMapAttr getTagMapAttr() {
310-
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getTagMapAttrStrName()));
313+
return cast<AffineMapAttr>(
314+
*(*this)->getInherentAttr(getTagMapAttrStrName()));
311315
}
312316

313317
/// Returns the tag memref index for this DMA operation.
@@ -465,6 +469,23 @@ AffineForOp getForInductionVarOwner(Value val);
465469
/// AffineParallelOp.
466470
AffineParallelOp getAffineParallelInductionVarOwner(Value val);
467471

472+
/// Helper to replace uses of loop carried values (iter_args) and loop
473+
/// yield values while promoting single iteration affine.for ops.
474+
void replaceIterArgsAndYieldResults(AffineForOp forOp);
475+
476+
/// Returns the trip count of the loop as an affine expression if the latter is
477+
/// expressible as an affine expression, and nullptr otherwise. The trip count
478+
/// expression is simplified before returning. This method only utilizes map
479+
/// composition to construct lower and upper bounds before computing the trip
480+
/// count expressions.
481+
void getTripCountMapAndOperands(AffineForOp forOp, AffineMap *tripCountMap,
482+
SmallVectorImpl<Value> *tripCountOperands);
483+
484+
/// Returns the trip count of the loop if it's a constant, std::nullopt
485+
/// otherwise. This uses affine expression analysis and is able to determine
486+
/// constant trip count in non-trivial cases.
487+
std::optional<uint64_t> getConstantTripCount(AffineForOp forOp);
488+
468489
/// Extracts the induction variables from a list of AffineForOps and places them
469490
/// in the output argument `ivs`.
470491
void extractForInductionVars(ArrayRef<AffineForOp> forInsts,

mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -12,115 +12,23 @@
1212

1313
#include "mlir/Dialect/Affine/Analysis/LoopAnalysis.h"
1414

15-
#include "mlir/Analysis/SliceAnalysis.h"
1615
#include "mlir/Dialect/Affine/Analysis/AffineAnalysis.h"
1716
#include "mlir/Dialect/Affine/Analysis/AffineStructures.h"
1817
#include "mlir/Dialect/Affine/Analysis/NestedMatcher.h"
1918
#include "mlir/Dialect/Affine/IR/AffineOps.h"
2019
#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
2120
#include "mlir/Support/MathExtras.h"
2221

23-
#include "llvm/ADT/DenseSet.h"
2422
#include "llvm/ADT/SmallPtrSet.h"
2523
#include "llvm/ADT/SmallString.h"
24+
2625
#include <numeric>
2726
#include <optional>
2827
#include <type_traits>
2928

3029
using namespace mlir;
3130
using namespace mlir::affine;
3231

33-
/// Returns the trip count of the loop as an affine expression if the latter is
34-
/// expressible as an affine expression, and nullptr otherwise. The trip count
35-
/// expression is simplified before returning. This method only utilizes map
36-
/// composition to construct lower and upper bounds before computing the trip
37-
/// count expressions.
38-
void mlir::affine::getTripCountMapAndOperands(
39-
AffineForOp forOp, AffineMap *tripCountMap,
40-
SmallVectorImpl<Value> *tripCountOperands) {
41-
MLIRContext *context = forOp.getContext();
42-
int64_t step = forOp.getStepAsInt();
43-
int64_t loopSpan;
44-
if (forOp.hasConstantBounds()) {
45-
int64_t lb = forOp.getConstantLowerBound();
46-
int64_t ub = forOp.getConstantUpperBound();
47-
loopSpan = ub - lb;
48-
if (loopSpan < 0)
49-
loopSpan = 0;
50-
*tripCountMap = AffineMap::getConstantMap(ceilDiv(loopSpan, step), context);
51-
tripCountOperands->clear();
52-
return;
53-
}
54-
auto lbMap = forOp.getLowerBoundMap();
55-
auto ubMap = forOp.getUpperBoundMap();
56-
if (lbMap.getNumResults() != 1) {
57-
*tripCountMap = AffineMap();
58-
return;
59-
}
60-
61-
// Difference of each upper bound expression from the single lower bound
62-
// expression (divided by the step) provides the expressions for the trip
63-
// count map.
64-
AffineValueMap ubValueMap(ubMap, forOp.getUpperBoundOperands());
65-
66-
SmallVector<AffineExpr, 4> lbSplatExpr(ubValueMap.getNumResults(),
67-
lbMap.getResult(0));
68-
auto lbMapSplat = AffineMap::get(lbMap.getNumDims(), lbMap.getNumSymbols(),
69-
lbSplatExpr, context);
70-
AffineValueMap lbSplatValueMap(lbMapSplat, forOp.getLowerBoundOperands());
71-
72-
AffineValueMap tripCountValueMap;
73-
AffineValueMap::difference(ubValueMap, lbSplatValueMap, &tripCountValueMap);
74-
for (unsigned i = 0, e = tripCountValueMap.getNumResults(); i < e; ++i)
75-
tripCountValueMap.setResult(i,
76-
tripCountValueMap.getResult(i).ceilDiv(step));
77-
78-
*tripCountMap = tripCountValueMap.getAffineMap();
79-
tripCountOperands->assign(tripCountValueMap.getOperands().begin(),
80-
tripCountValueMap.getOperands().end());
81-
}
82-
83-
/// Returns the trip count of the loop if it's a constant, std::nullopt
84-
/// otherwise. This method uses affine expression analysis (in turn using
85-
/// getTripCount) and is able to determine constant trip count in non-trivial
86-
/// cases.
87-
std::optional<uint64_t> mlir::affine::getConstantTripCount(AffineForOp forOp) {
88-
SmallVector<Value, 4> operands;
89-
AffineMap map;
90-
getTripCountMapAndOperands(forOp, &map, &operands);
91-
92-
if (!map)
93-
return std::nullopt;
94-
95-
// Take the min if all trip counts are constant.
96-
std::optional<uint64_t> tripCount;
97-
for (auto resultExpr : map.getResults()) {
98-
if (auto constExpr = dyn_cast<AffineConstantExpr>(resultExpr)) {
99-
if (tripCount.has_value())
100-
tripCount =
101-
std::min(*tripCount, static_cast<uint64_t>(constExpr.getValue()));
102-
else
103-
tripCount = constExpr.getValue();
104-
} else
105-
return std::nullopt;
106-
}
107-
return tripCount;
108-
}
109-
110-
void mlir::affine::replaceIterArgsAndYieldResults(AffineForOp forOp) {
111-
// Replace uses of iter arguments with iter operands (initial values).
112-
OperandRange iterOperands = forOp.getInits();
113-
MutableArrayRef<BlockArgument> iterArgs = forOp.getRegionIterArgs();
114-
for (auto [operand, arg] : llvm::zip(iterOperands, iterArgs))
115-
arg.replaceAllUsesWith(operand);
116-
117-
// Replace uses of loop results with the values yielded by the loop.
118-
ResultRange outerResults = forOp.getResults();
119-
OperandRange innerResults = forOp.getBody()->getTerminator()->getOperands();
120-
for (auto [outer, inner] : llvm::zip(outerResults, innerResults))
121-
outer.replaceAllUsesWith(inner);
122-
}
123-
12432
/// Returns the greatest known integral divisor of the trip count. Affine
12533
/// expression analysis is used (indirectly through getTripCount), and
12634
/// this method is thus able to determine non-trivial divisors.

mlir/lib/Dialect/Affine/IR/AffineOps.cpp

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,8 +2442,20 @@ std::optional<OpFoldResult> AffineForOp::getSingleUpperBound() {
24422442
return OpFoldResult(b.getI64IntegerAttr(getConstantUpperBound()));
24432443
}
24442444

2445-
/// Promotes the loop body of a forOp to its containing block if the forOp
2446-
/// was known to have a single iteration.
2445+
void mlir::affine::replaceIterArgsAndYieldResults(AffineForOp forOp) {
2446+
// Replace uses of iter arguments with iter operands (initial values).
2447+
OperandRange iterOperands = forOp.getInits();
2448+
MutableArrayRef<BlockArgument> iterArgs = forOp.getRegionIterArgs();
2449+
for (auto [operand, arg] : llvm::zip(iterOperands, iterArgs))
2450+
arg.replaceAllUsesWith(operand);
2451+
2452+
// Replace uses of loop results with the values yielded by the loop.
2453+
ResultRange outerResults = forOp.getResults();
2454+
OperandRange innerResults = forOp.getBody()->getTerminator()->getOperands();
2455+
for (auto [outer, inner] : llvm::zip(outerResults, innerResults))
2456+
outer.replaceAllUsesWith(inner);
2457+
}
2458+
24472459
LogicalResult AffineForOp::promoteIfSingleIteration(RewriterBase &rewriter) {
24482460
auto forOp = cast<AffineForOp>(getOperation());
24492461
std::optional<uint64_t> tripCount = getConstantTripCount(forOp);
@@ -2587,6 +2599,79 @@ AffineParallelOp mlir::affine::getAffineParallelInductionVarOwner(Value val) {
25872599
return nullptr;
25882600
}
25892601

2602+
/// Returns the trip count of the loop as an affine expression if the latter is
2603+
/// expressible as an affine expression, and nullptr otherwise. The trip count
2604+
/// expression is simplified before returning. This method only utilizes map
2605+
/// composition to construct lower and upper bounds before computing the trip
2606+
/// count expressions.
2607+
void mlir::affine::getTripCountMapAndOperands(
2608+
AffineForOp forOp, AffineMap *tripCountMap,
2609+
SmallVectorImpl<Value> *tripCountOperands) {
2610+
MLIRContext *context = forOp.getContext();
2611+
int64_t step = forOp.getStepAsInt();
2612+
int64_t loopSpan;
2613+
if (forOp.hasConstantBounds()) {
2614+
int64_t lb = forOp.getConstantLowerBound();
2615+
int64_t ub = forOp.getConstantUpperBound();
2616+
loopSpan = ub - lb;
2617+
if (loopSpan < 0)
2618+
loopSpan = 0;
2619+
*tripCountMap = AffineMap::getConstantMap(ceilDiv(loopSpan, step), context);
2620+
tripCountOperands->clear();
2621+
return;
2622+
}
2623+
auto lbMap = forOp.getLowerBoundMap();
2624+
auto ubMap = forOp.getUpperBoundMap();
2625+
if (lbMap.getNumResults() != 1) {
2626+
*tripCountMap = AffineMap();
2627+
return;
2628+
}
2629+
2630+
// Difference of each upper bound expression from the single lower bound
2631+
// expression (divided by the step) provides the expressions for the trip
2632+
// count map.
2633+
AffineValueMap ubValueMap(ubMap, forOp.getUpperBoundOperands());
2634+
2635+
SmallVector<AffineExpr, 4> lbSplatExpr(ubValueMap.getNumResults(),
2636+
lbMap.getResult(0));
2637+
auto lbMapSplat = AffineMap::get(lbMap.getNumDims(), lbMap.getNumSymbols(),
2638+
lbSplatExpr, context);
2639+
AffineValueMap lbSplatValueMap(lbMapSplat, forOp.getLowerBoundOperands());
2640+
2641+
AffineValueMap tripCountValueMap;
2642+
AffineValueMap::difference(ubValueMap, lbSplatValueMap, &tripCountValueMap);
2643+
for (unsigned i = 0, e = tripCountValueMap.getNumResults(); i < e; ++i)
2644+
tripCountValueMap.setResult(i,
2645+
tripCountValueMap.getResult(i).ceilDiv(step));
2646+
2647+
*tripCountMap = tripCountValueMap.getAffineMap();
2648+
tripCountOperands->assign(tripCountValueMap.getOperands().begin(),
2649+
tripCountValueMap.getOperands().end());
2650+
}
2651+
2652+
std::optional<uint64_t> mlir::affine::getConstantTripCount(AffineForOp forOp) {
2653+
SmallVector<Value, 4> operands;
2654+
AffineMap map;
2655+
getTripCountMapAndOperands(forOp, &map, &operands);
2656+
2657+
if (!map)
2658+
return std::nullopt;
2659+
2660+
// Take the min if all trip counts are constant.
2661+
std::optional<uint64_t> tripCount;
2662+
for (auto resultExpr : map.getResults()) {
2663+
if (auto constExpr = dyn_cast<AffineConstantExpr>(resultExpr)) {
2664+
if (tripCount.has_value())
2665+
tripCount =
2666+
std::min(*tripCount, static_cast<uint64_t>(constExpr.getValue()));
2667+
else
2668+
tripCount = constExpr.getValue();
2669+
} else
2670+
return std::nullopt;
2671+
}
2672+
return tripCount;
2673+
}
2674+
25902675
/// Extracts the induction variables from a list of AffineForOps and returns
25912676
/// them.
25922677
void mlir::affine::extractForInductionVars(ArrayRef<AffineForOp> forInsts,

0 commit comments

Comments
 (0)