blob: 54acedfb4bc7a4bc187c3c33fc37ccd46af240f8 [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));
38 assert(rhs->isSymbolic());
39 // TODO (more verification)
40 break;
41 case Kind::FloorDiv:
42 assert(rhs->isSymbolic());
43 // TODO (more verification)
44 break;
45 case Kind::CeilDiv:
46 assert(rhs->isSymbolic());
47 // TODO (more verification)
48 break;
49 case Kind::Mod:
50 assert(rhs->isSymbolic());
51 // 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 Bondhugula3934d4d2018-07-09 09:00:25 -070060bool AffineExpr::isSymbolic() const {
61 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);
76 return expr->getLHS()->isSymbolic() && expr->getRHS()->isSymbolic();
77 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070078 }
79}
80
Chris Lattner1ac20cb2018-07-10 10:59:53 -070081/// Returns true if this is a pure affine expression, i.e., multiplication,
82/// floordiv, ceildiv, and mod is only allowed w.r.t constants.
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070083bool AffineExpr::isPureAffine() const {
84 switch (getKind()) {
85 case Kind::SymbolId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070086 case Kind::DimId:
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070087 case Kind::Constant:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070088 return true;
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070089 case Kind::Add:
Chris Lattner1ac20cb2018-07-10 10:59:53 -070090 case Kind::Sub: {
91 auto op = cast<AffineBinaryOpExpr>(this);
92 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine();
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070093 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -070094
Chris Lattner1ac20cb2018-07-10 10:59:53 -070095 case Kind::Mul: {
96 // TODO: Canonicalize the constants in binary operators to the RHS when
97 // possible, allowing this to merge into the next case.
98 auto op = cast<AffineBinaryOpExpr>(this);
99 return op->getLHS()->isPureAffine() && op->getRHS()->isPureAffine() &&
100 (isa<AffineConstantExpr>(op->getLHS()) ||
101 isa<AffineConstantExpr>(op->getRHS()));
102 }
103 case Kind::FloorDiv:
104 case Kind::CeilDiv:
105 case Kind::Mod: {
106 auto op = cast<AffineBinaryOpExpr>(this);
107 return op->getLHS()->isPureAffine() &&
108 isa<AffineConstantExpr>(op->getRHS());
109 }
110 }
Uday Bondhugula3934d4d2018-07-09 09:00:25 -0700111}