@@ -4605,74 +4605,22 @@ struct DropUnitExtentBasis
46054605 }
46064606};
46074607
4608- // / Drop delinearization pattern related to loops in the following way
4608+ // / Drop delinearization with a single basis element
46094609// /
4610- // / ```
4611- // / <loop>(%iv) = (%c0) to (%ub) step (%c1) {
4612- // / %0 = affine.delinearize_index %iv into (%ub) : index
4613- // / <some_use>(%0)
4614- // / }
4615- // / ```
4616- // /
4617- // / can be canonicalized to
4618- // /
4619- // / ```
4620- // / <loop>(%iv) = (%c0) to (%ub) step (%c1) {
4621- // / <some_use>(%iv)
4622- // / }
4623- // / ```
4624- struct DropDelinearizeOfSingleLoop
4610+ // / By definition, `delinearize_index %linear into (%basis)` is
4611+ // / `%linear floorDiv 1` (since `1` is the product of the basis elememts,
4612+ // / ignoring the 0th one, and since there is no previous division we need
4613+ // / to use the remainder of). Therefore, a single-element `delinearize`
4614+ // / can be replaced by the underlying linear index.
4615+ struct DropDelinearizeOneBasisElement
46254616 : public OpRewritePattern<affine::AffineDelinearizeIndexOp> {
46264617 using OpRewritePattern::OpRewritePattern;
46274618
46284619 LogicalResult matchAndRewrite (affine::AffineDelinearizeIndexOp delinearizeOp,
46294620 PatternRewriter &rewriter) const override {
46304621 if (delinearizeOp.getStaticBasis ().size () != 1 )
46314622 return failure ();
4632- auto basis = delinearizeOp.getMixedBasis ();
4633-
4634- // Check that the `linear_index` is an induction variable.
4635- auto inductionVar = dyn_cast<BlockArgument>(delinearizeOp.getLinearIndex ());
4636- if (!inductionVar)
4637- return failure ();
4638-
4639- // Check that the parent is a `LoopLikeOpInterface`.
4640- auto loopLikeOp = dyn_cast<LoopLikeOpInterface>(
4641- inductionVar.getParentRegion ()->getParentOp ());
4642- if (!loopLikeOp)
4643- return failure ();
4644-
4645- // Check that loop is unit-rank and that the `linear_index` is the induction
4646- // variable.
4647- auto inductionVars = loopLikeOp.getLoopInductionVars ();
4648- if (!inductionVars || inductionVars->size () != 1 ||
4649- inductionVars->front () != inductionVar) {
4650- return rewriter.notifyMatchFailure (
4651- delinearizeOp, " `linear_index` is not loop induction variable" );
4652- }
4653-
4654- // Check that the upper-bound is the basis.
4655- auto upperBounds = loopLikeOp.getLoopUpperBounds ();
4656- if (!upperBounds || upperBounds->size () != 1 ||
4657- upperBounds->front () != basis.front ()) {
4658- return rewriter.notifyMatchFailure (delinearizeOp,
4659- " `basis` is not upper bound" );
4660- }
4661-
4662- // Check that the lower bound is zero.
4663- auto lowerBounds = loopLikeOp.getLoopLowerBounds ();
4664- if (!lowerBounds || lowerBounds->size () != 1 ||
4665- !isZeroIndex (lowerBounds->front ())) {
4666- return rewriter.notifyMatchFailure (delinearizeOp,
4667- " loop lower bound is not zero" );
4668- }
4669-
4670- // Check that the step is one.
4671- auto steps = loopLikeOp.getLoopSteps ();
4672- if (!steps || steps->size () != 1 || !isConstantIntValue (steps->front (), 1 ))
4673- return rewriter.notifyMatchFailure (delinearizeOp, " loop step is not one" );
4674-
4675- rewriter.replaceOp (delinearizeOp, inductionVar);
4623+ rewriter.replaceOp (delinearizeOp, delinearizeOp.getLinearIndex ());
46764624 return success ();
46774625 }
46784626};
@@ -4681,7 +4629,7 @@ struct DropDelinearizeOfSingleLoop
46814629
46824630void affine::AffineDelinearizeIndexOp::getCanonicalizationPatterns (
46834631 RewritePatternSet &patterns, MLIRContext *context) {
4684- patterns.insert <DropDelinearizeOfSingleLoop , DropUnitExtentBasis>(context);
4632+ patterns.insert <DropDelinearizeOneBasisElement , DropUnitExtentBasis>(context);
46854633}
46864634
46874635// ===----------------------------------------------------------------------===//
0 commit comments