MLIR  20.0.0git
IRDLExtensionOps.cpp
Go to the documentation of this file.
1 //===- IRDLExtensionOps.cpp - IRDL extension for the Transform dialect ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
13 #include "mlir/IR/Diagnostics.h"
16 #include "llvm/ADT/STLExtras.h"
17 
18 using namespace mlir;
19 
20 #define GET_OP_CLASSES
21 #include "mlir/Dialect/Transform/IRDLExtension/IRDLExtensionOps.cpp.inc"
22 
23 namespace mlir::transform {
24 
26 IRDLCollectMatchingOp::apply(TransformRewriter &rewriter,
27  TransformResults &results, TransformState &state) {
28  auto dialect = cast<irdl::DialectOp>(getBody().front().front());
29  Block &body = dialect.getBody().front();
30  irdl::OperationOp operation = *body.getOps<irdl::OperationOp>().begin();
31  auto verifier = irdl::createVerifier(
32  operation,
33  DenseMap<irdl::TypeOp, std::unique_ptr<DynamicTypeDefinition>>(),
34  DenseMap<irdl::AttributeOp, std::unique_ptr<DynamicAttrDefinition>>());
35 
36  auto handlerID = getContext()->getDiagEngine().registerHandler(
37  [](Diagnostic &) { return success(); });
39  for (Operation *payload : state.getPayloadOps(getRoot())) {
40  payload->walk([&](Operation *target) {
41  if (succeeded(verifier(target))) {
42  matched.push_back(target);
43  }
44  });
45  }
46  getContext()->getDiagEngine().eraseHandler(handlerID);
47  results.set(cast<OpResult>(getMatched()), matched);
49 }
50 
51 void IRDLCollectMatchingOp::getEffects(
53  onlyReadsHandle(getRootMutable(), effects);
54  producesHandle(getOperation()->getOpResults(), effects);
55  onlyReadsPayload(effects);
56 }
57 
58 LogicalResult IRDLCollectMatchingOp::verify() {
59  Block &bodyBlock = getBody().front();
60  if (!llvm::hasSingleElement(bodyBlock))
61  return emitOpError() << "expects a single operation in the body";
62 
63  auto dialect = dyn_cast<irdl::DialectOp>(bodyBlock.front());
64  if (!dialect) {
65  return emitOpError() << "expects the body operation to be "
66  << irdl::DialectOp::getOperationName();
67  }
68 
69  // TODO: relax this by taking a symbol name of the operation to match, note
70  // that symbol name is also the name of the operation and we may want to
71  // divert from that to have constraints on-the-fly using IRDL.
72  auto irdlOperations = dialect.getOps<irdl::OperationOp>();
73  if (!llvm::hasSingleElement(irdlOperations))
74  return emitOpError() << "expects IRDL to contain exactly one operation";
75 
76  if (!dialect.getOps<irdl::TypeOp>().empty() ||
77  !dialect.getOps<irdl::AttributeOp>().empty()) {
78  return emitOpError() << "IRDL types and attributes are not yet supported";
79  }
80 
81  return success();
82 }
83 
84 } // namespace mlir::transform
static MLIRContext * getContext(OpFoldResult val)
Block represents an ordered list of Operations.
Definition: Block.h:33
Operation & front()
Definition: Block.h:153
iterator_range< op_iterator< OpT > > getOps()
Return an iterator range over the operations within this block that are of 'OpT'.
Definition: Block.h:193
The result of a transform IR operation application.
static DiagnosedSilenceableFailure success()
Constructs a DiagnosedSilenceableFailure in the success state.
void eraseHandler(HandlerID id)
Erase the registered diagnostic handler with the given identifier.
HandlerID registerHandler(HandlerTy handler)
Register a new handler for diagnostics to the engine.
This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine.
Definition: Diagnostics.h:155
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
llvm::unique_function< LogicalResult(Operation *) const > createVerifier(OperationOp operation, const DenseMap< irdl::TypeOp, std::unique_ptr< DynamicTypeDefinition >> &typeDefs, const DenseMap< irdl::AttributeOp, std::unique_ptr< DynamicAttrDefinition >> &attrDefs)
Generate an op verifier function from the given IRDL operation definition.
void onlyReadsPayload(SmallVectorImpl< MemoryEffects::EffectInstance > &effects)
void producesHandle(ResultRange handles, SmallVectorImpl< MemoryEffects::EffectInstance > &effects)
void onlyReadsHandle(MutableArrayRef< OpOperand > handles, SmallVectorImpl< MemoryEffects::EffectInstance > &effects)
Include the generated interface declarations.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:425