2018-06-28 02:03:08 +08:00
|
|
|
//===- AffineMap.cpp - MLIR Affine Map Classes ----------------------------===//
|
|
|
|
//
|
|
|
|
// Copyright 2019 The MLIR Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
#include "mlir/IR/AffineMap.h"
|
2018-07-10 00:00:25 +08:00
|
|
|
#include "mlir/IR/AffineExpr.h"
|
2018-10-04 01:07:54 +08:00
|
|
|
#include "mlir/Support/MathExtras.h"
|
2018-06-28 02:03:08 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
|
|
|
|
using namespace mlir;
|
|
|
|
|
2018-07-04 11:16:08 +08:00
|
|
|
AffineMap::AffineMap(unsigned numDims, unsigned numSymbols, unsigned numResults,
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
ArrayRef<AffineExprRef> results,
|
|
|
|
ArrayRef<AffineExprRef> rangeSizes)
|
2018-07-04 11:16:08 +08:00
|
|
|
: numDims(numDims), numSymbols(numSymbols), numResults(numResults),
|
2018-07-12 12:31:07 +08:00
|
|
|
results(results), rangeSizes(rangeSizes) {}
|
2018-07-10 00:00:25 +08:00
|
|
|
|
2018-09-13 23:12:38 +08:00
|
|
|
/// Returns a single constant result affine map.
|
|
|
|
AffineMap *AffineMap::getConstantMap(int64_t val, MLIRContext *context) {
|
|
|
|
return get(/*dimCount=*/0, /*symbolCount=*/0,
|
2018-10-04 06:39:12 +08:00
|
|
|
{AffineConstantExpr::get(val, context)}, {}, context);
|
2018-09-13 23:12:38 +08:00
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
bool AffineMap::isIdentity() {
|
2018-08-15 03:43:51 +08:00
|
|
|
if (getNumDims() != getNumResults())
|
|
|
|
return false;
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
ArrayRef<AffineExprRef> results = getResults();
|
2018-08-16 06:14:45 +08:00
|
|
|
for (unsigned i = 0, numDims = getNumDims(); i < numDims; ++i) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
auto *expr =
|
|
|
|
const_cast<AffineDimExpr *>(dyn_cast<AffineDimExpr>(results[i]));
|
2018-08-16 06:14:45 +08:00
|
|
|
if (!expr || expr->getPosition() != i)
|
2018-08-15 03:43:51 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
bool AffineMap::isSingleConstant() {
|
2018-08-25 14:38:14 +08:00
|
|
|
return getNumResults() == 1 && isa<AffineConstantExpr>(getResult(0));
|
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
int64_t AffineMap::getSingleConstantResult() {
|
2018-08-25 14:38:14 +08:00
|
|
|
assert(isSingleConstant() && "map must have a single constant result");
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
return const_cast<AffineConstantExpr *>(
|
|
|
|
cast<AffineConstantExpr>(getResult(0)))
|
|
|
|
->getValue();
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineMap::getResult(unsigned idx) { return results[idx]; }
|
|
|
|
|
2018-08-02 13:02:00 +08:00
|
|
|
/// Simplify add expression. Return nullptr if it can't be simplified.
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineBinaryOpExpr::simplifyAdd(AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-08-02 13:02:00 +08:00
|
|
|
auto *lhsConst = dyn_cast<AffineConstantExpr>(lhs);
|
|
|
|
auto *rhsConst = dyn_cast<AffineConstantExpr>(rhs);
|
2018-07-12 12:19:31 +08:00
|
|
|
|
2018-08-02 13:02:00 +08:00
|
|
|
// Fold if both LHS, RHS are a constant.
|
|
|
|
if (lhsConst && rhsConst)
|
|
|
|
return AffineConstantExpr::get(lhsConst->getValue() + rhsConst->getValue(),
|
|
|
|
context);
|
|
|
|
|
|
|
|
// Canonicalize so that only the RHS is a constant. (4 + d0 becomes d0 + 4).
|
|
|
|
// If only one of them is a symbolic expressions, make it the RHS.
|
2018-07-20 04:07:16 +08:00
|
|
|
if (isa<AffineConstantExpr>(lhs) ||
|
2018-08-02 13:02:00 +08:00
|
|
|
(lhs->isSymbolicOrConstant() && !rhs->isSymbolicOrConstant())) {
|
2018-09-13 01:21:23 +08:00
|
|
|
return AffineBinaryOpExpr::getAdd(rhs, lhs, context);
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, if there was a constant, it would be on the right.
|
|
|
|
|
|
|
|
// Addition with a zero is a noop, return the other input.
|
|
|
|
if (rhsConst) {
|
|
|
|
if (rhsConst->getValue() == 0)
|
|
|
|
return lhs;
|
|
|
|
}
|
|
|
|
// Fold successive additions like (d0 + 2) + 3 into d0 + 5.
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
auto *lBin =
|
|
|
|
const_cast<AffineBinaryOpExpr *>(dyn_cast<AffineBinaryOpExpr>(lhs));
|
2018-08-02 13:02:00 +08:00
|
|
|
if (lBin && rhsConst && lBin->getKind() == Kind::Add) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS())))
|
2018-10-04 06:40:51 +08:00
|
|
|
return lBin->getLHS() + (lrhs->getValue() + rhsConst->getValue());
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// When doing successive additions, bring constant to the right: turn (d0 + 2)
|
|
|
|
// + d1 into (d0 + d1) + 2.
|
|
|
|
if (lBin && lBin->getKind() == Kind::Add) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS()))) {
|
2018-10-04 06:40:51 +08:00
|
|
|
return lBin->getLHS() + rhs + lrhs;
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
}
|
2018-07-12 12:19:31 +08:00
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-08-02 13:02:00 +08:00
|
|
|
/// Simplify a multiply expression. Return nullptr if it can't be simplified.
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineBinaryOpExpr::simplifyMul(AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-08-02 13:02:00 +08:00
|
|
|
auto *lhsConst = dyn_cast<AffineConstantExpr>(lhs);
|
|
|
|
auto *rhsConst = dyn_cast<AffineConstantExpr>(rhs);
|
|
|
|
|
|
|
|
if (lhsConst && rhsConst)
|
|
|
|
return AffineConstantExpr::get(lhsConst->getValue() * rhsConst->getValue(),
|
|
|
|
context);
|
2018-07-12 12:19:31 +08:00
|
|
|
|
2018-07-20 04:07:16 +08:00
|
|
|
assert(lhs->isSymbolicOrConstant() || rhs->isSymbolicOrConstant());
|
2018-07-12 12:19:31 +08:00
|
|
|
|
|
|
|
// Canonicalize the mul expression so that the constant/symbolic term is the
|
|
|
|
// RHS. If both the lhs and rhs are symbolic, swap them if the lhs is a
|
|
|
|
// constant. (Note that a constant is trivially symbolic).
|
2018-07-20 04:07:16 +08:00
|
|
|
if (!rhs->isSymbolicOrConstant() || isa<AffineConstantExpr>(lhs)) {
|
2018-07-12 12:19:31 +08:00
|
|
|
// At least one of them has to be symbolic.
|
2018-09-13 01:21:23 +08:00
|
|
|
return AffineBinaryOpExpr::getMul(rhs, lhs, context);
|
2018-07-12 12:19:31 +08:00
|
|
|
}
|
|
|
|
|
2018-08-02 13:02:00 +08:00
|
|
|
// At this point, if there was a constant, it would be on the right.
|
|
|
|
|
|
|
|
// Multiplication with a one is a noop, return the other input.
|
|
|
|
if (rhsConst) {
|
|
|
|
if (rhsConst->getValue() == 1)
|
|
|
|
return lhs;
|
|
|
|
// Multiplication with zero.
|
|
|
|
if (rhsConst->getValue() == 0)
|
|
|
|
return rhsConst;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fold successive multiplications: eg: (d0 * 2) * 3 into d0 * 6.
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
auto *lBin =
|
|
|
|
const_cast<AffineBinaryOpExpr *>(dyn_cast<AffineBinaryOpExpr>(lhs));
|
2018-08-02 13:02:00 +08:00
|
|
|
if (lBin && rhsConst && lBin->getKind() == Kind::Mul) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS())))
|
2018-10-04 06:40:51 +08:00
|
|
|
return lBin->getLHS() * (lrhs->getValue() * rhsConst->getValue());
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// When doing successive multiplication, bring constant to the right: turn (d0
|
|
|
|
// * 2) * d1 into (d0 * d1) * 2.
|
|
|
|
if (lBin && lBin->getKind() == Kind::Mul) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS()))) {
|
2018-10-04 06:40:51 +08:00
|
|
|
return (lBin->getLHS() * rhs) * lrhs;
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-10 00:00:25 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineBinaryOpExpr::simplifyFloorDiv(AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-08-02 13:02:00 +08:00
|
|
|
auto *lhsConst = dyn_cast<AffineConstantExpr>(lhs);
|
|
|
|
auto *rhsConst = dyn_cast<AffineConstantExpr>(rhs);
|
|
|
|
|
|
|
|
if (lhsConst && rhsConst)
|
2018-10-04 01:07:54 +08:00
|
|
|
return AffineConstantExpr::get(
|
|
|
|
floorDiv(lhsConst->getValue(), rhsConst->getValue()), context);
|
2018-08-02 13:02:00 +08:00
|
|
|
|
|
|
|
// Fold floordiv of a multiply with a constant that is a multiple of the
|
|
|
|
// divisor. Eg: (i * 128) floordiv 64 = i * 2.
|
|
|
|
if (rhsConst) {
|
2018-09-13 01:21:23 +08:00
|
|
|
if (rhsConst->getValue() == 1)
|
|
|
|
return lhs;
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
auto *lBin =
|
|
|
|
const_cast<AffineBinaryOpExpr *>(dyn_cast<AffineBinaryOpExpr>(lhs));
|
2018-08-02 13:02:00 +08:00
|
|
|
if (lBin && lBin->getKind() == Kind::Mul) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS()))) {
|
2018-08-02 13:02:00 +08:00
|
|
|
// rhsConst is known to be positive if a constant.
|
|
|
|
if (lrhs->getValue() % rhsConst->getValue() == 0)
|
2018-10-04 06:40:51 +08:00
|
|
|
return lBin->getLHS() * (lrhs->getValue() / rhsConst->getValue());
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-12 12:19:31 +08:00
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineBinaryOpExpr::simplifyCeilDiv(AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-08-02 13:02:00 +08:00
|
|
|
auto *lhsConst = dyn_cast<AffineConstantExpr>(lhs);
|
|
|
|
auto *rhsConst = dyn_cast<AffineConstantExpr>(rhs);
|
|
|
|
|
|
|
|
if (lhsConst && rhsConst)
|
|
|
|
return AffineConstantExpr::get(
|
2018-10-04 01:07:54 +08:00
|
|
|
ceilDiv(lhsConst->getValue(), rhsConst->getValue()), context);
|
2018-08-02 13:02:00 +08:00
|
|
|
|
|
|
|
// Fold ceildiv of a multiply with a constant that is a multiple of the
|
|
|
|
// divisor. Eg: (i * 128) ceildiv 64 = i * 2.
|
|
|
|
if (rhsConst) {
|
2018-09-13 01:21:23 +08:00
|
|
|
if (rhsConst->getValue() == 1)
|
|
|
|
return lhs;
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
auto *lBin =
|
|
|
|
const_cast<AffineBinaryOpExpr *>(dyn_cast<AffineBinaryOpExpr>(lhs));
|
2018-08-02 13:02:00 +08:00
|
|
|
if (lBin && lBin->getKind() == Kind::Mul) {
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
if (auto *lrhs = const_cast<AffineConstantExpr *>(
|
|
|
|
dyn_cast<AffineConstantExpr>(lBin->getRHS()))) {
|
2018-08-02 13:02:00 +08:00
|
|
|
// rhsConst is known to be positive if a constant.
|
|
|
|
if (lrhs->getValue() % rhsConst->getValue() == 0)
|
2018-10-04 06:40:51 +08:00
|
|
|
return lBin->getLHS() * (lrhs->getValue() / rhsConst->getValue());
|
2018-08-02 13:02:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-12 12:19:31 +08:00
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
[RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IR
This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few
places in the IR. By a domino effect that is pretty telling of the
inconsistencies in the codebase, const is removed where it makes sense.
The rationale is that the decision was concisously made that unique'd types
have pointer semantics without const specifier. This is fine but we should be
consistent. In the end, the only logical invariant is that there should never
be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet*
in our codebase.
This CL takes a number of shortcuts to killing const with fire, in particular
forcing const AffineExprRef to return the underlying non-const
AffineExpr*. This will be removed once AffineExpr* has disappeared in
containers but for now such shortcuts allow a bit of sanity in this long quest
for cleanups.
The **only** places where const AffineExpr*, const AffineMap* or const
IntegerSet* may still appear is by transitive needs from containers,
comparison operators etc.
There is still one major thing remaining here: figure out why cast/dyn_cast
return me a const AffineXXX*, which in turn requires a bunch of ugly
const_casts. I suspect this is due to the classof
taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if
it is coming from llvm itself (I'd doubt it) or something else (clattner@?)
In light of this, the whole discussion about const makes total sense to me now
and I would systematically apply the rule that in the end, we should never
have any const XXX in our codebase for unique'd types (assuming we can remove
them all in containers and no additional constness constraint is added on us
from the outside world).
PiperOrigin-RevId: 215811554
2018-10-05 06:10:33 +08:00
|
|
|
AffineExprRef AffineBinaryOpExpr::simplifyMod(AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-08-22 01:32:24 +08:00
|
|
|
auto *lhsConst = dyn_cast<AffineConstantExpr>(lhs);
|
|
|
|
auto *rhsConst = dyn_cast<AffineConstantExpr>(rhs);
|
|
|
|
|
|
|
|
if (lhsConst && rhsConst)
|
2018-10-04 01:07:54 +08:00
|
|
|
return AffineConstantExpr::get(
|
|
|
|
mod(lhsConst->getValue(), rhsConst->getValue()), context);
|
2018-08-22 01:32:24 +08:00
|
|
|
|
2018-08-31 08:35:15 +08:00
|
|
|
// Fold modulo of an expression that is known to be a multiple of a constant
|
|
|
|
// to zero if that constant is a multiple of the modulo factor. Eg: (i * 128)
|
|
|
|
// mod 64 is folded to 0, and less trivially, (i*(j*4*(k*32))) mod 128 = 0.
|
2018-08-22 01:32:24 +08:00
|
|
|
if (rhsConst) {
|
2018-08-31 08:35:15 +08:00
|
|
|
// rhsConst is known to be positive if a constant.
|
2018-09-13 01:21:23 +08:00
|
|
|
if (lhs->getLargestKnownDivisor() % rhsConst->getValue() == 0)
|
2018-08-31 08:35:15 +08:00
|
|
|
return AffineConstantExpr::get(0, context);
|
2018-08-22 01:32:24 +08:00
|
|
|
}
|
2018-07-12 12:19:31 +08:00
|
|
|
|
|
|
|
return nullptr;
|
2018-08-22 01:32:24 +08:00
|
|
|
// TODO(bondhugula): In general, this can be simplified more by using the GCD
|
|
|
|
// test, or in general using quantifier elimination (add two new variables q
|
|
|
|
// and r, and eliminate all variables from the linear system other than r. All
|
|
|
|
// of this can be done through mlir/Analysis/'s FlatAffineConstraints.
|
2018-07-12 12:19:31 +08:00
|
|
|
}
|