2018-06-27 11:03:08 -07:00
|
|
|
//===- AffineExpr.cpp - MLIR Affine Expr 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/AffineExpr.h"
|
2018-07-09 09:00:25 -07:00
|
|
|
#include "mlir/Support/STLExtras.h"
|
2018-10-03 15:36:53 -07:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2018-06-27 11:03:08 -07:00
|
|
|
|
|
|
|
using namespace mlir;
|
2018-07-09 09:00:25 -07:00
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineBinaryOpExpr::AffineBinaryOpExpr(Kind kind, AffineExprRef lhs,
|
|
|
|
AffineExprRef rhs, MLIRContext *context)
|
2018-10-03 15:36:53 -07:00
|
|
|
: AffineExpr(kind, context), lhs(lhs), rhs(rhs) {
|
2018-07-11 21:19:31 -07:00
|
|
|
// We verify affine op expr forms at construction time.
|
|
|
|
switch (kind) {
|
|
|
|
case Kind::Add:
|
2018-10-08 08:09:50 -07:00
|
|
|
assert(!lhs.isa<AffineConstantExprRef>());
|
2018-07-11 21:19:31 -07:00
|
|
|
break;
|
|
|
|
case Kind::Mul:
|
2018-10-08 08:09:50 -07:00
|
|
|
assert(!lhs.isa<AffineConstantExprRef>());
|
2018-07-19 13:07:16 -07:00
|
|
|
assert(rhs->isSymbolicOrConstant());
|
2018-07-11 21:19:31 -07:00
|
|
|
break;
|
|
|
|
case Kind::FloorDiv:
|
2018-07-19 13:07:16 -07:00
|
|
|
assert(rhs->isSymbolicOrConstant());
|
2018-07-11 21:19:31 -07:00
|
|
|
break;
|
|
|
|
case Kind::CeilDiv:
|
2018-07-19 13:07:16 -07:00
|
|
|
assert(rhs->isSymbolicOrConstant());
|
2018-07-11 21:19:31 -07:00
|
|
|
break;
|
|
|
|
case Kind::Mod:
|
2018-07-19 13:07:16 -07:00
|
|
|
assert(rhs->isSymbolicOrConstant());
|
2018-07-11 21:19:31 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("unexpected binary affine expr");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getSub(AffineExprRef lhs, AffineExprRef rhs,
|
|
|
|
MLIRContext *context) {
|
2018-09-12 10:21:23 -07:00
|
|
|
return getAdd(lhs, getMul(rhs, AffineConstantExpr::get(-1, context), context),
|
|
|
|
context);
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getAdd(AffineExprRef expr, int64_t rhs,
|
|
|
|
MLIRContext *context) {
|
2018-09-12 10:21:23 -07:00
|
|
|
return get(AffineExpr::Kind::Add, expr, AffineConstantExpr::get(rhs, context),
|
|
|
|
context);
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getMul(AffineExprRef expr, int64_t rhs,
|
|
|
|
MLIRContext *context) {
|
2018-09-13 08:12:38 -07:00
|
|
|
return get(AffineExpr::Kind::Mul, expr, AffineConstantExpr::get(rhs, context),
|
|
|
|
context);
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getFloorDiv(AffineExprRef lhs, uint64_t rhs,
|
|
|
|
MLIRContext *context) {
|
2018-10-03 15:34:57 -07:00
|
|
|
return get(AffineExpr::Kind::FloorDiv, lhs,
|
|
|
|
AffineConstantExpr::get(rhs, context), context);
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getCeilDiv(AffineExprRef lhs, uint64_t rhs,
|
|
|
|
MLIRContext *context) {
|
2018-09-12 10:21:23 -07:00
|
|
|
return get(AffineExpr::Kind::CeilDiv, lhs,
|
|
|
|
AffineConstantExpr::get(rhs, context), context);
|
|
|
|
}
|
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
AffineExprRef AffineBinaryOpExpr::getMod(AffineExprRef lhs, uint64_t rhs,
|
|
|
|
MLIRContext *context) {
|
2018-10-03 15:34:57 -07:00
|
|
|
return get(AffineExpr::Kind::Mod, lhs, AffineConstantExpr::get(rhs, context),
|
|
|
|
context);
|
|
|
|
}
|
|
|
|
|
2018-07-10 10:59:53 -07:00
|
|
|
/// Returns true if this expression is made out of only symbols and
|
|
|
|
/// constants (no dimensional identifiers).
|
[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-04 15:10:33 -07:00
|
|
|
bool AffineExpr::isSymbolicOrConstant() {
|
2018-07-09 09:00:25 -07:00
|
|
|
switch (getKind()) {
|
|
|
|
case Kind::Constant:
|
|
|
|
return true;
|
|
|
|
case Kind::DimId:
|
|
|
|
return false;
|
|
|
|
case Kind::SymbolId:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case Kind::Add:
|
|
|
|
case Kind::Mul:
|
|
|
|
case Kind::FloorDiv:
|
|
|
|
case Kind::CeilDiv:
|
2018-07-10 10:59:53 -07:00
|
|
|
case Kind::Mod: {
|
2018-10-03 15:39:12 -07:00
|
|
|
auto *expr = cast<AffineBinaryOpExpr>(this);
|
2018-07-19 13:07:16 -07:00
|
|
|
return expr->getLHS()->isSymbolicOrConstant() &&
|
|
|
|
expr->getRHS()->isSymbolicOrConstant();
|
2018-07-10 10:59:53 -07:00
|
|
|
}
|
2018-07-09 09:00:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-10 10:59:53 -07:00
|
|
|
/// Returns true if this is a pure affine expression, i.e., multiplication,
|
|
|
|
/// floordiv, ceildiv, and mod is only allowed w.r.t constants.
|
[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-04 15:10:33 -07:00
|
|
|
bool AffineExpr::isPureAffine() {
|
2018-07-09 09:00:25 -07:00
|
|
|
switch (getKind()) {
|
|
|
|
case Kind::SymbolId:
|
|
|
|
case Kind::DimId:
|
|
|
|
case Kind::Constant:
|
2018-07-10 10:59:53 -07:00
|
|
|
return true;
|
2018-07-19 14:08:50 -07:00
|
|
|
case Kind::Add: {
|
|
|
|
auto *op = cast<AffineBinaryOpExpr>(this);
|
2018-07-10 10:59:53 -07:00
|
|
|
return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine();
|
|
|
|
}
|
|
|
|
|
|
|
|
case Kind::Mul: {
|
|
|
|
// TODO: Canonicalize the constants in binary operators to the RHS when
|
|
|
|
// possible, allowing this to merge into the next case.
|
2018-07-19 14:08:50 -07:00
|
|
|
auto *op = cast<AffineBinaryOpExpr>(this);
|
2018-07-10 10:59:53 -07:00
|
|
|
return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine() &&
|
2018-10-08 08:09:50 -07:00
|
|
|
(op->getLHS().isa<AffineConstantExprRef>() ||
|
|
|
|
op->getRHS().isa<AffineConstantExprRef>());
|
2018-07-10 10:59:53 -07:00
|
|
|
}
|
2018-07-09 09:00:25 -07:00
|
|
|
case Kind::FloorDiv:
|
|
|
|
case Kind::CeilDiv:
|
2018-07-10 10:59:53 -07:00
|
|
|
case Kind::Mod: {
|
2018-07-19 14:08:50 -07:00
|
|
|
auto *op = cast<AffineBinaryOpExpr>(this);
|
2018-07-10 10:59:53 -07:00
|
|
|
return op->getLHS()->isPureAffine() &&
|
2018-10-08 08:09:50 -07:00
|
|
|
op->getRHS().isa<AffineConstantExprRef>();
|
2018-07-10 10:59:53 -07:00
|
|
|
}
|
2018-07-09 09:00:25 -07:00
|
|
|
}
|
|
|
|
}
|
2018-08-30 17:35:15 -07:00
|
|
|
|
2018-09-12 10:21:23 -07:00
|
|
|
/// Returns the greatest known integral divisor of this affine expression.
|
[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-04 15:10:33 -07:00
|
|
|
uint64_t AffineExpr::getLargestKnownDivisor() {
|
2018-08-30 17:35:15 -07:00
|
|
|
AffineBinaryOpExpr *binExpr = nullptr;
|
|
|
|
switch (kind) {
|
|
|
|
case Kind::SymbolId:
|
|
|
|
LLVM_FALLTHROUGH;
|
|
|
|
case Kind::DimId:
|
|
|
|
return 1;
|
|
|
|
case Kind::Constant:
|
|
|
|
return std::abs(cast<AffineConstantExpr>(this)->getValue());
|
2018-10-03 15:39:12 -07:00
|
|
|
case 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-04 15:10:33 -07:00
|
|
|
binExpr = cast<AffineBinaryOpExpr>(this);
|
2018-09-12 10:21:23 -07:00
|
|
|
return binExpr->getLHS()->getLargestKnownDivisor() *
|
|
|
|
binExpr->getRHS()->getLargestKnownDivisor();
|
2018-10-03 15:39:12 -07:00
|
|
|
}
|
2018-08-30 17:35:15 -07:00
|
|
|
case Kind::Add:
|
|
|
|
LLVM_FALLTHROUGH;
|
|
|
|
case Kind::FloorDiv:
|
|
|
|
case Kind::CeilDiv:
|
2018-10-03 15:39:12 -07:00
|
|
|
case Kind::Mod: {
|
[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-04 15:10:33 -07:00
|
|
|
binExpr = cast<AffineBinaryOpExpr>(this);
|
2018-09-12 10:21:23 -07:00
|
|
|
return llvm::GreatestCommonDivisor64(
|
|
|
|
binExpr->getLHS()->getLargestKnownDivisor(),
|
|
|
|
binExpr->getRHS()->getLargestKnownDivisor());
|
2018-08-30 17:35:15 -07:00
|
|
|
}
|
2018-10-03 15:39:12 -07:00
|
|
|
}
|
2018-08-30 17:35:15 -07: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-04 15:10:33 -07:00
|
|
|
bool AffineExpr::isMultipleOf(int64_t factor) {
|
2018-08-30 17:35:15 -07:00
|
|
|
AffineBinaryOpExpr *binExpr = nullptr;
|
|
|
|
uint64_t l, u;
|
|
|
|
switch (kind) {
|
|
|
|
case Kind::SymbolId:
|
|
|
|
LLVM_FALLTHROUGH;
|
|
|
|
case Kind::DimId:
|
|
|
|
return factor * factor == 1;
|
|
|
|
case Kind::Constant:
|
|
|
|
return cast<AffineConstantExpr>(this)->getValue() % factor == 0;
|
2018-10-03 15:39:12 -07:00
|
|
|
case 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-04 15:10:33 -07:00
|
|
|
binExpr = cast<AffineBinaryOpExpr>(this);
|
2018-08-30 17:35:15 -07:00
|
|
|
// It's probably not worth optimizing this further (to not traverse the
|
|
|
|
// whole sub-tree under - it that would require a version of isMultipleOf
|
2018-09-12 10:21:23 -07:00
|
|
|
// that on a 'false' return also returns the largest known divisor).
|
|
|
|
return (l = binExpr->getLHS()->getLargestKnownDivisor()) % factor == 0 ||
|
|
|
|
(u = binExpr->getRHS()->getLargestKnownDivisor()) % factor == 0 ||
|
2018-08-30 17:35:15 -07:00
|
|
|
(l * u) % factor == 0;
|
2018-10-03 15:39:12 -07:00
|
|
|
}
|
2018-08-30 17:35:15 -07:00
|
|
|
case Kind::Add:
|
|
|
|
case Kind::FloorDiv:
|
|
|
|
case Kind::CeilDiv:
|
2018-10-03 15:39:12 -07:00
|
|
|
case Kind::Mod: {
|
[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-04 15:10:33 -07:00
|
|
|
binExpr = cast<AffineBinaryOpExpr>(this);
|
2018-09-12 10:21:23 -07:00
|
|
|
return llvm::GreatestCommonDivisor64(
|
|
|
|
binExpr->getLHS()->getLargestKnownDivisor(),
|
|
|
|
binExpr->getRHS()->getLargestKnownDivisor()) %
|
2018-08-30 17:35:15 -07:00
|
|
|
factor ==
|
|
|
|
0;
|
|
|
|
}
|
2018-10-03 15:39:12 -07:00
|
|
|
}
|
2018-08-30 17:35:15 -07:00
|
|
|
}
|
2018-10-03 15:36:53 -07: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-04 15:10:33 -07:00
|
|
|
MLIRContext *AffineExpr::getContext() { return context; }
|
2018-10-03 15:36:53 -07:00
|
|
|
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator+(int64_t v) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return AffineBinaryOpExpr::getAdd(expr, v, expr->getContext());
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator+(AffineExprRef other) const {
|
|
|
|
return AffineBinaryOpExpr::getAdd(expr, other, expr->getContext());
|
|
|
|
}
|
|
|
|
template <> AffineExprRef AffineExprRef::operator*(int64_t v) const {
|
|
|
|
return AffineBinaryOpExpr::getMul(expr, v, expr->getContext());
|
|
|
|
}
|
|
|
|
template <> AffineExprRef AffineExprRef::operator*(AffineExprRef other) const {
|
|
|
|
return AffineBinaryOpExpr::getMul(expr, other, expr->getContext());
|
2018-10-03 15:36:53 -07:00
|
|
|
}
|
|
|
|
// Unary minus, delegate to operator*.
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator-() const {
|
2018-10-08 08:09:50 -07:00
|
|
|
return AffineBinaryOpExpr::getMul(expr, -1, expr->getContext());
|
2018-10-03 15:40:51 -07:00
|
|
|
}
|
2018-10-03 15:36:53 -07:00
|
|
|
// Delegate to operator+.
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator-(int64_t v) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return *this + (-v);
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator-(AffineExprRef other) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return *this + (-other);
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::floorDiv(uint64_t v) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return AffineBinaryOpExpr::getFloorDiv(expr, v, expr->getContext());
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::floorDiv(AffineExprRef other) const {
|
|
|
|
return AffineBinaryOpExpr::getFloorDiv(expr, other, expr->getContext());
|
2018-10-03 15:36:53 -07:00
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::ceilDiv(uint64_t v) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return AffineBinaryOpExpr::getCeilDiv(expr, v, expr->getContext());
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::ceilDiv(AffineExprRef other) const {
|
|
|
|
return AffineBinaryOpExpr::getCeilDiv(expr, other, expr->getContext());
|
2018-10-03 15:36:53 -07:00
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator%(uint64_t v) const {
|
2018-10-03 15:36:53 -07:00
|
|
|
return AffineBinaryOpExpr::getMod(expr, v, expr->getContext());
|
|
|
|
}
|
2018-10-03 15:40:51 -07:00
|
|
|
template <> AffineExprRef AffineExprRef::operator%(AffineExprRef other) const {
|
|
|
|
return AffineBinaryOpExpr::getMod(expr, other, expr->getContext());
|
2018-10-03 15:36:53 -07:00
|
|
|
}
|