blob: 1ce1551ea4083d4f898ce3a8be2ca7e1eae43373 [file] [log] [blame]
Chris Lattner4c95a502018-06-23 16:03:42 -07001//===- BasicBlock.cpp - MLIR BasicBlock Class -----------------------------===//
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/BasicBlock.h"
Chris Lattnerf6d80a02018-06-24 11:18:29 -070019#include "mlir/IR/CFGFunction.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070020using namespace mlir;
21
James Molloy61a656c2018-07-22 15:45:24 -070022BasicBlock::BasicBlock() {}
Chris Lattner3a467cc2018-07-01 20:28:00 -070023
24BasicBlock::~BasicBlock() {
25 if (terminator)
26 terminator->eraseFromBlock();
James Molloy61a656c2018-07-22 15:45:24 -070027 for (BBArgument *arg : arguments)
28 delete arg;
29 arguments.clear();
Chris Lattner3a467cc2018-07-01 20:28:00 -070030}
31
Chris Lattner1604e472018-07-23 08:42:19 -070032//===----------------------------------------------------------------------===//
33// Argument list management.
34//===----------------------------------------------------------------------===//
35
36BBArgument *BasicBlock::addArgument(Type *type) {
37 auto *arg = new BBArgument(type, this);
38 arguments.push_back(arg);
39 return arg;
40}
41
42/// Add one argument to the argument list for each type specified in the list.
43auto BasicBlock::addArguments(ArrayRef<Type *> types)
44 -> llvm::iterator_range<args_iterator> {
45 arguments.reserve(arguments.size() + types.size());
46 auto initialSize = arguments.size();
47 for (auto *type : types) {
48 addArgument(type);
49 }
50 return {arguments.data() + initialSize, arguments.data() + arguments.size()};
51}
52
53//===----------------------------------------------------------------------===//
54// Terminator management
55//===----------------------------------------------------------------------===//
56
Chris Lattner3a467cc2018-07-01 20:28:00 -070057void BasicBlock::setTerminator(TerminatorInst *inst) {
Chris Lattner8a9310a2018-08-24 21:13:19 -070058 assert((!inst || !inst->block) && "terminator already inserted into a block");
Chris Lattner3a467cc2018-07-01 20:28:00 -070059 // If we already had a terminator, abandon it.
60 if (terminator)
61 terminator->block = nullptr;
62
63 // Reset our terminator to the new instruction.
64 terminator = inst;
65 if (inst)
66 inst->block = this;
67}
68
Chris Lattner25ce3062018-07-27 11:10:12 -070069/// Return true if this block has no predecessors.
70bool BasicBlock::hasNoPredecessors() const {
71 return pred_begin() == pred_end();
72}
73
74/// If this basic block has exactly one predecessor, return it. Otherwise,
75/// return null.
76///
77/// Note that multiple edges from a single block (e.g. if you have a cond
78/// branch with the same block as the true/false destinations) is not
79/// considered to be a single predecessor.
80BasicBlock *BasicBlock::getSinglePredecessor() {
81 auto it = pred_begin();
82 if (it == pred_end())
83 return nullptr;
84 auto *firstPred = *it;
85 ++it;
86 return it == pred_end() ? firstPred : nullptr;
87}
88
Chris Lattner1604e472018-07-23 08:42:19 -070089//===----------------------------------------------------------------------===//
90// ilist_traits for BasicBlock
91//===----------------------------------------------------------------------===//
92
Chris Lattner3a467cc2018-07-01 20:28:00 -070093mlir::CFGFunction *
94llvm::ilist_traits<::mlir::BasicBlock>::getContainingFunction() {
95 size_t Offset(
96 size_t(&((CFGFunction *)nullptr->*CFGFunction::getSublistAccess(nullptr))));
97 iplist<BasicBlock> *Anchor(static_cast<iplist<BasicBlock> *>(this));
98 return reinterpret_cast<CFGFunction *>(reinterpret_cast<char *>(Anchor) -
99 Offset);
100}
101
102/// This is a trait method invoked when a basic block is added to a function.
103/// We keep the function pointer up to date.
104void llvm::ilist_traits<::mlir::BasicBlock>::
105addNodeToList(BasicBlock *block) {
106 assert(!block->function && "already in a function!");
107 block->function = getContainingFunction();
108}
109
110/// This is a trait method invoked when an instruction is removed from a
111/// function. We keep the function pointer up to date.
112void llvm::ilist_traits<::mlir::BasicBlock>::
113removeNodeFromList(BasicBlock *block) {
114 assert(block->function && "not already in a function!");
115 block->function = nullptr;
116}
117
118/// This is a trait method invoked when an instruction is moved from one block
119/// to another. We keep the block pointer up to date.
120void llvm::ilist_traits<::mlir::BasicBlock>::
121transferNodesFromList(ilist_traits<BasicBlock> &otherList,
122 block_iterator first, block_iterator last) {
123 // If we are transferring instructions within the same function, the parent
124 // pointer doesn't need to be updated.
125 CFGFunction *curParent = getContainingFunction();
126 if (curParent == otherList.getContainingFunction())
127 return;
128
129 // Update the 'function' member of each BasicBlock.
130 for (; first != last; ++first)
131 first->function = curParent;
Chris Lattner4c95a502018-06-23 16:03:42 -0700132}
Chris Lattner8a9310a2018-08-24 21:13:19 -0700133
134//===----------------------------------------------------------------------===//
135// Manipulators
136//===----------------------------------------------------------------------===//
137
138/// Unlink this BasicBlock from its CFGFunction and delete it.
139void BasicBlock::eraseFromFunction() {
140 assert(getFunction() && "BasicBlock has no parent");
141 getFunction()->getBlocks().erase(this);
142}
143
144/// Split the basic block into two basic blocks before the specified
145/// instruction or iterator.
146///
147/// Note that all instructions BEFORE the specified iterator stay as part of
148/// the original basic block, an unconditional branch is added to the original
149/// block (going to the new block), and the rest of the instructions in the
150/// original block are moved to the new BB, including the old terminator. The
151/// newly formed BasicBlock is returned.
152///
153/// This function invalidates the specified iterator.
154BasicBlock *BasicBlock::splitBasicBlock(iterator splitBefore) {
155 // Start by creating a new basic block, and insert it immediate after this
156 // one in the containing function.
157 auto newBB = new BasicBlock();
158 getFunction()->getBlocks().insert(++CFGFunction::iterator(this), newBB);
159
160 // Create an unconditional branch to the new block, and move our terminator
161 // to the new block.
162 auto *branchLoc =
163 splitBefore == end() ? getTerminator()->getLoc() : splitBefore->getLoc();
164 auto oldTerm = getTerminator();
165 setTerminator(BranchInst::create(branchLoc, newBB));
166 newBB->setTerminator(oldTerm);
167
168 // Move all of the operations from the split point to the end of the function
169 // into the new block.
170 newBB->getOperations().splice(newBB->end(), getOperations(), splitBefore,
171 end());
172 return newBB;
173}