Changeset View
Changeset View
Standalone View
Standalone View
mlir/lib/IR/AffineExpr.cpp
Show First 20 Lines • Show All 585 Lines • ▼ Show 20 Lines | static AffineExpr simplifyAdd(AffineExpr lhs, AffineExpr rhs) { | ||||
// When doing successive additions, bring constant to the right: turn (d0 + 2) | // When doing successive additions, bring constant to the right: turn (d0 + 2) | ||||
// + d1 into (d0 + d1) + 2. | // + d1 into (d0 + d1) + 2. | ||||
if (lBin && lBin.getKind() == AffineExprKind::Add) { | if (lBin && lBin.getKind() == AffineExprKind::Add) { | ||||
if (auto lrhs = lBin.getRHS().dyn_cast<AffineConstantExpr>()) { | if (auto lrhs = lBin.getRHS().dyn_cast<AffineConstantExpr>()) { | ||||
return lBin.getLHS() + rhs + lrhs; | return lBin.getLHS() + rhs + lrhs; | ||||
} | } | ||||
} | } | ||||
// Detect and transform "expr - c * (expr floordiv c)" to "expr mod c". This | // Detect and transform "expr - q * (expr floordiv q)" to "expr mod q", where | ||||
// leads to a much more efficient form when 'c' is a power of two, and in | // q may be a constant or symbolic expression. This leads to a much more | ||||
// general a more compact and readable form. | // efficient form when 'c' is a power of two, and in general a more compact | ||||
// and readable form. | |||||
// Process '(expr floordiv c) * (-c)'. | // Process '(expr floordiv c) * (-c)'. | ||||
if (!rBinOpExpr) | if (!rBinOpExpr) | ||||
return nullptr; | return nullptr; | ||||
auto lrhs = rBinOpExpr.getLHS(); | auto lrhs = rBinOpExpr.getLHS(); | ||||
auto rrhs = rBinOpExpr.getRHS(); | auto rrhs = rBinOpExpr.getRHS(); | ||||
AffineExpr llrhs, rlrhs; | |||||
// Check if lrhsBinOpExpr is of the form (expr floordiv q) * q, where q is a | |||||
bondhugula: -> Check if lrhsBin... is of the form ... | |||||
// symbolic expression. | |||||
auto lrhsBinOpExpr = lrhs.dyn_cast<AffineBinaryOpExpr>(); | |||||
// Check rrhsConstOpExpr = -1. | |||||
auto rrhsConstOpExpr = rrhs.dyn_cast<AffineConstantExpr>(); | |||||
if (rrhsConstOpExpr && rrhsConstOpExpr.getValue() == -1 && lrhsBinOpExpr && | |||||
lrhsBinOpExpr.getKind() == AffineExprKind::Mul) { | |||||
// Check llrhs = expr floordiv q. | |||||
llrhs = lrhsBinOpExpr.getLHS(); | |||||
// Check rlrhs = q. | |||||
rlrhs = lrhsBinOpExpr.getRHS(); | |||||
auto llrhsBinOpExpr = llrhs.dyn_cast<AffineBinaryOpExpr>(); | |||||
if (!llrhsBinOpExpr || llrhsBinOpExpr.getKind() != AffineExprKind::FloorDiv) | |||||
You don't need the extra llrhsBinOpExpr on the second disjunct. bondhugula: You don't need the extra `llrhsBinOpExpr` on the second disjunct. | |||||
return nullptr; | |||||
if (llrhsBinOpExpr.getRHS() == rlrhs && lhs == llrhsBinOpExpr.getLHS()) | |||||
return lhs % rlrhs; | |||||
} | |||||
// Process lrhs, which is 'expr floordiv c'. | // Process lrhs, which is 'expr floordiv c'. | ||||
AffineBinaryOpExpr lrBinOpExpr = lrhs.dyn_cast<AffineBinaryOpExpr>(); | AffineBinaryOpExpr lrBinOpExpr = lrhs.dyn_cast<AffineBinaryOpExpr>(); | ||||
if (!lrBinOpExpr || lrBinOpExpr.getKind() != AffineExprKind::FloorDiv) | if (!lrBinOpExpr || lrBinOpExpr.getKind() != AffineExprKind::FloorDiv) | ||||
return nullptr; | return nullptr; | ||||
auto llrhs = lrBinOpExpr.getLHS(); | llrhs = lrBinOpExpr.getLHS(); | ||||
auto rlrhs = lrBinOpExpr.getRHS(); | rlrhs = lrBinOpExpr.getRHS(); | ||||
if (lhs == llrhs && rlrhs == -rrhs) { | if (lhs == llrhs && rlrhs == -rrhs) { | ||||
return lhs % rlrhs; | return lhs % rlrhs; | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
AffineExpr AffineExpr::operator+(int64_t v) const { | AffineExpr AffineExpr::operator+(int64_t v) const { | ||||
▲ Show 20 Lines • Show All 775 Lines • Show Last 20 Lines |
-> Check if lrhsBin... is of the form ...