blob: 8d0ee3dfca5cca28a6c853aeb2bfc735790bb08f [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));
31 // TODO (more verification)
32 break;
33 case Kind::Sub:
34 // TODO (verification)
35 break;
36 case Kind::Mul:
37 assert(!isa<AffineConstantExpr>(lhs));
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070038 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070039 // TODO (more verification)
40 break;
41 case Kind::FloorDiv:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070042 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070043 // TODO (more verification)
44 break;
45 case Kind::CeilDiv:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070046 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070047 // TODO (more verification)
48 break;
49 case Kind::Mod:
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070050 assert(rhs->isSymbolicOrConstant());
Uday Bondhugulae082aad2018-07-11 21:19:31 -070051 // TODO (more verification)
52 break;
53 default:
54 llvm_unreachable("unexpected binary affine expr");
55 }
56}
57
Chris Lattner1ac20cb2018-07-10 10:59:53 -070058/// Returns true if this expression is made out of only symbols and
59/// constants (no dimensional identifiers).
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070060bool AffineExpr::isSymbolicOrConstant() const {
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070061 switch (getKind()) {
62 case Kind::Constant:
63 return true;
64 case Kind::DimId:
65 return false;
66 case Kind::SymbolId:
67 return true;
68
69 case Kind::Add:
70 case Kind::Sub:
71 case Kind::Mul:
72 case Kind::FloorDiv:
73 case Kind::CeilDiv:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070074 case Kind::Mod: {
75 auto expr = cast<AffineBinaryOpExpr>(this);
Uday Bondhugulacbe4cca2018-07-19 13:07:16 -070076 return expr->getLHS()->isSymbolicOrConstant() &&
77 expr->getRHS()->isSymbolicOrConstant();
Chris Lattner1ac20cb2018-07-10 10:59:53 -070078 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070079 }
80}
81
Chris Lattner1ac20cb2018-07-10 10:59:53 -070082/// Returns true if this is a pure affine expression, i.e., multiplication,
83/// floordiv, ceildiv, and mod is only allowed w.r.t constants.
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070084bool AffineExpr::isPureAffine() const {
85 switch (getKind()) {
86 case Kind::SymbolId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070087 case Kind::DimId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070088 case Kind::Constant:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070089 return true;
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070090 case Kind::Add:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070091 case Kind::Sub: {
92 auto op = cast<AffineBinaryOpExpr>(this);
93 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine();
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070094 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070095
Chris Lattner1ac20cb2018-07-10 10:59:53 -070096 case Kind::Mul: {
97 // TODO: Canonicalize the constants in binary operators to the RHS when
98 // possible, allowing this to merge into the next case.
99 auto op = cast<AffineBinaryOpExpr>(this);
100 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine() &&
101 (isa<AffineConstantExpr>(op->getLHS()) ||
102 isa<AffineConstantExpr>(op->getRHS()));
103 }
104 case Kind::FloorDiv:
105 case Kind::CeilDiv:
106 case Kind::Mod: {
107 auto op = cast<AffineBinaryOpExpr>(this);
108 return op->getLHS()->isPureAffine() &&
109 isa<AffineConstantExpr>(op->getRHS());
110 }
111 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -0700112}