21 assert(representation == benefit && benefit != ImpossibleToMatchSentinel &&
22 "This pattern match benefit is too large to represent");
27 return representation;
47 :
Pattern(nullptr, RootKind::Any, generatedNames, benefit, context) {}
55 :
Pattern(interfaceID.getAsOpaquePointer(), RootKind::InterfaceID,
56 generatedNames, benefit, context) {}
64 :
Pattern(traitID.getAsOpaquePointer(), RootKind::TraitID, generatedNames,
73 : rootValue(rootValue), rootKind(rootKind), benefit(benefit),
74 contextAndHasBoundedRecursion(context, false) {
75 if (generatedNames.empty())
77 generatedOps.reserve(generatedNames.size());
78 std::transform(generatedNames.begin(), generatedNames.end(),
79 std::back_inserter(generatedOps), [context](StringRef name) {
80 return OperationName(name, context);
89 llvm_unreachable(
"need to implement either matchAndRewrite or one of the "
90 "rewrite functions!");
94 llvm_unreachable(
"need to implement either match or matchAndRewrite!");
98 void RewritePattern::anchor() {}
106 os <<
"<NULL-PDLValue>";
111 os << cast<Attribute>();
114 os << *cast<Operation *>();
120 llvm::interleaveComma(cast<TypeRange>(), os);
126 llvm::interleaveComma(cast<ValueRange>(), os);
160 if (!other.pdlModule)
164 for (
auto &it : other.constraintFunctions)
166 for (
auto &it : other.rewriteFunctions)
168 for (
auto &it : other.configs)
169 configs.emplace_back(std::move(it));
170 for (
auto &it : other.configMap)
171 configMap.insert(it);
175 pdlModule = std::move(other.pdlModule);
180 Block *block = pdlModule->getBody();
182 other.pdlModule->getBody()->getOperations());
185 void PDLPatternModule::attachConfigToPatterns(ModuleOp module,
192 if (op->
hasTrait<SymbolOpInterface::Trait>())
193 configMap[op] = &configSet;
206 constraintFunctions.try_emplace(name, std::move(constraintFn));
215 rewriteFunctions.try_emplace(name, std::move(rewriteFn));
236 llvm::unique_function<
bool(
OpOperand &)
const> functor) {
238 "incorrect number of values to replace operation");
241 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
242 rewriteListener->notifyOperationReplaced(op, newValues);
245 bool replacedAllUses =
true;
246 for (
auto it : llvm::zip(op->
getResults(), newValues)) {
248 replacedAllUses &= std::get<0>(it).use_empty();
251 *allUsesReplaced = replacedAllUses;
259 Block *block,
bool *allUsesReplaced) {
270 "incorrect # of replacement values");
273 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
274 rewriteListener->notifyOperationReplaced(op, newValues);
277 for (
auto it : llvm::zip(op->
getResults(), newValues))
288 assert(op && newOp &&
"expected non-null op");
290 "ops have different number of results");
293 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
294 rewriteListener->notifyOperationReplaced(op, newOp);
307 assert(op->
use_empty() &&
"expected 'op' to have no uses");
308 auto *rewriteListener = dyn_cast_if_present<Listener>(
listener);
311 if (!rewriteListener) {
317 auto eraseSingleOp = [&](
Operation *op) {
322 "expected empty regions");
327 "expected that op has no uses");
329 rewriteListener->notifyOperationRemoved(op);
349 for (
Block *b : llvm::post_order(&r.front())) {
356 erasedBlocks.push_back(b);
358 for (
Block *b : erasedBlocks) {
376 for (
auto &op : llvm::make_early_inc_range(llvm::reverse(*block))) {
377 assert(op.
use_empty() &&
"expected 'op' to have no uses");
385 if (
auto *rewriteListener = dyn_cast_if_present<Listener>(
listener))
386 rewriteListener->notifyOperationModified(op);
395 if (functor(operand))
404 "incorrect # of argument replacement values");
409 "expected 'source' to have no predecessors");
411 if (dest->
end() != before) {
416 "expected 'source' to have no successors");
421 assert(dest->
hasNoSuccessors() &&
"expected 'dest' to have no successors");
425 for (
auto it : llvm::zip(source->
getArguments(), argValues))
469 region.
cloneInto(&parent, before, mapping);
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()
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.
void dropAllUses()
Drop all uses of results of this operation.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Block * getBlock()
Returns the operation block that contains this operation.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Region * getParentRegion()
Returns the region to which the instruction belongs.
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.
Include the generated interface declarations.
bool mayBeGraphRegion(Region ®ion)
Return "true" if the given region may be a graph region without SSA dominance.
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 constexpr auto makeIterable(RangeT &&range)
static bool classof(const OpBuilder::Listener *base)