16 #include "llvm/ADT/MapVector.h"
17 #include "llvm/ADT/ScopedHashTable.h"
18 #include "llvm/ADT/Sequence.h"
19 #include "llvm/ADT/SetVector.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/TypeSwitch.h"
24 #define GEN_PASS_DEF_CONVERTPDLTOPDLINTERP
25 #include "mlir/Conversion/Passes.h.inc"
38 struct PatternLowering {
40 PatternLowering(pdl_interp::FuncOp matcherFunc, ModuleOp rewriterModule,
45 void lower(ModuleOp module);
48 using ValueMap = llvm::ScopedHashTable<Position *, Value>;
49 using ValueMapScope = llvm::ScopedHashTableScope<Position *, Value>;
54 Block *block =
nullptr);
77 SymbolRefAttr generateRewriter(pdl::PatternOp pattern,
81 void generateRewriter(pdl::ApplyNativeRewriteOp rewriteOp,
84 void generateRewriter(pdl::AttributeOp attrOp,
87 void generateRewriter(pdl::EraseOp eraseOp,
90 void generateRewriter(pdl::OperationOp operationOp,
93 void generateRewriter(pdl::RangeOp rangeOp,
96 void generateRewriter(pdl::ReplaceOp replaceOp,
99 void generateRewriter(pdl::ResultOp resultOp,
102 void generateRewriter(pdl::ResultsOp resultOp,
105 void generateRewriter(pdl::TypeOp typeOp,
108 void generateRewriter(pdl::TypesOp typeOp,
115 void generateOperationResultTypeRewriter(
118 bool &hasInferredResultTypes);
124 pdl_interp::FuncOp matcherFunc;
128 ModuleOp rewriterModule;
159 PatternLowering::PatternLowering(
160 pdl_interp::FuncOp matcherFunc, ModuleOp rewriterModule,
162 : builder(matcherFunc.
getContext()), matcherFunc(matcherFunc),
163 rewriterModule(rewriterModule), rewriterSymbolTable(rewriterModule),
164 configMap(configMap) {}
166 void PatternLowering::lower(ModuleOp module) {
171 ValueMapScope topLevelValueScope(values);
175 Block *matcherEntryBlock = &matcherFunc.
front();
176 values.insert(predicateBuilder.getRoot(), matcherEntryBlock->
getArgument(0));
179 std::unique_ptr<MatcherNode> root = MatcherNode::generateMatcherTree(
180 module, predicateBuilder, valueToPosition);
181 Block *firstMatcherBlock = generateMatcher(*root, matcherFunc.getBody());
182 assert(failureBlockStack.empty() &&
"failed to empty the stack");
187 firstMatcherBlock->
erase();
195 ValueMapScope scope(values);
199 if (isa<ExitNode>(node)) {
200 builder.setInsertionPointToEnd(block);
201 builder.create<pdl_interp::FinalizeOp>(matcherFunc.getLoc());
211 std::unique_ptr<MatcherNode> &failureNode = node.
getFailureNode();
214 failureBlock = generateMatcher(*failureNode, region);
215 failureBlockStack.push_back(failureBlock);
217 assert(!failureBlockStack.empty() &&
"expected valid failure block");
218 failureBlock = failureBlockStack.
back();
223 Block *currentBlock = block;
225 Value val = position ? getValueAt(currentBlock, position) :
Value();
229 bool isOperationValue = val && isa<pdl::OperationType>(val.
getType());
230 if (isOperationValue)
236 this->generate(derivedNode, currentBlock, val);
239 generate(successNode, currentBlock);
244 while (failureBlockStack.back() != failureBlock) {
245 failureBlockStack.pop_back();
246 assert(!failureBlockStack.empty() &&
"unable to locate failure block");
251 failureBlockStack.pop_back();
253 if (isOperationValue)
260 if (
Value val = values.lookup(pos))
266 parentVal = getValueAt(currentBlock, parent);
269 Location loc = parentVal ? parentVal.
getLoc() : builder.getUnknownLoc();
270 builder.setInsertionPointToEnd(currentBlock);
274 auto *operationPos = cast<OperationPosition>(pos);
275 if (operationPos->isOperandDefiningOp())
277 value = builder.create<pdl_interp::GetDefiningOpOp>(
278 loc, builder.getType<pdl::OperationType>(), parentVal);
285 auto *usersPos = cast<UsersPosition>(pos);
290 if (isa<pdl::RangeType>(parentVal.
getType()) &&
291 usersPos->useRepresentative())
292 value = builder.create<pdl_interp::ExtractOp>(loc, parentVal, 0);
297 value = builder.create<pdl_interp::GetUsersOp>(loc, value);
301 assert(!failureBlockStack.empty() &&
"expected valid failure block");
302 auto foreach = builder.create<pdl_interp::ForEachOp>(
303 loc, parentVal, failureBlockStack.back(),
true);
304 value =
foreach.getLoopVariable();
307 Block *continueBlock = builder.createBlock(&
foreach.getRegion());
308 builder.create<pdl_interp::ContinueOp>(loc);
309 failureBlockStack.
push_back(continueBlock);
311 currentBlock = &
foreach.getRegion().
front();
315 auto *operandPos = cast<OperandPosition>(pos);
316 value = builder.create<pdl_interp::GetOperandOp>(
317 loc, builder.getType<pdl::ValueType>(), parentVal,
318 operandPos->getOperandNumber());
322 auto *operandPos = cast<OperandGroupPosition>(pos);
323 Type valueTy = builder.getType<pdl::ValueType>();
324 value = builder.create<pdl_interp::GetOperandsOp>(
326 parentVal, operandPos->getOperandGroupNumber());
330 auto *attrPos = cast<AttributePosition>(pos);
331 value = builder.create<pdl_interp::GetAttributeOp>(
332 loc, builder.getType<pdl::AttributeType>(), parentVal,
333 attrPos->getName().strref());
337 if (isa<pdl::AttributeType>(parentVal.getType()))
338 value = builder.create<pdl_interp::GetAttributeTypeOp>(loc, parentVal);
340 value = builder.create<pdl_interp::GetValueTypeOp>(loc, parentVal);
344 auto *resPos = cast<ResultPosition>(pos);
345 value = builder.create<pdl_interp::GetResultOp>(
346 loc, builder.getType<pdl::ValueType>(), parentVal,
347 resPos->getResultNumber());
351 auto *resPos = cast<ResultGroupPosition>(pos);
352 Type valueTy = builder.getType<pdl::ValueType>();
353 value = builder.create<pdl_interp::GetResultsOp>(
355 parentVal, resPos->getResultGroupNumber());
359 auto *attrPos = cast<AttributeLiteralPosition>(pos);
361 builder.create<pdl_interp::CreateAttributeOp>(loc, attrPos->getValue());
365 auto *typePos = cast<TypeLiteralPosition>(pos);
366 Attribute rawTypeAttr = typePos->getValue();
367 if (TypeAttr typeAttr = dyn_cast<TypeAttr>(rawTypeAttr))
368 value = builder.create<pdl_interp::CreateTypeOp>(loc, typeAttr);
370 value = builder.create<pdl_interp::CreateTypesOp>(
371 loc, cast<ArrayAttr>(rawTypeAttr));
377 auto *constrResPos = cast<ConstraintPosition>(pos);
378 auto i = constraintOpMap.find(constrResPos->getQuestion());
379 assert(i != constraintOpMap.end());
380 value = i->second->getResult(constrResPos->getIndex());
384 llvm_unreachable(
"Generating unknown Position getter");
388 values.insert(pos, value);
392 void PatternLowering::generate(
BoolNode *boolNode,
Block *¤tBlock,
402 if (
auto *equalToQuestion = dyn_cast<EqualToQuestion>(question)) {
403 args = {getValueAt(currentBlock, equalToQuestion->getValue())};
404 }
else if (
auto *cstQuestion = dyn_cast<ConstraintQuestion>(question)) {
405 for (
Position *position : cstQuestion->getArgs())
406 args.push_back(getValueAt(currentBlock, position));
411 Block *failure = failureBlockStack.
back();
414 builder.setInsertionPointToEnd(currentBlock);
418 builder.create<pdl_interp::IsNotNullOp>(loc, val, success, failure);
421 auto *opNameAnswer = cast<OperationNameAnswer>(answer);
422 builder.create<pdl_interp::CheckOperationNameOp>(
423 loc, val, opNameAnswer->getValue().getStringRef(), success, failure);
427 auto *ans = cast<TypeAnswer>(answer);
428 if (isa<pdl::RangeType>(val.getType()))
429 builder.create<pdl_interp::CheckTypesOp>(
430 loc, val, llvm::cast<ArrayAttr>(ans->getValue()), success, failure);
432 builder.create<pdl_interp::CheckTypeOp>(
433 loc, val, llvm::cast<TypeAttr>(ans->getValue()), success, failure);
437 auto *ans = cast<AttributeAnswer>(answer);
438 builder.create<pdl_interp::CheckAttributeOp>(loc, val, ans->getValue(),
444 builder.create<pdl_interp::CheckOperandCountOp>(
445 loc, val, cast<UnsignedAnswer>(answer)->getValue(),
451 builder.create<pdl_interp::CheckResultCountOp>(
452 loc, val, cast<UnsignedAnswer>(answer)->getValue(),
457 bool trueAnswer = isa<TrueAnswer>(answer);
458 builder.create<pdl_interp::AreEqualOp>(loc, val, args.front(),
459 trueAnswer ? success : failure,
460 trueAnswer ? failure : success);
464 auto *cstQuestion = cast<ConstraintQuestion>(question);
465 auto applyConstraintOp = builder.create<pdl_interp::ApplyConstraintOp>(
466 loc, cstQuestion->getResultTypes(), cstQuestion->getName(), args,
467 cstQuestion->getIsNegated(), success, failure);
469 constraintOpMap.insert({cstQuestion, applyConstraintOp});
473 llvm_unreachable(
"Generating unknown Predicate operation");
481 template <
typename OpT,
typename PredT,
typename ValT =
typename PredT::KeyTy>
483 llvm::MapVector<Qualifier *, Block *> &dests) {
484 std::vector<ValT> values;
485 std::vector<Block *> blocks;
486 values.reserve(dests.size());
487 blocks.reserve(dests.size());
488 for (
const auto &it : dests) {
489 blocks.push_back(it.second);
490 values.push_back(cast<PredT>(it.first)->getValue());
492 builder.
create<OpT>(val.
getLoc(), val, values, defaultDest, blocks);
495 void PatternLowering::generate(
SwitchNode *switchNode,
Block *currentBlock,
499 Block *defaultDest = failureBlockStack.
back();
508 llvm::seq<unsigned>(0, switchNode->
getChildren().size()));
509 llvm::sort(sortedChildren, [&](
unsigned lhs,
unsigned rhs) {
510 return cast<UnsignedAnswer>(switchNode->
getChild(lhs).first)->getValue() >
511 cast<UnsignedAnswer>(switchNode->
getChild(rhs).first)->getValue();
531 failureBlockStack.push_back(defaultDest);
533 for (
unsigned idx : sortedChildren) {
534 auto &child = switchNode->
getChild(idx);
535 Block *childBlock = generateMatcher(*child.second, *region);
536 Block *predicateBlock = builder.createBlock(childBlock);
537 builder.setInsertionPointToEnd(predicateBlock);
538 unsigned ans = cast<UnsignedAnswer>(child.first)->getValue();
541 builder.create<pdl_interp::CheckOperandCountOp>(
542 loc, val, ans,
true, childBlock, defaultDest);
545 builder.create<pdl_interp::CheckResultCountOp>(
546 loc, val, ans,
true, childBlock, defaultDest);
549 llvm_unreachable(
"Generating invalid AtLeast operation");
551 failureBlockStack.back() = predicateBlock;
553 Block *firstPredicateBlock = failureBlockStack.pop_back_val();
556 firstPredicateBlock->
erase();
562 llvm::MapVector<Qualifier *, Block *> children;
564 children.insert({it.first, generateMatcher(*it.second, *region)});
565 builder.setInsertionPointToEnd(currentBlock);
570 int32_t>(val, defaultDest, builder, children);
573 int32_t>(val, defaultDest, builder, children);
579 if (isa<pdl::RangeType>(val.getType())) {
580 return createSwitchOp<pdl_interp::SwitchTypesOp, TypeAnswer>(
581 val, defaultDest, builder, children);
583 return createSwitchOp<pdl_interp::SwitchTypeOp, TypeAnswer>(
584 val, defaultDest, builder, children);
586 return createSwitchOp<pdl_interp::SwitchAttributeOp, AttributeAnswer>(
587 val, defaultDest, builder, children);
589 llvm_unreachable(
"Generating unknown switch predicate.");
593 void PatternLowering::generate(
SuccessNode *successNode,
Block *¤tBlock) {
594 pdl::PatternOp pattern = successNode->
getPattern();
600 SymbolRefAttr rewriterFuncRef = generateRewriter(pattern, usedMatchValues);
603 std::vector<Value> mappedMatchValues;
604 mappedMatchValues.reserve(usedMatchValues.size());
605 for (
Position *position : usedMatchValues)
606 mappedMatchValues.push_back(getValueAt(currentBlock, position));
611 pattern.getRewriter().getBodyRegion().getOps<pdl::OperationOp>())
612 generatedOps.push_back(*op.getOpName());
613 ArrayAttr generatedOpsAttr;
614 if (!generatedOps.empty())
615 generatedOpsAttr = builder.getStrArrayAttr(generatedOps);
618 StringAttr rootKindAttr;
619 if (pdl::OperationOp rootOp = root.
getDefiningOp<pdl::OperationOp>())
620 if (std::optional<StringRef> rootKind = rootOp.getOpName())
621 rootKindAttr = builder.getStringAttr(*rootKind);
623 builder.setInsertionPointToEnd(currentBlock);
624 auto matchOp = builder.create<pdl_interp::RecordMatchOp>(
625 pattern.getLoc(), mappedMatchValues, locOps.getArrayRef(),
626 rewriterFuncRef, rootKindAttr, generatedOpsAttr, pattern.getBenefitAttr(),
627 failureBlockStack.back());
631 configMap->try_emplace(matchOp, configMap->lookup(pattern));
634 SymbolRefAttr PatternLowering::generateRewriter(
636 builder.setInsertionPointToEnd(rewriterModule.getBody());
637 auto rewriterFunc = builder.create<pdl_interp::FuncOp>(
638 pattern.getLoc(),
"pdl_generated_rewriter",
639 builder.getFunctionType(std::nullopt, std::nullopt));
640 rewriterSymbolTable.insert(rewriterFunc);
643 builder.setInsertionPointToEnd(&rewriterFunc.front());
647 auto mapRewriteValue = [&](
Value oldValue) {
648 Value &newValue = rewriteValues[oldValue];
653 Operation *oldOp = oldValue.getDefiningOp();
654 if (pdl::AttributeOp attrOp = dyn_cast<pdl::AttributeOp>(oldOp)) {
655 if (
Attribute value = attrOp.getValueAttr()) {
656 return newValue = builder.create<pdl_interp::CreateAttributeOp>(
657 attrOp.getLoc(), value);
659 }
else if (pdl::TypeOp typeOp = dyn_cast<pdl::TypeOp>(oldOp)) {
660 if (TypeAttr type = typeOp.getConstantTypeAttr()) {
661 return newValue = builder.create<pdl_interp::CreateTypeOp>(
662 typeOp.getLoc(), type);
664 }
else if (pdl::TypesOp typeOp = dyn_cast<pdl::TypesOp>(oldOp)) {
665 if (ArrayAttr type = typeOp.getConstantTypesAttr()) {
666 return newValue = builder.create<pdl_interp::CreateTypesOp>(
667 typeOp.getLoc(), typeOp.getType(), type);
672 Position *inputPos = valueToPosition.lookup(oldValue);
673 assert(inputPos &&
"expected value to be a pattern input");
674 usedMatchValues.push_back(inputPos);
675 return newValue = rewriterFunc.front().addArgument(oldValue.getType(),
681 pdl::RewriteOp rewriter = pattern.getRewriter();
682 if (StringAttr rewriteName = rewriter.getNameAttr()) {
684 if (rewriter.getRoot())
685 args.push_back(mapRewriteValue(rewriter.getRoot()));
687 llvm::map_range(rewriter.getExternalArgs(), mapRewriteValue);
688 args.append(mappedArgs.begin(), mappedArgs.end());
689 builder.create<pdl_interp::ApplyRewriteOp>(
690 rewriter.getLoc(),
TypeRange(), rewriteName, args);
693 for (
Operation &rewriteOp : *rewriter.getBody()) {
695 .Case<pdl::ApplyNativeRewriteOp, pdl::AttributeOp, pdl::EraseOp,
696 pdl::OperationOp, pdl::RangeOp, pdl::ReplaceOp, pdl::ResultOp,
697 pdl::ResultsOp, pdl::TypeOp, pdl::TypesOp>([&](
auto op) {
698 this->generateRewriter(op, rewriteValues, mapRewriteValue);
704 rewriterFunc.setType(builder.getFunctionType(
705 llvm::to_vector<8>(rewriterFunc.front().getArgumentTypes()),
708 builder.create<pdl_interp::FinalizeOp>(rewriter.getLoc());
710 builder.getContext(),
711 pdl_interp::PDLInterpDialect::getRewriterModuleName(),
715 void PatternLowering::generateRewriter(
719 for (
Value argument : rewriteOp.getArgs())
720 arguments.push_back(mapRewriteValue(argument));
721 auto interpOp = builder.create<pdl_interp::ApplyRewriteOp>(
722 rewriteOp.getLoc(), rewriteOp.getResultTypes(), rewriteOp.getNameAttr(),
724 for (
auto it : llvm::zip(rewriteOp.getResults(), interpOp.getResults()))
725 rewriteValues[std::get<0>(it)] = std::get<1>(it);
728 void PatternLowering::generateRewriter(
731 Value newAttr = builder.create<pdl_interp::CreateAttributeOp>(
732 attrOp.getLoc(), attrOp.getValueAttr());
733 rewriteValues[attrOp] = newAttr;
736 void PatternLowering::generateRewriter(
739 builder.create<pdl_interp::EraseOp>(eraseOp.getLoc(),
740 mapRewriteValue(eraseOp.getOpValue()));
743 void PatternLowering::generateRewriter(
747 for (
Value operand : operationOp.getOperandValues())
748 operands.push_back(mapRewriteValue(operand));
751 for (
Value attr : operationOp.getAttributeValues())
752 attributes.push_back(mapRewriteValue(attr));
754 bool hasInferredResultTypes =
false;
756 generateOperationResultTypeRewriter(operationOp, mapRewriteValue, types,
757 rewriteValues, hasInferredResultTypes);
760 Location loc = operationOp.getLoc();
761 Value createdOp = builder.create<pdl_interp::CreateOperationOp>(
762 loc, *operationOp.getOpName(), types, hasInferredResultTypes, operands,
763 attributes, operationOp.getAttributeValueNames());
764 rewriteValues[operationOp.getOp()] = createdOp;
770 if (resultTys.size() == 1 && isa<pdl::RangeType>(resultTys[0].
getType())) {
771 Value &type = rewriteValues[resultTys[0]];
773 auto results = builder.create<pdl_interp::GetResultsOp>(loc, createdOp);
774 type = builder.create<pdl_interp::GetValueTypeOp>(loc, results);
780 bool seenVariableLength =
false;
781 Type valueTy = builder.getType<pdl::ValueType>();
784 Value &type = rewriteValues[it.value()];
787 bool isVariadic = isa<pdl::RangeType>(it.value().getType());
788 seenVariableLength |= isVariadic;
793 if (seenVariableLength)
794 resultVal = builder.create<pdl_interp::GetResultsOp>(
795 loc, isVariadic ? valueRangeTy : valueTy, createdOp, it.index());
797 resultVal = builder.create<pdl_interp::GetResultOp>(
798 loc, valueTy, createdOp, it.index());
799 type = builder.create<pdl_interp::GetValueTypeOp>(loc, resultVal);
803 void PatternLowering::generateRewriter(
807 for (
Value operand : rangeOp.getArguments())
808 replOperands.push_back(mapRewriteValue(operand));
809 rewriteValues[rangeOp] = builder.create<pdl_interp::CreateRangeOp>(
810 rangeOp.getLoc(), rangeOp.getType(), replOperands);
813 void PatternLowering::generateRewriter(
821 if (
Value replOp = replaceOp.getReplOperation()) {
823 auto opOp = replaceOp.getOpValue().getDefiningOp<pdl::OperationOp>();
824 if (!opOp || !opOp.getTypeValues().empty()) {
825 replOperands.push_back(builder.create<pdl_interp::GetResultsOp>(
826 replOp.getLoc(), mapRewriteValue(replOp)));
829 for (
Value operand : replaceOp.getReplValues())
830 replOperands.push_back(mapRewriteValue(operand));
834 if (replOperands.empty()) {
835 builder.create<pdl_interp::EraseOp>(
836 replaceOp.getLoc(), mapRewriteValue(replaceOp.getOpValue()));
840 builder.create<pdl_interp::ReplaceOp>(replaceOp.getLoc(),
841 mapRewriteValue(replaceOp.getOpValue()),
845 void PatternLowering::generateRewriter(
848 rewriteValues[resultOp] = builder.create<pdl_interp::GetResultOp>(
849 resultOp.getLoc(), builder.getType<pdl::ValueType>(),
850 mapRewriteValue(resultOp.getParent()), resultOp.getIndex());
853 void PatternLowering::generateRewriter(
856 rewriteValues[resultOp] = builder.create<pdl_interp::GetResultsOp>(
857 resultOp.getLoc(), resultOp.getType(),
858 mapRewriteValue(resultOp.getParent()), resultOp.getIndex());
861 void PatternLowering::generateRewriter(
866 if (TypeAttr typeAttr = typeOp.getConstantTypeAttr()) {
867 rewriteValues[typeOp] =
868 builder.create<pdl_interp::CreateTypeOp>(typeOp.getLoc(), typeAttr);
872 void PatternLowering::generateRewriter(
877 if (ArrayAttr typeAttr = typeOp.getConstantTypesAttr()) {
878 rewriteValues[typeOp] = builder.create<pdl_interp::CreateTypesOp>(
879 typeOp.getLoc(), typeOp.getType(), typeAttr);
883 void PatternLowering::generateOperationResultTypeRewriter(
886 bool &hasInferredResultTypes) {
887 Block *rewriterBlock = op->getBlock();
893 auto tryResolveResultTypes = [&] {
894 types.reserve(resultTypeValues.size());
896 Value resultType = it.value();
899 if (
Value existingRewriteValue = rewriteValues.lookup(resultType)) {
900 types.push_back(existingRewriteValue);
906 types.push_back(mapRewriteValue(resultType));
917 if (!resultTypeValues.empty() && succeeded(tryResolveResultTypes()))
921 if (op.hasTypeInference()) {
922 hasInferredResultTypes =
true;
928 for (
OpOperand &use : op.getOp().getUses()) {
931 pdl::ReplaceOp replOpUser = dyn_cast<pdl::ReplaceOp>(use.getOwner());
932 if (!replOpUser || use.getOperandNumber() == 0)
938 Value replOpVal = replOpUser.getOpValue();
940 if (replacedOp->
getBlock() == rewriterBlock &&
944 Value replacedOpResults = builder.create<pdl_interp::GetResultsOp>(
945 replacedOp->
getLoc(), mapRewriteValue(replOpVal));
946 types.push_back(builder.create<pdl_interp::GetValueTypeOp>(
947 replacedOp->
getLoc(), replacedOpResults));
954 if (resultTypeValues.empty())
960 op->emitOpError() <<
"unable to infer result type for operation";
961 llvm_unreachable(
"unable to infer result type for operation");
969 struct PDLToPDLInterpPass
970 :
public impl::ConvertPDLToPDLInterpBase<PDLToPDLInterpPass> {
971 PDLToPDLInterpPass() =
default;
972 PDLToPDLInterpPass(
const PDLToPDLInterpPass &rhs) =
default;
974 : configMap(&configMap) {}
975 void runOnOperation() final;
984 void PDLToPDLInterpPass::runOnOperation() {
985 ModuleOp module = getOperation();
989 OpBuilder builder = OpBuilder::atBlockBegin(module.getBody());
990 auto matcherFunc = builder.
create<pdl_interp::FuncOp>(
991 module.getLoc(), pdl_interp::PDLInterpDialect::getMatcherFunctionName(),
998 ModuleOp rewriterModule = builder.
create<ModuleOp>(
999 module.getLoc(), pdl_interp::PDLInterpDialect::getRewriterModuleName());
1002 PatternLowering
generator(matcherFunc, rewriterModule, configMap);
1006 for (pdl::PatternOp pattern :
1007 llvm::make_early_inc_range(module.getOps<pdl::PatternOp>())) {
1010 configMap->erase(pattern);
1017 return std::make_unique<PDLToPDLInterpPass>();
1021 return std::make_unique<PDLToPDLInterpPass>(configMap);
static MLIRContext * getContext(OpFoldResult val)
static const mlir::GenInfo * generator
static void createSwitchOp(Value val, Block *defaultDest, OpBuilder &builder, llvm::MapVector< Qualifier *, Block * > &dests)
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
BlockArgument getArgument(unsigned i)
void erase()
Unlink this Block from its parent region and delete it.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
OpListType & getOperations()
void push_back(Operation *op)
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
Ty getType(Args &&...args)
Get or construct an instance of the type Ty with provided arguments.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents an operand of an operation.
This class implements the operand iterators for the Operation class.
Operation is the basic unit of execution within MLIR.
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
Location getLoc()
The source location the operation was defined or derived from.
Block * getBlock()
Returns the operation block that contains this operation.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
Location getLoc() const
Return the location of this value.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
This class represents the base of a predicate matcher node.
Position * getPosition() const
Returns the position on which the question predicate should be checked.
std::unique_ptr< MatcherNode > & getFailureNode()
Returns the node that should be visited if this, or a subsequent node fails.
Qualifier * getQuestion() const
Returns the predicate checked on this node.
A position describes a value on the input IR on which a predicate may be applied, such as an operatio...
Position * getParent() const
Returns the parent position. The root operation position has no parent.
Predicates::Kind getKind() const
Returns the kind of this position.
This class provides utilities for constructing predicates.
This class provides a storage uniquer that is used to allocate predicate instances.
An ordinal predicate consists of a "Question" and a set of acceptable "Answers" (later converted to o...
Predicates::Kind getKind() const
Returns the kind of this qualifier.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Kind
An enumeration of the kinds of predicates.
@ ResultCountAtLeastQuestion
@ OperationPos
Positions, ordered by decreasing priority.
@ OperandCountAtLeastQuestion
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
std::unique_ptr< OperationPass< ModuleOp > > createPDLToPDLInterpPass()
Creates and returns a pass to convert PDL ops to PDL interpreter ops.
A BoolNode denotes a question with a boolean-like result.
std::unique_ptr< MatcherNode > & getSuccessNode()
Returns the node that should be visited on success.
Qualifier * getAnswer() const
Returns the expected answer of this boolean node.
An Answer representing an OperationName value.
A SuccessNode denotes that a given high level pattern has successfully been matched.
pdl::PatternOp getPattern() const
Return the high level pattern operation that is matched with this node.
Value getRoot() const
Return the chosen root of the pattern.
A SwitchNode denotes a question with multiple potential results.
std::pair< Qualifier *, std::unique_ptr< MatcherNode > > & getChild(unsigned i)
Returns the child at the given index.
ChildMapT & getChildren()