@@ -349,26 +349,20 @@ unsigned AffineDimExpr::getPosition() const {
349
349
return static_cast <ImplType *>(expr)->position ;
350
350
}
351
351
352
- namespace {
353
-
354
352
// / Returns true if the expression is divisible by the given symbol with
355
353
// / position `symbolPos`. The argument `opKind` specifies here what kind of
356
354
// / division or mod operation called this division. It helps in implementing the
357
355
// / commutative property of the floordiv and ceildiv operations. If the argument
358
356
// /`exprKind` is floordiv and `expr` is also a binary expression of a floordiv
359
357
// / operation, then the commutative property can be used otherwise, the floordiv
360
358
// / operation is not divisible. The same argument holds for ceildiv operation.
361
- bool isDivisibleBySymbolImpl (AffineExpr expr, unsigned symbolPos,
362
- AffineExprKind opKind,
363
- SmallVectorImpl<AffineExpr> &visitedExprs,
364
- size_t depth = 0 ) {
359
+ static bool canSimplifyDivisionBySymbol (AffineExpr expr, unsigned symbolPos,
360
+ AffineExprKind opKind,
361
+ bool fromMul = false ) {
365
362
// The argument `opKind` can either be Modulo, Floordiv or Ceildiv only.
366
363
assert ((opKind == AffineExprKind::Mod || opKind == AffineExprKind::FloorDiv ||
367
364
opKind == AffineExprKind::CeilDiv) &&
368
365
" unexpected opKind" );
369
- if (visitedExprs.size () > depth)
370
- visitedExprs.resize (depth);
371
- visitedExprs.emplace_back (expr);
372
366
switch (expr.getKind ()) {
373
367
case AffineExprKind::Constant:
374
368
return cast<AffineConstantExpr>(expr).getValue () == 0 ;
@@ -379,10 +373,9 @@ bool isDivisibleBySymbolImpl(AffineExpr expr, unsigned symbolPos,
379
373
// Checks divisibility by the given symbol for both operands.
380
374
case AffineExprKind::Add: {
381
375
AffineBinaryOpExpr binaryExpr = cast<AffineBinaryOpExpr>(expr);
382
- return isDivisibleBySymbolImpl (binaryExpr.getLHS (), symbolPos, opKind,
383
- visitedExprs, depth + 1 ) &&
384
- isDivisibleBySymbolImpl (binaryExpr.getRHS (), symbolPos, opKind,
385
- visitedExprs, depth + 1 );
376
+ return canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos,
377
+ opKind) &&
378
+ canSimplifyDivisionBySymbol (binaryExpr.getRHS (), symbolPos, opKind);
386
379
}
387
380
// Checks divisibility by the given symbol for both operands. Consider the
388
381
// expression `(((s1*s0) floordiv w) mod ((s1 * s2) floordiv p)) floordiv s1`,
@@ -391,53 +384,43 @@ bool isDivisibleBySymbolImpl(AffineExpr expr, unsigned symbolPos,
391
384
// `AffineExprKind::Mod` for this reason.
392
385
case AffineExprKind::Mod: {
393
386
AffineBinaryOpExpr binaryExpr = cast<AffineBinaryOpExpr>(expr);
394
- return isDivisibleBySymbolImpl (binaryExpr.getLHS (), symbolPos,
395
- AffineExprKind::Mod, visitedExprs,
396
- depth + 1 ) &&
397
- isDivisibleBySymbolImpl (binaryExpr.getRHS (), symbolPos,
398
- AffineExprKind::Mod, visitedExprs,
399
- depth + 1 );
387
+ return canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos,
388
+ AffineExprKind::Mod) &&
389
+ canSimplifyDivisionBySymbol (binaryExpr.getRHS (), symbolPos,
390
+ AffineExprKind::Mod);
400
391
}
401
392
// Checks if any of the operand divisible by the given symbol.
402
393
case AffineExprKind::Mul: {
403
394
AffineBinaryOpExpr binaryExpr = cast<AffineBinaryOpExpr>(expr);
404
- return isDivisibleBySymbolImpl (binaryExpr.getLHS (), symbolPos, opKind,
405
- visitedExprs, depth + 1 ) ||
406
- isDivisibleBySymbolImpl (binaryExpr.getRHS (), symbolPos, opKind,
407
- visitedExprs, depth + 1 );
395
+ return canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos, opKind,
396
+ true ) ||
397
+ canSimplifyDivisionBySymbol (binaryExpr.getRHS (), symbolPos, opKind,
398
+ true );
408
399
}
409
400
// Floordiv and ceildiv are divisible by the given symbol when the first
410
401
// operand is divisible, and the affine expression kind of the argument expr
411
402
// is same as the argument `opKind`. This can be inferred from commutative
412
403
// property of floordiv and ceildiv operations and are as follow:
413
404
// (exp1 floordiv exp2) floordiv exp3 = (exp1 floordiv exp3) floordiv exp2
414
405
// (exp1 ceildiv exp2) ceildiv exp3 = (exp1 ceildiv exp3) ceildiv expr2
415
- // It will fail if operations are not same. For example:
416
- // (exps1 ceildiv exp2) floordiv exp3 can not be simplified.
406
+ // It will fail 1.if operations are not same. For example:
407
+ // (exps1 ceildiv exp2) floordiv exp3 can not be simplified. 2.if there is a
408
+ // multiplication operation in the expression. For example:
409
+ // (exps1 ceildiv exp2) mul exp3 ceildiv exp4 can not be simplified.
417
410
case AffineExprKind::FloorDiv:
418
411
case AffineExprKind::CeilDiv: {
419
412
AffineBinaryOpExpr binaryExpr = cast<AffineBinaryOpExpr>(expr);
420
413
if (opKind != expr.getKind ())
421
414
return false ;
422
- if (llvm::any_of (visitedExprs, [](auto expr) {
423
- return expr.getKind () == AffineExprKind::Mul;
424
- }))
415
+ if (fromMul)
425
416
return false ;
426
- return isDivisibleBySymbolImpl (binaryExpr.getLHS (), symbolPos,
427
- expr.getKind (), visitedExprs, depth + 1 );
417
+ return canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos,
418
+ expr.getKind ());
428
419
}
429
420
}
430
421
llvm_unreachable (" Unknown AffineExpr" );
431
422
}
432
423
433
- bool isDivisibleBySymbol (AffineExpr expr, unsigned symbolPos,
434
- AffineExprKind opKind) {
435
- SmallVector<AffineExpr> visitedExprs;
436
- return isDivisibleBySymbolImpl (expr, symbolPos, opKind, visitedExprs);
437
- }
438
-
439
- } // namespace
440
-
441
424
// / Divides the given expression by the given symbol at position `symbolPos`. It
442
425
// / considers the divisibility condition is checked before calling itself. A
443
426
// / null expression is returned whenever the divisibility condition fails.
@@ -474,7 +457,7 @@ static AffineExpr symbolicDivide(AffineExpr expr, unsigned symbolPos,
474
457
// Dividing any of the operand by the given symbol.
475
458
case AffineExprKind::Mul: {
476
459
AffineBinaryOpExpr binaryExpr = cast<AffineBinaryOpExpr>(expr);
477
- if (!isDivisibleBySymbol (binaryExpr.getLHS (), symbolPos, opKind))
460
+ if (!canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos, opKind))
478
461
return binaryExpr.getLHS () *
479
462
symbolicDivide (binaryExpr.getRHS (), symbolPos, opKind);
480
463
return symbolicDivide (binaryExpr.getLHS (), symbolPos, opKind) *
@@ -609,7 +592,8 @@ static AffineExpr simplifySemiAffine(AffineExpr expr, unsigned numDims,
609
592
if (!symbolExpr)
610
593
return getAffineBinaryOpExpr (expr.getKind (), sLHS , sRHS );
611
594
unsigned symbolPos = symbolExpr.getPosition ();
612
- if (!isDivisibleBySymbol (binaryExpr.getLHS (), symbolPos, expr.getKind ()))
595
+ if (!canSimplifyDivisionBySymbol (binaryExpr.getLHS (), symbolPos,
596
+ expr.getKind ()))
613
597
return getAffineBinaryOpExpr (expr.getKind (), sLHS , sRHS );
614
598
if (expr.getKind () == AffineExprKind::Mod)
615
599
return getAffineConstantExpr (0 , expr.getContext ());
0 commit comments