MLIR  14.0.0git
PDLInterp.cpp
Go to the documentation of this file.
1 //===- PDLInterp.cpp - PDL Interpreter Dialect ------------------*- C++ -*-===//
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 
11 #include "mlir/IR/BuiltinTypes.h"
13 
14 using namespace mlir;
15 using namespace mlir::pdl_interp;
16 
17 #include "mlir/Dialect/PDLInterp/IR/PDLInterpOpsDialect.cpp.inc"
18 
19 //===----------------------------------------------------------------------===//
20 // PDLInterp Dialect
21 //===----------------------------------------------------------------------===//
22 
23 void PDLInterpDialect::initialize() {
24  addOperations<
25 #define GET_OP_LIST
26 #include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.cpp.inc"
27  >();
28 }
29 
30 //===----------------------------------------------------------------------===//
31 // pdl_interp::CreateOperationOp
32 //===----------------------------------------------------------------------===//
33 
36  ArrayAttr &attrNamesAttr) {
37  Builder &builder = p.getBuilder();
38  SmallVector<Attribute, 4> attrNames;
39  if (succeeded(p.parseOptionalLBrace())) {
40  do {
41  StringAttr nameAttr;
43  if (p.parseAttribute(nameAttr) || p.parseEqual() ||
44  p.parseOperand(operand))
45  return failure();
46  attrNames.push_back(nameAttr);
47  attrOperands.push_back(operand);
48  } while (succeeded(p.parseOptionalComma()));
49  if (p.parseRBrace())
50  return failure();
51  }
52  attrNamesAttr = builder.getArrayAttr(attrNames);
53  return success();
54 }
55 
57  CreateOperationOp op,
58  OperandRange attrArgs,
59  ArrayAttr attrNames) {
60  if (attrNames.empty())
61  return;
62  p << " {";
63  interleaveComma(llvm::seq<int>(0, attrNames.size()), p,
64  [&](int i) { p << attrNames[i] << " = " << attrArgs[i]; });
65  p << '}';
66 }
67 
68 //===----------------------------------------------------------------------===//
69 // pdl_interp::ForEachOp
70 //===----------------------------------------------------------------------===//
71 
72 void ForEachOp::build(::mlir::OpBuilder &builder, ::mlir::OperationState &state,
73  Value range, Block *successor, bool initLoop) {
74  build(builder, state, range, successor);
75  if (initLoop) {
76  // Create the block and the loop variable.
77  // FIXME: Allow passing in a proper location for the loop variable.
78  auto rangeType = range.getType().cast<pdl::RangeType>();
79  state.regions.front()->emplaceBlock();
80  state.regions.front()->addArgument(rangeType.getElementType(),
81  state.location);
82  }
83 }
84 
86  // Parse the loop variable followed by type.
87  OpAsmParser::OperandType loopVariable;
88  Type loopVariableType;
89  if (parser.parseRegionArgument(loopVariable) ||
90  parser.parseColonType(loopVariableType))
91  return failure();
92 
93  // Parse the "in" keyword.
94  if (parser.parseKeyword("in", " after loop variable"))
95  return failure();
96 
97  // Parse the operand (value range).
98  OpAsmParser::OperandType operandInfo;
99  if (parser.parseOperand(operandInfo))
100  return failure();
101 
102  // Resolve the operand.
103  Type rangeType = pdl::RangeType::get(loopVariableType);
104  if (parser.resolveOperand(operandInfo, rangeType, result.operands))
105  return failure();
106 
107  // Parse the body region.
108  Region *body = result.addRegion();
109  if (parser.parseRegion(*body, {loopVariable}, {loopVariableType}))
110  return failure();
111 
112  // Parse the attribute dictionary.
113  if (parser.parseOptionalAttrDict(result.attributes))
114  return failure();
115 
116  // Parse the successor.
117  Block *successor;
118  if (parser.parseArrow() || parser.parseSuccessor(successor))
119  return failure();
120  result.addSuccessors(successor);
121 
122  return success();
123 }
124 
125 static void print(OpAsmPrinter &p, ForEachOp op) {
126  BlockArgument arg = op.getLoopVariable();
127  p << ' ' << arg << " : " << arg.getType() << " in " << op.values() << ' ';
128  p.printRegion(op.region(), /*printEntryBlockArgs=*/false);
129  p.printOptionalAttrDict(op->getAttrs());
130  p << " -> ";
131  p.printSuccessor(op.successor());
132 }
133 
134 static LogicalResult verify(ForEachOp op) {
135  // Verify that the operation has exactly one argument.
136  if (op.region().getNumArguments() != 1)
137  return op.emitOpError("requires exactly one argument");
138 
139  // Verify that the loop variable and the operand (value range)
140  // have compatible types.
141  BlockArgument arg = op.getLoopVariable();
142  Type rangeType = pdl::RangeType::get(arg.getType());
143  if (rangeType != op.values().getType())
144  return op.emitOpError("operand must be a range of loop variable type");
145 
146  return success();
147 }
148 
149 //===----------------------------------------------------------------------===//
150 // pdl_interp::GetValueTypeOp
151 //===----------------------------------------------------------------------===//
152 
153 /// Given the result type of a `GetValueTypeOp`, return the expected input type.
155  Type valueTy = pdl::ValueType::get(type.getContext());
156  return type.isa<pdl::RangeType>() ? pdl::RangeType::get(valueTy) : valueTy;
157 }
158 
159 //===----------------------------------------------------------------------===//
160 // TableGen Auto-Generated Op and Interface Definitions
161 //===----------------------------------------------------------------------===//
162 
163 #define GET_OP_CLASSES
164 #include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.cpp.inc"
virtual ParseResult parseOperand(OperandType &result)=0
Parse a single operand.
This is the representation of an operand reference.
Include the generated interface declarations.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
Block represents an ordered list of Operations.
Definition: Block.h:29
LogicalResult verify(Operation *op)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs, on this operation and any nested operations.
Definition: Verifier.cpp:353
virtual ParseResult parseRegionArgument(OperandType &argument)=0
Parse a region argument, this argument is resolved when calling &#39;parseRegion&#39;.
static ParseResult parseForEachOp(OpAsmParser &parser, OperationState &result)
Definition: PDLInterp.cpp:85
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value...
Definition: LogicalResult.h:68
The OpAsmParser has methods for interacting with the asm parser: parsing things from it...
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual ParseResult parseOptionalLBrace()=0
Parse a { token if present.
virtual ParseResult parseOptionalComma()=0
Parse a , token if present.
SmallVector< Value, 4 > operands
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
virtual ParseResult resolveOperand(const OperandType &operand, Type type, SmallVectorImpl< Value > &result)=0
Resolve an operand to an SSA value, emitting an error on failure.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
virtual ParseResult parseRegion(Region &region, ArrayRef< OperandType > arguments={}, ArrayRef< Type > argTypes={}, ArrayRef< Location > argLocations={}, bool enableNameShadowing=false)=0
Parses a region.
static void printCreateOperationOpAttributes(OpAsmPrinter &p, CreateOperationOp op, OperandRange attrArgs, ArrayAttr attrNames)
Definition: PDLInterp.cpp:56
ParseResult parseKeyword(StringRef keyword, const Twine &msg="")
Parse a given keyword.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
static Type getGetValueTypeOpValueType(Type type)
Given the result type of a GetValueTypeOp, return the expected input type.
Definition: PDLInterp.cpp:154
This represents an operation in an abstracted form, suitable for use with the builder APIs...
This class represents an argument of a Block.
Definition: Value.h:298
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
static ParseResult parseCreateOperationOpAttributes(OpAsmParser &p, SmallVectorImpl< OpAsmParser::OperandType > &attrOperands, ArrayAttr &attrNamesAttr)
Definition: PDLInterp.cpp:34
virtual ParseResult parseRBrace()=0
Parse a } token.
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition: Types.cpp:19
void addSuccessors(Block *successor)
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
virtual ParseResult parseArrow()=0
Parse a &#39;->&#39; token.
NamedAttrList attributes
virtual void printSuccessor(Block *successor)=0
Print the given successor.
virtual void printOptionalAttrDict(ArrayRef< NamedAttribute > attrs, ArrayRef< StringRef > elidedAttrs={})=0
If the specified operation has attributes, print out an attribute dictionary with their values...
Region * addRegion()
Create a region that should be attached to the operation.
This class is a general helper class for creating context-global objects like types, attributes, and affine expressions.
Definition: Builders.h:49
Type getType() const
Return the type of this value.
Definition: Value.h:117
static void print(OpAsmPrinter &p, ForEachOp op)
Definition: PDLInterp.cpp:125
This class implements the operand iterators for the Operation class.
virtual ParseResult parseOptionalAttrDict(NamedAttrList &result)=0
Parse a named dictionary into &#39;result&#39; if it is present.
virtual ParseResult parseEqual()=0
Parse a = token.
virtual ParseResult parseSuccessor(Block *&dest)=0
Parse a single operation successor.
SmallVector< std::unique_ptr< Region >, 1 > regions
Regions that the op will hold.
bool isa() const
Definition: Types.h:234
This class represents success/failure for operation parsing.
Definition: OpDefinition.h:36
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
This class helps build Operations.
Definition: Builders.h:177
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
Definition: Builders.cpp:205
virtual ParseResult parseColonType(Type &result)=0
Parse a colon followed by a type.
U cast() const
Definition: Types.h:250
virtual void printRegion(Region &blocks, bool printEntryBlockArgs=true, bool printBlockTerminators=true, bool printEmptyBlock=false)=0
Prints a region.