blob: 6bfbaf538b2946ff7ae9f1ca3323ed946ef3789e [file] [log] [blame]
MLIR Teamf85a6262018-06-27 11:03:08 -07001//===- AffineExpr.cpp - MLIR Affine Expr Classes --------------------------===//
2//
3// Copyright 2019 The MLIR Authors.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16// =============================================================================
17
18#include "mlir/IR/AffineExpr.h"
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070019#include "mlir/Support/STLExtras.h"
Uday Bondhugulae082aad2018-07-11 21:19:31 -070020#include "third_party/llvm/llvm/include/llvm/ADT/STLExtras.h"
MLIR Teamf85a6262018-06-27 11:03:08 -070021
22using namespace mlir;
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070023
Uday Bondhugulae082aad2018-07-11 21:19:31 -070024AffineBinaryOpExpr::AffineBinaryOpExpr(Kind kind, AffineExpr *lhs,
25 AffineExpr *rhs)
26 : AffineExpr(kind), lhs(lhs), rhs(rhs) {
27 // We verify affine op expr forms at construction time.
28 switch (kind) {
29 case Kind::Add:
30 assert(!isa<AffineConstantExpr>(lhs));
Uday Bondhugulae082aad2018-07-11 21:19:31 -070031 break;
32 case Kind::Mul:
33 assert(!isa<AffineConstantExpr>(lhs));
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070034 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070035 break;
36 case Kind::FloorDiv:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070037 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070038 break;
39 case Kind::CeilDiv:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070040 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070041 break;
42 case Kind::Mod:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070043 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070044 break;
45 default:
46 llvm_unreachable("unexpected binary affine expr");
47 }
48}
49
Chris Lattner1ac20cb2018-07-10 10:59:53 -070050/// Returns true if this expression is made out of only symbols and
51/// constants (no dimensional identifiers).
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070052bool AffineExpr::isSymbolicOrConstant() const {
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070053 switch (getKind()) {
54 case Kind::Constant:
55 return true;
56 case Kind::DimId:
57 return false;
58 case Kind::SymbolId:
59 return true;
60
61 case Kind::Add:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070062 case Kind::Mul:
63 case Kind::FloorDiv:
64 case Kind::CeilDiv:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070065 case Kind::Mod: {
66 auto expr = cast<AffineBinaryOpExpr>(this);
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070067 return expr->getLHS()->isSymbolicOrConstant() &&
68 expr->getRHS()->isSymbolicOrConstant();
Chris Lattner1ac20cb2018-07-10 10:59:53 -070069 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070070 }
71}
72
Chris Lattner1ac20cb2018-07-10 10:59:53 -070073/// Returns true if this is a pure affine expression, i.e., multiplication,
74/// floordiv, ceildiv, and mod is only allowed w.r.t constants.
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070075bool AffineExpr::isPureAffine() const {
76 switch (getKind()) {
77 case Kind::SymbolId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070078 case Kind::DimId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070079 case Kind::Constant:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070080 return true;
Uday Bondhugulac1faf662018-07-19 14:08:50 -070081 case Kind::Add: {
82 auto *op = cast<AffineBinaryOpExpr>(this);
Chris Lattner1ac20cb2018-07-10 10:59:53 -070083 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine();
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070084 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070085
Chris Lattner1ac20cb2018-07-10 10:59:53 -070086 case Kind::Mul: {
87 // TODO: Canonicalize the constants in binary operators to the RHS when
88 // possible, allowing this to merge into the next case.
Uday Bondhugulac1faf662018-07-19 14:08:50 -070089 auto *op = cast<AffineBinaryOpExpr>(this);
Chris Lattner1ac20cb2018-07-10 10:59:53 -070090 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine() &&
91 (isa<AffineConstantExpr>(op->getLHS()) ||
92 isa<AffineConstantExpr>(op->getRHS()));
93 }
94 case Kind::FloorDiv:
95 case Kind::CeilDiv:
96 case Kind::Mod: {
Uday Bondhugulac1faf662018-07-19 14:08:50 -070097 auto *op = cast<AffineBinaryOpExpr>(this);
Chris Lattner1ac20cb2018-07-10 10:59:53 -070098 return op->getLHS()->isPureAffine() &&
99 isa<AffineConstantExpr>(op->getRHS());
100 }
101 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -0700102}