44 bool knownNonNegative) {
45 if (staticBasis.empty())
49 result.reserve(staticBasis.size());
50 size_t dynamicIndex = dynamicBasis.size();
51 Value dynamicPart =
nullptr;
55 arith::IntegerOverflowFlags ovflags = arith::IntegerOverflowFlags::nsw;
57 ovflags = ovflags | arith::IntegerOverflowFlags::nuw;
58 for (
int64_t elem : llvm::reverse(staticBasis)) {
59 if (ShapedType::isDynamic(elem)) {
64 arith::MulIOp::create(rewriter, loc, dynamicPart,
65 dynamicBasis[dynamicIndex - 1], ovflags);
67 dynamicPart = dynamicBasis[dynamicIndex - 1];
73 if (dynamicPart && staticPart == 1) {
74 result.push_back(dynamicPart);
80 arith::MulIOp::create(rewriter, loc, dynamicPart, stride, ovflags);
99 AffineDelinearizeIndexOp op) {
101 Value linearIdx = op.getLinearIndex();
102 unsigned numResults = op.getNumResults();
104 if (numResults == staticBasis.size())
105 staticBasis = staticBasis.drop_front();
107 if (numResults == 1) {
113 results.reserve(numResults);
121 for (
Value &stride : strides)
125 arith::ConstantOp::create(rewriter, loc, rewriter.
getZeroAttr(indexType));
128 arith::FloorDivSIOp::create(rewriter, loc, linearIdx, strides.front());
129 results.push_back(initialPart);
132 Value remainder = arith::RemSIOp::create(rewriter, loc, linearIdx, stride);
133 Value remainderNegative = arith::CmpIOp::create(
134 rewriter, loc, arith::CmpIPredicate::slt, remainder, zero);
138 Value corrected = arith::AddIOp::create(rewriter, loc, remainder, stride,
139 arith::IntegerOverflowFlags::nsw);
140 Value mod = arith::SelectOp::create(rewriter, loc, remainderNegative,
141 corrected, remainder);
146 for (
size_t i = 0, e = strides.size() - 1; i < e; ++i) {
147 Value thisStride = strides[i];
149 Value modulus = emitModTerm(thisStride);
153 Value divided = arith::DivSIOp::create(rewriter, loc, modulus, nextStride);
154 results.push_back(divided);
157 results.push_back(emitModTerm(strides.back()));
164 AffineLinearizeIndexOp op) {
166 if (op.getMultiIndex().empty()) {
168 op, rewriter.
getZeroAttr(op.getLinearIndex().getType()));
174 Type indexType = op.getLinearIndex().getType();
175 size_t numIndexes = multiIndex.size();
177 if (numIndexes == staticBasis.size())
178 staticBasis = staticBasis.drop_front();
185 for (
Value &stride : strides)
189 scaledValues.reserve(numIndexes);
194 for (
auto [stride, idxOp] :
195 llvm::zip_equal(strides, llvm::drop_end(op.getMultiIndexMutable()))) {
196 Value scaledIdx = arith::MulIOp::create(rewriter, loc, idxOp.get(), stride,
197 arith::IntegerOverflowFlags::nsw);
199 scaledValues.emplace_back(scaledIdx, numHoistableLoops);
201 scaledValues.emplace_back(
207 llvm::stable_sort(scaledValues,
208 [&](
auto l,
auto r) {
return l.second > r.second; });
211 for (
auto [scaledValue, numHoistableLoops] : llvm::drop_begin(scaledValues)) {
212 std::ignore = numHoistableLoops;
213 result = arith::AddIOp::create(rewriter, loc,
result, scaledValue,
214 arith::IntegerOverflowFlags::nsw);
221struct LowerDelinearizeIndexOps
224 LogicalResult matchAndRewrite(AffineDelinearizeIndexOp op,
230struct LowerLinearizeIndexOps final :
OpRewritePattern<AffineLinearizeIndexOp> {
232 LogicalResult matchAndRewrite(AffineLinearizeIndexOp op,
233 PatternRewriter &rewriter)
const override {
238class ExpandAffineIndexOpsPass
241 ExpandAffineIndexOpsPass() =
default;
243 void runOnOperation()
override {
245 RewritePatternSet patterns(context);
248 return signalPassFailure();
256 patterns.
insert<LowerDelinearizeIndexOps, LowerLinearizeIndexOps>(
261 return std::make_unique<ExpandAffineIndexOpsPass>();
void createOrFold(SmallVectorImpl< Value > &results, Location location, Args &&...args)
Create an operation of specific op type at the current insertion point, and immediately try to fold i...
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})
Patterns must specify the root operation name they match against, and can also specify the benefit of...