blob: 6b272e0bc633f3ef7f826c38d0cdbd42e748ff17 [file] [log] [blame]
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -07001//===- Statement.cpp - MLIR Statement 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/MLFunction.h"
19#include "mlir/IR/Statements.h"
Uday Bondhugula0b4059b2018-07-24 20:01:16 -070020#include "mlir/IR/StmtVisitor.h"
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070021using namespace mlir;
22
23//===----------------------------------------------------------------------===//
24// Statement
25//===------------------------------------------------------------------===//
26
27// Statements are deleted through the destroy() member because we don't have
28// a virtual destructor.
29Statement::~Statement() {
30 assert(block == nullptr && "statement destroyed but still in a block");
31}
32
33/// Destroy this statement or one of its subclasses.
Tatiana Shpeisman6708b452018-07-24 10:15:13 -070034void Statement::destroy() {
35 switch (this->getKind()) {
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070036 case Kind::Operation:
Tatiana Shpeisman6708b452018-07-24 10:15:13 -070037 delete cast<OperationStmt>(this);
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070038 break;
39 case Kind::For:
Tatiana Shpeisman6708b452018-07-24 10:15:13 -070040 delete cast<ForStmt>(this);
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070041 break;
42 case Kind::If:
Tatiana Shpeisman6708b452018-07-24 10:15:13 -070043 delete cast<IfStmt>(this);
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070044 break;
45 }
46}
47
48MLFunction *Statement::getFunction() const {
49 return this->getBlock()->getFunction();
50}
51
Uday Bondhugula0b4059b2018-07-24 20:01:16 -070052unsigned Statement::getNumNestedLoops() const {
53 struct NestedLoopCounter : public StmtVisitor<NestedLoopCounter> {
54 unsigned numNestedLoops;
55 NestedLoopCounter() : numNestedLoops(0) {}
56 void visitForStmt(const ForStmt *fs) { numNestedLoops++; }
57 };
58
59 NestedLoopCounter nlc;
60 nlc.visit(const_cast<Statement *>(this));
61 return nlc.numNestedLoops;
62}
63
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070064//===----------------------------------------------------------------------===//
65// ilist_traits for Statement
66//===----------------------------------------------------------------------===//
67
68StmtBlock *llvm::ilist_traits<::mlir::Statement>::getContainingBlock() {
69 size_t Offset(
70 size_t(&((StmtBlock *)nullptr->*StmtBlock::getSublistAccess(nullptr))));
71 iplist<Statement> *Anchor(static_cast<iplist<Statement> *>(this));
72 return reinterpret_cast<StmtBlock *>(reinterpret_cast<char *>(Anchor) -
73 Offset);
74}
75
76/// This is a trait method invoked when a statement is added to a block. We
77/// keep the block pointer up to date.
78void llvm::ilist_traits<::mlir::Statement>::addNodeToList(Statement *stmt) {
79 assert(!stmt->getBlock() && "already in a statement block!");
80 stmt->block = getContainingBlock();
81}
82
83/// This is a trait method invoked when a statement is removed from a block.
84/// We keep the block pointer up to date.
85void llvm::ilist_traits<::mlir::Statement>::removeNodeFromList(
86 Statement *stmt) {
87 assert(stmt->block && "not already in a statement block!");
88 stmt->block = nullptr;
89}
90
91/// This is a trait method invoked when a statement is moved from one block
92/// to another. We keep the block pointer up to date.
93void llvm::ilist_traits<::mlir::Statement>::transferNodesFromList(
94 ilist_traits<Statement> &otherList, stmt_iterator first,
95 stmt_iterator last) {
96 // If we are transferring statements within the same block, the block
97 // pointer doesn't need to be updated.
98 StmtBlock *curParent = getContainingBlock();
99 if (curParent == otherList.getContainingBlock())
100 return;
101
102 // Update the 'block' member of each statement.
103 for (; first != last; ++first)
104 first->block = curParent;
105}
106
Uday Bondhugula0b4059b2018-07-24 20:01:16 -0700107/// Remove this statement (and its descendants) from its StmtBlock and delete
108/// all of them.
109/// TODO: erase all descendents for ForStmt/IfStmt.
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700110void Statement::eraseFromBlock() {
111 assert(getBlock() && "Statement has no block");
112 getBlock()->getStatements().erase(this);
113}
114
115//===----------------------------------------------------------------------===//
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700116// IfStmt
117//===----------------------------------------------------------------------===//
118
119IfStmt::~IfStmt() {
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700120 delete thenClause;
121 if (elseClause != nullptr)
122 delete elseClause;
123}