Refactor the asmparser hook to work with a new OperationState type that fully
encapsulates an operation that is yet to be created. This is a patch towards
custom ops providing create methods that don't need to be templated, allowing
them to move out of line in the future.
PiperOrigin-RevId: 207725557
diff --git a/include/mlir/IR/Builders.h b/include/mlir/IR/Builders.h
index 59aca69..80b30c6 100644
--- a/include/mlir/IR/Builders.h
+++ b/include/mlir/IR/Builders.h
@@ -155,7 +155,8 @@
// Add new basic block and set the insertion point to the end of it.
BasicBlock *createBlock();
- // Create an operation at the current insertion point.
+ // TODO(clattner): remove this.
+ /// Create an operation at the current insertion point.
OperationInst *createOperation(Identifier name, ArrayRef<CFGValue *> operands,
ArrayRef<Type *> resultTypes,
ArrayRef<NamedAttribute> attributes) {
@@ -165,18 +166,23 @@
return op;
}
+ /// Create an operation given the fields represented as an OperationState.
+ OperationInst *createOperation(const OperationState &state);
+
+ // TODO(clattner): rework build to return an OperationState so the
+ // implementations can moved out of line.
+ /// Create operation of specific op type at the current insertion point.
+ template <typename OpTy, typename... Args>
+ OpPointer<OpTy> create(Args... args) {
+ return OpTy::build(this, args...);
+ }
+
OperationInst *cloneOperation(const OperationInst &srcOpInst) {
auto *op = srcOpInst.clone();
block->getOperations().insert(insertPoint, op);
return op;
}
- // Create operation of specific op type at the current insertion point.
- template <typename OpTy, typename... Args>
- OpPointer<OpTy> create(Args... args) {
- return OpTy::build(this, args...);
- }
-
// Terminators.
ReturnInst *createReturnInst(ArrayRef<CFGValue *> operands) {
@@ -256,6 +262,7 @@
/// Get the current insertion point of the builder.
StmtBlock::iterator getInsertionPoint() const { return insertPoint; }
+ // TODO(clattner): remove this.
OperationStmt *createOperation(Identifier name, ArrayRef<MLValue *> operands,
ArrayRef<Type *> resultTypes,
ArrayRef<NamedAttribute> attributes) {
@@ -265,6 +272,11 @@
return op;
}
+ /// Create an operation given the fields represented as an OperationState.
+ OperationStmt *createOperation(const OperationState &state);
+
+ // TODO(clattner): rework build to return an OperationState so the
+ // implementations can moved out of line.
// Create operation of specific op type at the current insertion point.
template <typename OpTy, typename... Args>
OpPointer<OpTy> create(Args... args) {
diff --git a/include/mlir/IR/OpDefinition.h b/include/mlir/IR/OpDefinition.h
index b2a95fe..5fc9de1 100644
--- a/include/mlir/IR/OpDefinition.h
+++ b/include/mlir/IR/OpDefinition.h
@@ -71,23 +71,6 @@
const OpType value;
};
-/// This is the result type of parsing a custom operation. If an error is
-/// emitted, it is fine to return this in a partially mutated state.
-struct OpAsmParserResult {
- SmallVector<SSAValue *, 4> operands;
- SmallVector<Type *, 4> types;
- SmallVector<NamedAttribute, 4> attributes;
-
- /*implicit*/ OpAsmParserResult() {}
-
- OpAsmParserResult(ArrayRef<SSAValue *> operands, ArrayRef<Type *> types,
- ArrayRef<NamedAttribute> attributes = {})
- : operands(operands.begin(), operands.end()),
- types(types.begin(), types.end()),
- attributes(attributes.begin(), attributes.end()) {}
-};
-
-
/// This is the concrete base class that holds the operation pointer and has
/// non-generic methods that only depend on State (to avoid having them
/// instantiated on template types that don't affect them.
@@ -125,8 +108,11 @@
/// back to this one which accepts everything.
const char *verify() const { return nullptr; }
- // Unless overridden, the short form of an op is always rejected.
- static OpAsmParserResult parse(OpAsmParser *parser);
+ /// Unless overridden, the short form of an op is always rejected. Op
+ /// implementations should implement this to return boolean true on failure.
+ /// On success, they should return false and fill in result with the fields to
+ /// use.
+ static bool parse(OpAsmParser *parser, OperationState *result);
// The fallback for the printer is to print it the longhand form.
void print(OpAsmPrinter *p) const;
@@ -159,9 +145,11 @@
}
/// This is the hook used by the AsmParser to parse the custom form of this
- /// op from an .mlir file. Op implementations should provide a parse method.
- static OpAsmParserResult parseAssembly(OpAsmParser *parser) {
- return ConcreteType::parse(parser);
+ /// op from an .mlir file. Op implementations should provide a parse method,
+ /// which returns boolean true on failure. On success, they should return
+ /// false and fill in result with the fields to use.
+ static bool parseAssembly(OpAsmParser *parser, OperationState *result) {
+ return ConcreteType::parse(parser, result);
}
/// This is the hook used by the AsmPrinter to emit this to the .mlir file.
diff --git a/include/mlir/IR/OpImplementation.h b/include/mlir/IR/OpImplementation.h
index 62b8e4f..65b25ae 100644
--- a/include/mlir/IR/OpImplementation.h
+++ b/include/mlir/IR/OpImplementation.h
@@ -278,8 +278,8 @@
return false;
}
- /// Emit a diagnostic at the specified location.
- virtual void emitError(llvm::SMLoc loc, const Twine &message) = 0;
+ /// Emit a diagnostic at the specified location and return true.
+ virtual bool emitError(llvm::SMLoc loc, const Twine &message) = 0;
};
} // end namespace mlir
diff --git a/include/mlir/IR/Operation.h b/include/mlir/IR/Operation.h
index 6f78232..51f7ee1 100644
--- a/include/mlir/IR/Operation.h
+++ b/include/mlir/IR/Operation.h
@@ -32,12 +32,34 @@
template <typename ObjectType, typename ElementType> class OperandIterator;
template <typename ObjectType, typename ElementType> class ResultIterator;
class SSAValue;
+class Type;
/// NamedAttribute is a used for operation attribute lists, it holds an
/// identifier for the name and a value for the attribute. The attribute
/// pointer should always be non-null.
typedef std::pair<Identifier, Attribute*> NamedAttribute;
+/// This represents an operation in an abstracted form, suitable for use with
+/// the builder APIs. This object is a large and heavy weight object meant to
+/// be used as a temporary object on the stack. It is generally unwise to put
+/// this in a collection.
+struct OperationState {
+ Identifier name;
+ SmallVector<SSAValue *, 4> operands;
+ SmallVector<Type *, 4> types;
+ SmallVector<NamedAttribute, 4> attributes;
+
+public:
+ OperationState(Identifier name) : name(name) {}
+
+ OperationState(Identifier name, ArrayRef<SSAValue *> operands,
+ ArrayRef<Type *> types,
+ ArrayRef<NamedAttribute> attributes = {})
+ : name(name), operands(operands.begin(), operands.end()),
+ types(types.begin(), types.end()),
+ attributes(attributes.begin(), attributes.end()) {}
+};
+
/// Operations represent all of the arithmetic and other basic computation in
/// MLIR. This class is the common implementation details behind OperationInst
/// and OperationStmt.
diff --git a/include/mlir/IR/OperationSet.h b/include/mlir/IR/OperationSet.h
index 59dbfb9..1fea466 100644
--- a/include/mlir/IR/OperationSet.h
+++ b/include/mlir/IR/OperationSet.h
@@ -27,6 +27,7 @@
namespace mlir {
class Operation;
+class OperationState;
class OpAsmParser;
class OpAsmParserResult;
class OpAsmPrinter;
@@ -53,7 +54,7 @@
bool (&isClassFor)(const Operation *op);
/// Use the specified object to parse this ops custom assembly format.
- OpAsmParserResult (&parseAssembly)(OpAsmParser *parser);
+ bool (&parseAssembly)(OpAsmParser *parser, OperationState *result);
/// This hook implements the AsmPrinter for this operation.
void (&printAssembly)(const Operation *op, OpAsmPrinter *p);
@@ -66,7 +67,8 @@
private:
AbstractOperation(StringRef name, bool (&isClassFor)(const Operation *op),
- OpAsmParserResult (&parseAssembly)(OpAsmParser *parser),
+ bool (&parseAssembly)(OpAsmParser *parser,
+ OperationState *result),
void (&printAssembly)(const Operation *op, OpAsmPrinter *p),
const char *(&verifyInvariants)(const Operation *op))
: name(name), isClassFor(isClassFor), parseAssembly(parseAssembly),
diff --git a/include/mlir/IR/StandardOps.h b/include/mlir/IR/StandardOps.h
index f8701bf..ac5dbad 100644
--- a/include/mlir/IR/StandardOps.h
+++ b/include/mlir/IR/StandardOps.h
@@ -51,7 +51,7 @@
}
const char *verify() const;
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
private:
@@ -85,7 +85,7 @@
static StringRef getOperationName() { return "affine_apply"; }
// Hooks to customize behavior of this op.
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
const char *verify() const;
@@ -124,7 +124,7 @@
// Hooks to customize behavior of this op.
const char *verify() const;
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
private:
@@ -148,7 +148,7 @@
static StringRef getOperationName() { return "constant"; }
// Hooks to customize behavior of this op.
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
const char *verify() const;
@@ -235,7 +235,7 @@
// Hooks to customize behavior of this op.
const char *verify() const;
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
private:
@@ -269,7 +269,7 @@
// Hooks to customize behavior of this op.
const char *verify() const;
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
private:
@@ -308,7 +308,7 @@
// Hooks to customize behavior of this op.
const char *verify() const;
- static OpAsmParserResult parse(OpAsmParser *parser);
+ static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p) const;
private: