[Mlir-commits] [mlir] [mlir] Add property combinators, initial ODS support (PR #94732)
Krzysztof Drewniak
llvmlistbot at llvm.org
Mon Jun 17 21:48:30 PDT 2024
================
@@ -133,37 +201,487 @@ defvar writeMlirBytecodeWithConvertToAttribute = [{
// Primitive property kinds
// Any kind of integer stored as properties.
-class IntProperty<string storageTypeParam = "", string desc = ""> :
+class IntProperty<string storageTypeParam, string desc = ""> :
Property<storageTypeParam, desc> {
- code writeToMlirBytecode = [{
+ let summary = !if(!empty(desc), storageTypeParam, desc);
+ let optionalParser = [{
+ return $_parser.parseOptionalInteger($_storage);
+ }];
+ let writeToMlirBytecode = [{
$_writer.writeVarInt($_storage);
}];
- code readFromMlirBytecode = [{
+ let readFromMlirBytecode = [{
uint64_t val;
if (failed($_reader.readVarInt(val)))
return ::mlir::failure();
$_storage = val;
}];
}
-class ArrayProperty<string storageTypeParam = "", int n, string desc = ""> :
- Property<storageTypeParam # "[" # n # "]", desc> {
- let interfaceType = "::llvm::ArrayRef<" # storageTypeParam # ">";
- let convertFromStorage = "$_storage";
- let assignToStorage = "::llvm::copy($_value, $_storage)";
-}
+def I32Property : IntProperty<"int32_t">;
+def I64Property : IntProperty<"int64_t">;
-class EnumProperty<string storageTypeParam, string desc = ""> :
+class EnumProperty<string storageTypeParam, string desc = "", string default = ""> :
Property<storageTypeParam, desc> {
- code writeToMlirBytecode = [{
+ // TODO: take advantage of EnumAttrInfo and the like to make this share nice
+ // parsing code with EnumAttr.
+ let writeToMlirBytecode = [{
$_writer.writeVarInt(static_cast<uint64_t>($_storage));
}];
- code readFromMlirBytecode = [{
+ let readFromMlirBytecode = [{
uint64_t val;
if (failed($_reader.readVarInt(val)))
return ::mlir::failure();
$_storage = static_cast<}] # storageTypeParam # [{>(val);
}];
+ let defaultValue = default;
}
+def StringProperty : Property<"std::string", "string"> {
+ let interfaceType = "::llvm::StringRef";
+ let convertFromStorage = "::llvm::StringRef{$_storage}";
+ let assignToStorage = "$_storage = $_value.str()";
+ let optionalParser = [{
+ if (::mlir::failed($_parser.parseOptionalString(&$_storage)))
+ return std::nullopt;
+ }];
+ let printer = "$_printer.printString($_storage)";
+ let readFromMlirBytecode = [{
+ StringRef val;
+ if (::mlir::failed($_reader.readString(val)))
+ return ::mlir::failure();
+ $_storage = val.str();
+ }];
+ let writeToMlirBytecode = [{
+ $_writer.writeOwnedString($_storage);
+ }];
+}
+
+def BoolProperty : IntProperty<"bool", "boolean"> {
+ let printer = [{ $_printer << ($_storage ? "true" : "false") }];
+ let readFromMlirBytecode = [{
+ return $_reader.readBool($_storage);
+ }];
+ let writeToMlirBytecode = [{
+ $_writer.writeOwnedBool($_storage);
+ }];
+}
+
+def UnitProperty : Property<"bool", "unit property"> {
+ let summary = "unit property";
+ let description = [{
+ A property whose presence or abscence is used as a flag.
+
+ This is stored as a boolean that defaults to false, and is named UnitProperty
+ by analogy with UnitAttr, which has the more comprehensive rationale and
+ explains the less typical syntax.
+
+ Note that this attribute does have a syntax for the false case to allow for its
+ use in contexts where default values shouldn't be elided.
+ }];
+ let defaultValue = "false";
+
+ let convertToAttribute = [{
+ if ($_storage)
+ return ::mlir::UnitAttr::get($_ctxt);
+ else
+ return ::mlir::BoolAttr::get($_ctxt, false);
+ }];
+ let convertFromAttribute = [{
+ if (::llvm::isa<::mlir::UnitAttr>($_attr)) {
+ $_storage = true;
+ return ::mlir::success();
+ }
+ if (auto boolAttr = ::llvm::dyn_cast<::mlir::BoolAttr>($_attr)) {
+ $_storage = boolAttr.getValue();
+ return ::mlir::success();
+ }
+ return ::mlir::failure();
+ }];
+
+ let parser = [{
+ ::llvm::StringRef keyword;
+ if (::mlir::failed($_parser.parseOptionalKeyword(&keyword,
+ {"unit", "unit_absent"})))
+ return $_parser.emitError($_parser.getCurrentLocation(),
+ "expected 'unit' or 'unit_absent'");
+ $_storage = (keyword == "unit");
+ }];
+
+ let optionalParser = [{
+ ::llvm::StringRef keyword;
+ if (::mlir::failed($_parser.parseOptionalKeyword(&keyword,
+ {"unit", "unit_absent"})))
+ return std::nullopt;
+ $_storage = (keyword == "unit");
+ }];
+
+ let printer = [{
+ $_printer << ($_storage ? "unit" : "unit_absent")
+ }];
+
+ let writeToMlirBytecode = [{
+ $_writer.writeOwnedBool($_storage);
+ }];
+ let readFromMlirBytecode = [{
+ if (::mlir::failed($_reader.readBool($_storage)))
+ return ::mlir::failure();
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Primitive property combinators
+
+/// Create a variable named `name` of `prop`'s storage type that is initialized
+/// to the correct default value, if there is one.
+class _makePropStorage<Property prop, string name> {
+ code ret = prop.storageType # " " # name
+ # !cond(!not(!empty(prop.storageTypeValueOverride)) : " = " # prop.storageTypeValueOverride,
+ !not(!empty(prop.defaultValue)) : " = " # prop.defaultValue,
+ true : "") # ";";
+}
+
+/// The generic class for arrays of some other property, which is stored as a
+/// `SmallVector` of that property. This uses an `ArrayAttr` as its attribute form
+/// though subclasses can override this, as is the case with IntArrayAttr below.
+class ArrayProperty<Property elem = Property<>, string desc = ""> :
+ Property<"::llvm::SmallVector<" # elem.storageType # ">", desc> {
----------------
krzysz00 wrote:
Might be a good idea to somehow make that an optional argument to the tablegen
https://github.com/llvm/llvm-project/pull/94732
More information about the Mlir-commits
mailing list