1 //===- Block.cpp - MLIR Block 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/Block.h" 19 #include "mlir/IR/Builders.h" 20 #include "mlir/IR/Operation.h" 21 using namespace mlir; 22 23 //===----------------------------------------------------------------------===// 24 // BlockArgument 25 //===----------------------------------------------------------------------===// 26 27 /// Returns the number of this argument. 28 unsigned BlockArgument::getArgNumber() { 29 // Arguments are not stored in place, so we have to find it within the list. 30 auto argList = getOwner()->getArguments(); 31 return std::distance(argList.begin(), llvm::find(argList, this)); 32 } 33 34 //===----------------------------------------------------------------------===// 35 // Block 36 //===----------------------------------------------------------------------===// 37 38 Block::~Block() { 39 assert(!verifyInstOrder() && "Expected valid operation ordering."); 40 clear(); 41 llvm::DeleteContainerPointers(arguments); 42 } 43 44 Region *Block::getParent() { return parentValidInstOrderPair.getPointer(); } 45 46 /// Returns the closest surrounding operation that contains this block or 47 /// nullptr if this block is unlinked. 48 Operation *Block::getParentOp() { 49 return getParent() ? getParent()->getParentOp() : nullptr; 50 } 51 52 /// Return if this block is the entry block in the parent region. 53 bool Block::isEntryBlock() { return this == &getParent()->front(); } 54 55 /// Insert this block (which must not already be in a region) right before the 56 /// specified block. 57 void Block::insertBefore(Block *block) { 58 assert(!getParent() && "already inserted into a block!"); 59 assert(block->getParent() && "cannot insert before a block without a parent"); 60 block->getParent()->getBlocks().insert(Region::iterator(block), this); 61 } 62 63 /// Unlink this Block from its parent Region and delete it. 64 void Block::erase() { 65 assert(getParent() && "Block has no parent"); 66 getParent()->getBlocks().erase(this); 67 } 68 69 /// Returns 'op' if 'op' lies in this block, or otherwise finds the 70 /// ancestor operation of 'op' that lies in this block. Returns nullptr if 71 /// the latter fails. 72 Operation *Block::findAncestorInstInBlock(Operation &op) { 73 // Traverse up the operation hierarchy starting from the owner of operand to 74 // find the ancestor operation that resides in the block of 'forInst'. 75 auto *currInst = &op; 76 while (currInst->getBlock() != this) { 77 currInst = currInst->getParentOp(); 78 if (!currInst) 79 return nullptr; 80 } 81 return currInst; 82 } 83 84 /// This drops all operand uses from operations within this block, which is 85 /// an essential step in breaking cyclic dependences between references when 86 /// they are to be deleted. 87 void Block::dropAllReferences() { 88 for (Operation &i : *this) 89 i.dropAllReferences(); 90 } 91 92 void Block::dropAllDefinedValueUses() { 93 for (auto *arg : getArguments()) 94 arg->dropAllUses(); 95 for (auto &op : *this) 96 op.dropAllDefinedValueUses(); 97 dropAllUses(); 98 } 99 100 /// Returns true if the ordering of the child operations is valid, false 101 /// otherwise. 102 bool Block::isInstOrderValid() { return parentValidInstOrderPair.getInt(); } 103 104 /// Invalidates the current ordering of operations. 105 void Block::invalidateInstOrder() { 106 // Validate the current ordering. 107 assert(!verifyInstOrder()); 108 parentValidInstOrderPair.setInt(false); 109 } 110 111 /// Verifies the current ordering of child operations. Returns false if the 112 /// order is valid, true otherwise. 113 bool Block::verifyInstOrder() { 114 // The order is already known to be invalid. 115 if (!isInstOrderValid()) 116 return false; 117 // The order is valid if there are less than 2 operations. 118 if (operations.empty() || std::next(operations.begin()) == operations.end()) 119 return false; 120 121 Operation *prev = nullptr; 122 for (auto &i : *this) { 123 // The previous operation must have a smaller order index than the next as 124 // it appears earlier in the list. 125 if (prev && prev->orderIndex >= i.orderIndex) 126 return true; 127 prev = &i; 128 } 129 return false; 130 } 131 132 /// Recomputes the ordering of child operations within the block. 133 void Block::recomputeInstOrder() { 134 parentValidInstOrderPair.setInt(true); 135 136 // TODO(riverriddle) Have non-congruent indices to reduce the number of times 137 // an insert invalidates the list. 138 unsigned orderIndex = 0; 139 for (auto &op : *this) 140 op.orderIndex = orderIndex++; 141 } 142 143 //===----------------------------------------------------------------------===// 144 // Argument list management. 145 //===----------------------------------------------------------------------===// 146 147 BlockArgument *Block::addArgument(Type type) { 148 auto *arg = new BlockArgument(type, this); 149 arguments.push_back(arg); 150 return arg; 151 } 152 153 /// Add one argument to the argument list for each type specified in the list. 154 auto Block::addArguments(ArrayRef<Type> types) 155 -> llvm::iterator_range<args_iterator> { 156 arguments.reserve(arguments.size() + types.size()); 157 auto initialSize = arguments.size(); 158 for (auto type : types) { 159 addArgument(type); 160 } 161 return {arguments.data() + initialSize, arguments.data() + arguments.size()}; 162 } 163 164 void Block::eraseArgument(unsigned index, bool updatePredTerms) { 165 assert(index < arguments.size()); 166 167 // Delete the argument. 168 delete arguments[index]; 169 arguments.erase(arguments.begin() + index); 170 171 // If we aren't updating predecessors, there is nothing left to do. 172 if (!updatePredTerms) 173 return; 174 175 // Erase this argument from each of the predecessor's terminator. 176 for (auto predIt = pred_begin(), predE = pred_end(); predIt != predE; 177 ++predIt) { 178 auto *predTerminator = (*predIt)->getTerminator(); 179 predTerminator->eraseSuccessorOperand(predIt.getSuccessorIndex(), index); 180 } 181 } 182 183 //===----------------------------------------------------------------------===// 184 // Terminator management 185 //===----------------------------------------------------------------------===// 186 187 /// Get the terminator operation of this block. This function asserts that 188 /// the block has a valid terminator operation. 189 Operation *Block::getTerminator() { 190 assert(!empty() && !back().isKnownNonTerminator()); 191 return &back(); 192 } 193 194 /// Return true if this block has no predecessors. 195 bool Block::hasNoPredecessors() { return pred_begin() == pred_end(); } 196 197 // Indexed successor access. 198 unsigned Block::getNumSuccessors() { 199 return empty() ? 0 : back().getNumSuccessors(); 200 } 201 202 Block *Block::getSuccessor(unsigned i) { 203 assert(i < getNumSuccessors()); 204 return getTerminator()->getSuccessor(i); 205 } 206 207 /// If this block has exactly one predecessor, return it. Otherwise, return 208 /// null. 209 /// 210 /// Note that multiple edges from a single block (e.g. if you have a cond 211 /// branch with the same block as the true/false destinations) is not 212 /// considered to be a single predecessor. 213 Block *Block::getSinglePredecessor() { 214 auto it = pred_begin(); 215 if (it == pred_end()) 216 return nullptr; 217 auto *firstPred = *it; 218 ++it; 219 return it == pred_end() ? firstPred : nullptr; 220 } 221 222 //===----------------------------------------------------------------------===// 223 // Other 224 //===----------------------------------------------------------------------===// 225 226 /// Split the block into two blocks before the specified operation or 227 /// iterator. 228 /// 229 /// Note that all operations BEFORE the specified iterator stay as part of 230 /// the original basic block, and the rest of the operations in the original 231 /// block are moved to the new block, including the old terminator. The 232 /// original block is left without a terminator. 233 /// 234 /// The newly formed Block is returned, and the specified iterator is 235 /// invalidated. 236 Block *Block::splitBlock(iterator splitBefore) { 237 // Start by creating a new basic block, and insert it immediate after this 238 // one in the containing region. 239 auto newBB = new Block(); 240 getParent()->getBlocks().insert(std::next(Region::iterator(this)), newBB); 241 242 // Move all of the operations from the split point to the end of the region 243 // into the new block. 244 newBB->getOperations().splice(newBB->end(), getOperations(), splitBefore, 245 end()); 246 return newBB; 247 } 248 249 //===----------------------------------------------------------------------===// 250 // Predecessors 251 //===----------------------------------------------------------------------===// 252 253 Block *PredecessorIterator::unwrap(BlockOperand &value) { 254 return value.getOwner()->getBlock(); 255 } 256 257 /// Get the successor number in the predecessor terminator. 258 unsigned PredecessorIterator::getSuccessorIndex() const { 259 return I->getOperandNumber(); 260 } 261