12#include "llvm/ADT/SmallPtrSet.h"
21 assert(representation == benefit && benefit != ImpossibleToMatchSentinel &&
22 "This pattern match benefit is too large to represent");
27 return representation;
40 :
Pattern(OperationName(rootName, context).getAsOpaquePointer(),
41 RootKind::OperationName, generatedNames, benefit, context) {}
49 :
Pattern(
nullptr, RootKind::Any, generatedNames, benefit, context) {}
58 :
Pattern(interfaceID.getAsOpaquePointer(), RootKind::InterfaceID,
59 generatedNames, benefit, context) {}
68 :
Pattern(traitID.getAsOpaquePointer(), RootKind::TraitID, generatedNames,
78 : rootValue(rootValue), rootKind(rootKind), benefit(benefit),
79 contextAndHasBoundedRecursion(context,
false) {
80 if (generatedNames.empty())
82 generatedOps.reserve(generatedNames.size());
83 llvm::append_range(generatedOps,
84 llvm::map_range(generatedNames, [context](StringRef name) {
85 return OperationName(name, context);
94void RewritePattern::anchor() {}
110 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
111 rewriteListener->notifyOperationReplaced(from, to);
118 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
119 rewriteListener->notifyOperationReplaced(from, to);
129 "incorrect # of replacement values");
142 assert(op && newOp &&
"expected non-null op");
144 "ops have different number of results");
156 assert(op->
use_empty() &&
"expected 'op' to have no uses");
157 auto *rewriteListener = dyn_cast_if_present<Listener>(
listener);
165 if (!rewriteListener) {
171 auto eraseSingleOp = [&](
Operation *op) {
176 "expected empty regions");
181 "expected that op has no uses");
183 rewriteListener->notifyOperationErased(op);
206 for (
Block *
b : llvm::post_order_ext(&r.front(), visited)) {
213 erasedBlocks.push_back(
b);
215 for (
Block *
b : erasedBlocks) {
233 assert(block->use_empty() &&
"expected 'block' to have no uses");
235 for (
auto &op : llvm::make_early_inc_range(llvm::reverse(*block))) {
236 assert(op.
use_empty() &&
"expected 'op' to have no uses");
241 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
242 rewriteListener->notifyBlockErased(block);
248 const BitVector &eraseIndices) {
250 "number of op results and bitvector size must match");
254 newResultTypes.reserve(op->
getNumResults() - eraseIndices.count());
256 if (!eraseIndices[
result.getResultNumber()])
257 newResultTypes.push_back(
result.getType());
264 for ([[maybe_unused]]
auto i : llvm::seq<unsigned>(0, op->
getNumRegions()))
267 for (
const auto &[
index, region] : llvm::enumerate(op->
getRegions())) {
275 unsigned nextResultIdx = 0;
277 if (!eraseIndices[i])
278 replacements[i] = newOp->
getResult(nextResultIdx++);
285 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
286 rewriteListener->notifyOperationModified(op);
293 return !preservedUsers.contains(user);
299 bool *allUsesReplaced) {
300 bool allReplaced =
true;
302 bool replace = functor(operand);
305 allReplaced &= replace;
308 *allUsesReplaced = allReplaced;
313 bool *allUsesReplaced) {
314 assert(from.size() == to.size() &&
"incorrect number of replacements");
315 bool allReplaced =
true;
316 for (
auto it : llvm::zip_equal(from, to)) {
319 allUsesReplaced ? &r :
nullptr);
323 *allUsesReplaced = allReplaced;
330 "incorrect # of argument replacement values");
335 "expected 'source' to have no predecessors");
337 if (dest->
end() != before) {
342 "expected 'source' to have no successors");
347 assert(dest->
hasNoSuccessors() &&
"expected 'dest' to have no successors");
351 for (
auto it : llvm::zip(source->
getArguments(), argValues))
360 while (!source->
empty())
370 assert(source->
empty() &&
"expected 'source' to be empty");
394 createBlock(block->getParent(), std::next(block->getIterator()));
397 if (before == block->end())
402 while (before->getBlock() != newBlock)
421 while (!region.
empty())
430 anotherBlock->getIterator());
435 Region *currentRegion = block->getParent();
437 block->moveBefore(region, iterator);
439 listener->notifyBlockInserted(block, currentRegion,
463 assert(iterator != block->end() &&
"cannot move after end of block");
false
Parses a map_entries map type from a string format back into its numeric value.
This class represents an argument of a Block.
Block represents an ordered list of Operations.
OpListType::iterator iterator
bool hasNoSuccessors()
Returns true if this blocks has no successors.
unsigned getNumArguments()
Block * splitBlock(iterator splitBefore)
Split the block into two blocks before the specified operation or iterator.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
OpListType & getOperations()
BlockArgListType getArguments()
bool hasNoPredecessors()
Return true if this block has no predecessors.
MLIRContext is the top-level object for a collection of MLIR operations.
This class represents a saved insertion point.
RAII guard to reset the insertion point of the builder when destroyed.
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
Listener * listener
The optional listener for events of this builder.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
This class represents an operand of an operation.
This is a value defined by a result of an operation.
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
Operation is the basic unit of execution within MLIR.
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
bool use_empty()
Returns true if this operation has no uses.
void dropAllUses()
Drop all uses of results of this operation.
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Block * getBlock()
Returns the operation block that contains this operation.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
unsigned getNumRegions()
Returns the number of regions held by this operation.
Location getLoc()
The source location the operation was defined or derived from.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
OperationName getName()
The name of an operation is the key identifier for it.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
operand_range getOperands()
Returns an iterator on the underlying Value's.
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
result_range getResults()
Region * getParentRegion()
Returns the region to which the instruction belongs.
void erase()
Remove this operation from its parent block and delete it.
unsigned getNumResults()
Return the number of results held by this operation.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
bool isImpossibleToMatch() const
unsigned short getBenefit() const
If the corresponding pattern can match, return its benefit. If the.
Pattern(StringRef rootName, PatternBenefit benefit, MLIRContext *context, ArrayRef< StringRef > generatedNames={})
Construct a pattern with a certain benefit that matches the operation with the given root name.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
BlockListType & getBlocks()
BlockListType::iterator iterator
virtual void eraseBlock(Block *block)
This method erases all operations in a block.
Block * splitBlock(Block *block, Block::iterator before)
Split the operations starting at "before" (inclusive) out of the given block into a new block,...
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
void moveBlockBefore(Block *block, Block *anotherBlock)
Unlink this block and insert it right before existingBlock.
virtual void finalizeOpModification(Operation *op)
This method is used to signal the end of an in-place modification of the given operation.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
Operation * eraseOpResults(Operation *op, const BitVector &eraseIndices)
Erase the specified results of the given operation.
virtual void replaceUsesWithIf(Value from, Value to, function_ref< bool(OpOperand &)> functor, bool *allUsesReplaced=nullptr)
Find uses of from and replace them with to if the functor returns true.
void replaceAllUsesExcept(Value from, Value to, Operation *exceptedUser)
Find uses of from and replace them with to except if the user is exceptedUser.
virtual void inlineBlockBefore(Block *source, Block *dest, Block::iterator before, ValueRange argValues={})
Inline the operations of block 'source' into block 'dest' before the given position.
void moveOpBefore(Operation *op, Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
void mergeBlocks(Block *source, Block *dest, ValueRange argValues={})
Inline the operations of block 'source' into the end of block 'dest'.
void modifyOpInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around an in-place modification of an operation.
void moveOpAfter(Operation *op, Operation *existingOp)
Unlink this operation from its current block and insert it right after existingOp which may be in the...
void inlineRegionBefore(Region ®ion, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
virtual void replaceAllUsesWith(Value from, Value to)
Find uses of from and replace them with to.
void replaceAllOpUsesWith(Operation *from, ValueRange to)
Find uses of from and replace them with to.
This class provides an efficient unique identifier for a specific C++ type.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
use_range getUses() const
Returns a range of all uses, which is useful for iterating over all uses.
Operation * getOwner() const
Return the owner of this operand.
Include the generated interface declarations.
bool mayBeGraphRegion(Region ®ion)
Return "true" if the given region may be a graph region without SSA dominance.
llvm::function_ref< Fn > function_ref
@ RewriterBaseListener
RewriterBase::Listener or user-derived class.
This class represents a listener that may be used to hook into various actions within an OpBuilder.
This represents an operation in an abstracted form, suitable for use with the builder APIs.
Region * addRegion()
Create a region that should be attached to the operation.
This class acts as a special tag that makes the desire to match "any" operation type explicit.
This class acts as a special tag that makes the desire to match any operation that implements a given...
This class acts as a special tag that makes the desire to match any operation that implements a given...
static constexpr auto makeIterable(RangeT &&range)
static bool classof(const OpBuilder::Listener *base)