19 assert(representation == benefit && benefit != ImpossibleToMatchSentinel &&
20 "This pattern match benefit is too large to represent");
25 return representation;
45 :
Pattern(nullptr, RootKind::Any, generatedNames, benefit, context) {}
53 :
Pattern(interfaceID.getAsOpaquePointer(), RootKind::InterfaceID,
54 generatedNames, benefit, context) {}
62 :
Pattern(traitID.getAsOpaquePointer(), RootKind::TraitID, generatedNames,
71 : rootValue(rootValue), rootKind(rootKind), benefit(benefit),
72 contextAndHasBoundedRecursion(context, false) {
73 if (generatedNames.empty())
75 generatedOps.reserve(generatedNames.size());
76 std::transform(generatedNames.begin(), generatedNames.end(),
77 std::back_inserter(generatedOps), [context](StringRef name) {
78 return OperationName(name, context);
87 llvm_unreachable(
"need to implement either matchAndRewrite or one of the "
88 "rewrite functions!");
92 llvm_unreachable(
"need to implement either match or matchAndRewrite!");
96 void RewritePattern::anchor() {}
104 os <<
"<NULL-PDLValue>";
109 os << cast<Attribute>();
112 os << *cast<Operation *>();
118 llvm::interleaveComma(cast<TypeRange>(), os);
124 llvm::interleaveComma(cast<ValueRange>(), os);
158 if (!other.pdlModule)
162 for (
auto &it : other.constraintFunctions)
164 for (
auto &it : other.rewriteFunctions)
166 for (
auto &it : other.configs)
167 configs.emplace_back(std::move(it));
168 for (
auto &it : other.configMap)
169 configMap.insert(it);
173 pdlModule = std::move(other.pdlModule);
178 Block *block = pdlModule->getBody();
180 other.pdlModule->getBody()->getOperations());
183 void PDLPatternModule::attachConfigToPatterns(ModuleOp module,
190 if (op->
hasTrait<SymbolOpInterface::Trait>())
191 configMap[op] = &configSet;
204 constraintFunctions.try_emplace(name, std::move(constraintFn));
213 rewriteFunctions.try_emplace(name, std::move(rewriteFn));
234 llvm::unique_function<
bool(
OpOperand &)
const> functor) {
236 "incorrect number of values to replace operation");
239 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
240 rewriteListener->notifyOperationReplaced(op, newValues);
243 bool replacedAllUses =
true;
244 for (
auto it : llvm::zip(op->
getResults(), newValues)) {
246 replacedAllUses &= std::get<0>(it).use_empty();
249 *allUsesReplaced = replacedAllUses;
257 Block *block,
bool *allUsesReplaced) {
268 "incorrect # of replacement values");
271 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
272 rewriteListener->notifyOperationReplaced(op, newValues);
275 for (
auto it : llvm::zip(op->
getResults(), newValues))
278 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
279 rewriteListener->notifyOperationRemoved(op);
286 assert(op->
use_empty() &&
"expected 'op' to have no uses");
287 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
288 rewriteListener->notifyOperationRemoved(op);
293 for (
auto &op : llvm::make_early_inc_range(llvm::reverse(*block))) {
294 assert(op.
use_empty() &&
"expected 'op' to have no uses");
302 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
303 rewriteListener->notifyOperationModified(op);
312 if (functor(operand))
321 "incorrect # of argument replacement values");
326 "expected 'source' to have no predecessors");
328 if (dest->
end() != before) {
333 "expected 'source' to have no successors");
338 assert(dest->
hasNoSuccessors() &&
"expected 'dest' to have no successors");
342 for (
auto it : llvm::zip(source->
getArguments(), argValues))
369 void RewriterBase::replaceOpWithResultsOfAnotherOp(
Operation *op,
372 "replacement op doesn't match results of original op");
397 region.
cloneInto(&parent, before, mapping);
Block represents an ordered list of Operations.
OpListType::iterator iterator
bool hasNoSuccessors()
Returns true if this blocks has no successors.
unsigned getNumArguments()
void erase()
Unlink this Block from its parent region and delete it.
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.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
This is a utility class for mapping one set of IR entities to another.
MLIRContext is the top-level object for a collection of MLIR operations.
Listener * listener
The optional listener for events of this builder.
This class represents an operand of an operation.
Operation is the basic unit of execution within MLIR.
bool use_empty()
Returns true if this operation has no uses.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Block * getBlock()
Returns the operation block that contains this operation.
result_range getResults()
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 contains a set of configurations for a specific pattern.
This class contains all of the necessary data for a set of PDL patterns, or pattern rewrites specifie...
void registerRewriteFunction(StringRef name, PDLRewriteFunction rewriteFn)
Register a rewrite function with PDL.
void mergeIn(PDLPatternModule &&other)
Merge the state in other into this pattern module.
void registerConstraintFunction(StringRef name, PDLConstraintFunction constraintFn)
Register a constraint function with PDL.
void print(raw_ostream &os) const
Print this value to the provided output stream.
Kind
The underlying kind of a PDL value.
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.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
This class contains all of the data related to a pattern, but does not contain any methods or logic f...
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.
void cloneInto(Region *dest, IRMapping &mapper)
Clone the internal blocks from this region into dest.
BlockListType & getBlocks()
BlockListType::iterator iterator
virtual LogicalResult match(Operation *op) const
Attempt to match against code rooted at the specified operation, which is the same operation code as ...
virtual void rewrite(Operation *op, PatternRewriter &rewriter) const
Rewrite the IR rooted at the specified operation with the result of this pattern, generating any new ...
virtual void replaceOpWithIf(Operation *op, ValueRange newValues, bool *allUsesReplaced, llvm::unique_function< bool(OpOperand &) const > functor)
This method replaces the uses of the results of op with the values in newValues when the provided fun...
virtual void cloneRegionBefore(Region ®ion, Region &parent, Region::iterator before, IRMapping &mapping)
Clone the blocks that belong to "region" before the given position in another region "parent".
virtual void eraseBlock(Block *block)
This method erases all operations in a block.
virtual 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)
This method replaces the results of the operation with the specified list of values.
void updateRootInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around a root update of an operation.
void replaceAllUsesWith(Value from, Value to)
Find uses of from and replace them with to.
void mergeBlocks(Block *source, Block *dest, ValueRange argValues=std::nullopt)
Inline the operations of block 'source' into the end of block 'dest'.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
void replaceOpWithinBlock(Operation *op, ValueRange newValues, Block *block, bool *allUsesReplaced=nullptr)
This method replaces the uses of the results of op with the values in newValues when a use is nested ...
virtual void finalizeRootUpdate(Operation *op)
This method is used to signal the end of a root update on the given operation.
void replaceUsesWithIf(Value from, Value to, function_ref< bool(OpOperand &)> functor)
Find uses of from and replace them with to if the functor returns true.
virtual 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 inlineBlockBefore(Block *source, Block *dest, Block::iterator before, ValueRange argValues=std::nullopt)
Inline the operations of block 'source' into block 'dest' before the given position.
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.
This header declares functions that assit transformations in the MemRef dialect.
std::function< LogicalResult(PatternRewriter &, ArrayRef< PDLValue >)> PDLConstraintFunction
A generic PDL pattern constraint function.
std::function< LogicalResult(PatternRewriter &, PDLResultList &, ArrayRef< PDLValue >)> PDLRewriteFunction
A native PDL rewrite function.
This class represents an efficient way to signal success or failure.
@ 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 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 bool classof(const OpBuilder::Listener *base)