12 #include "llvm/ADT/BitVector.h" 20 assert(!
verifyOpOrder() &&
"Expected valid operation ordering.");
40 assert(!
getParent() &&
"already inserted into a block!");
41 assert(block->
getParent() &&
"cannot insert before a block without a parent");
48 assert(block->
getParent() &&
"cannot insert before a block without a parent");
55 assert(
getParent() &&
"Block has no parent");
66 while (currOp->getBlock() !=
this) {
85 for (
auto &op : *
this)
86 op.dropAllDefinedValueUses();
98 parentValidOpOrderPair.setInt(
false);
108 if (operations.empty() || std::next(operations.begin()) == operations.end())
112 for (
auto &i : *
this) {
115 if (prev && prev->orderIndex != Operation::kInvalidOrderIdx &&
116 prev->orderIndex >= i.orderIndex)
125 parentValidOpOrderPair.setInt(
true);
127 unsigned orderIndex = 0;
128 for (
auto &op : *
this)
129 op.orderIndex = (orderIndex += Operation::kOrderStride);
142 BlockArgument arg = BlockArgument::create(type,
this, arguments.size(), loc);
143 arguments.push_back(arg);
150 assert(types.size() == locs.size() &&
151 "incorrect number of block argument locations");
152 size_t initialSize = arguments.size();
153 arguments.reserve(initialSize + types.size());
155 for (
auto typeAndLoc : llvm::zip(types, locs))
156 addArgument(std::get<0>(typeAndLoc), std::get<1>(typeAndLoc));
157 return {arguments.data() + initialSize, arguments.data() + arguments.size()};
161 assert(index <= arguments.size() &&
"invalid insertion index");
163 auto arg = BlockArgument::create(type,
this, index, loc);
164 arguments.insert(arguments.begin() + index, arg);
169 arg.setArgNumber(index++);
177 "cannot insert arguments to blocks with predecessors");
182 assert(index < arguments.size());
183 arguments[index].destroy();
184 arguments.erase(arguments.begin() + index);
186 arg.setArgNumber(index++);
191 for (
unsigned i : argIndices)
202 auto firstDead = llvm::find_if(arguments, shouldEraseFn);
203 if (firstDead == arguments.end())
208 unsigned index = firstDead->getArgNumber();
209 firstDead->destroy();
212 for (
auto it = std::next(firstDead), e = arguments.end(); it != e; ++it) {
214 if (shouldEraseFn(*it)) {
217 it->setArgNumber(index++);
221 arguments.erase(firstDead, arguments.end());
231 assert(!
empty() &&
back().mightHaveTrait<OpTrait::IsTerminator>());
255 auto *firstPred = *it;
257 return it ==
pred_end() ? firstPred :
nullptr;
268 auto *firstPred = *it;
269 for (++it; it != e; ++it)
270 if (*it != firstPred)
292 auto *newBB =
new Block();
297 newBB->getOperations().splice(newBB->end(),
getOperations(), splitBefore,
312 return I->getOperandNumber();
322 if (block->
empty() || llvm::hasSingleElement(*block->
getParent()))
339 if ((count = blocks.size()))
340 base = blocks.data();
344 :
BlockRange(successors.begin().getBase(), successors.size()) {}
348 if (
auto *operand =
object.dyn_cast<BlockOperand *>())
349 return {operand + index};
350 return {
object.dyn_cast<
Block *
const *>() + index};
354 Block *BlockRange::dereference_iterator(
OwnerT object, ptrdiff_t index) {
355 if (
const auto *operand =
object.dyn_cast<BlockOperand *>())
356 return operand[index].get();
357 return object.dyn_cast<
Block *
const *>()[index];
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
Block * getSuccessor(unsigned i)
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Operation is a basic unit of execution within MLIR.
BlockRange(ArrayRef< Block *> blocks=llvm::None)
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
BlockListType & getBlocks()
Block represents an ordered list of Operations.
iterator_range< args_iterator > addArguments(TypeRange types, ArrayRef< Location > locs)
Add one argument to the argument list for each type specified in the list.
void moveBefore(Block *block)
Unlink this block from its current region and insert it right before the specific block...
OpListType & getOperations()
void invalidateOpOrder()
Invalidates the current ordering of operations.
BlockArgument insertArgument(args_iterator it, Type type, Location loc)
Insert one value to the position in the argument list indicated by the given iterator.
BlockListType::iterator iterator
A block operand represents an operand that holds a reference to a Block, e.g.
iterator_range< pred_iterator > getPredecessors()
unsigned getNumSuccessors()
unsigned getArgNumber() const
Returns the number of this argument.
Block * getBlock()
Returns the operation block that contains this operation.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
void dropAllUses()
Drop all uses of this object from their respective owners.
Block * getUniquePredecessor()
If this block has a unique predecessor, i.e., all incoming edges originate from one block...
void eraseArguments(ArrayRef< unsigned > argIndices)
Erases the arguments listed in argIndices and removes them from the argument list.
BlockArgListType::iterator args_iterator
void erase()
Unlink this Block from its parent region and delete it.
OpListType::iterator iterator
Block * getSuccessor(unsigned index)
unsigned getNumArguments()
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
void eraseArgument(unsigned index)
Erase the argument at 'index' and remove it from the argument list.
This class provides an abstraction over the various different ranges of value types.
bool isEntryBlock()
Return if this block is the entry block in the parent region.
MutableArrayRef< BlockOperand > getBlockOperands()
BlockArgListType getArguments()
This class represents an argument of a Block.
void dropAllDefinedValueUses()
This drops all uses of values defined in this block or in the blocks of nested regions wherever the u...
This class implements the successor iterators for Block.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isOpOrderValid()
Returns true if the ordering of the child operations is valid, false otherwise.
Operation * getParentOp()
Return the parent operation this region is attached to.
unsigned getSuccessorIndex() const
Get the successor number in the predecessor terminator.
This class implements iteration on the types of a given range of values.
Operation * getTerminator()
Get the terminator operation of this block.
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
ValueTypeRange< BlockArgListType > getArgumentTypes()
Return a range containing the types of the arguments for this block.
void dropAllReferences()
This drops all operand uses from operations within this block, which is an essential step in breaking...
unsigned getNumSuccessors()
void recomputeOpOrder()
Recomputes the ordering of child operations within the block.
Operation * getOwner() const
Return the owner of this operand.
This class provides an abstraction over the different types of ranges over Blocks.
Block * getSinglePredecessor()
If this block has exactly one predecessor, return it.
void insertBefore(Block *block)
Insert this block (which must not already be in a region) right before the specified block...
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
Operation * findAncestorOpInBlock(Operation &op)
Returns 'op' if 'op' lies in this block, or otherwise finds the ancestor operation of 'op' that lies ...
bool verifyOpOrder()
Verifies the current ordering of child operations matches the validOpOrder flag.
Block * splitBlock(iterator splitBefore)
Split the block into two blocks before the specified operation or iterator.
pred_iterator pred_begin()