|
6 | 6 | //
|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
| 9 | +#include "mlir/Bytecode/BytecodeReader.h" |
9 | 10 | #include "mlir/Bytecode/BytecodeWriter.h"
|
10 | 11 | #include "mlir/IR/AsmState.h"
|
11 | 12 | #include "mlir/IR/BuiltinAttributes.h"
|
|
15 | 16 |
|
16 | 17 | #include "llvm/ADT/StringRef.h"
|
17 | 18 | #include "llvm/Support/Endian.h"
|
| 19 | +#include "llvm/Support/MemoryBufferRef.h" |
18 | 20 | #include "gmock/gmock.h"
|
19 | 21 | #include "gtest/gtest.h"
|
20 | 22 |
|
@@ -86,3 +88,60 @@ TEST(Bytecode, MultiModuleWithResource) {
|
86 | 88 | checkResourceAttribute(*module);
|
87 | 89 | checkResourceAttribute(*roundTripModule);
|
88 | 90 | }
|
| 91 | + |
| 92 | +namespace { |
| 93 | +/// A custom operation for the purpose of showcasing how discardable attributes |
| 94 | +/// are handled in absence of properties. |
| 95 | +class OpWithoutProperties : public Op<OpWithoutProperties> { |
| 96 | +public: |
| 97 | + // Begin boilerplate. |
| 98 | + MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(OpWithoutProperties) |
| 99 | + using Op::Op; |
| 100 | + static ArrayRef<StringRef> getAttributeNames() { |
| 101 | + static StringRef attributeNames[] = {StringRef("inherent_attr")}; |
| 102 | + return ArrayRef(attributeNames); |
| 103 | + }; |
| 104 | + static StringRef getOperationName() { |
| 105 | + return "test_op_properties.op_without_properties"; |
| 106 | + } |
| 107 | + // End boilerplate. |
| 108 | +}; |
| 109 | + |
| 110 | +// A trivial supporting dialect to register the above operation. |
| 111 | +class TestOpPropertiesDialect : public Dialect { |
| 112 | +public: |
| 113 | + MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestOpPropertiesDialect) |
| 114 | + static constexpr StringLiteral getDialectNamespace() { |
| 115 | + return StringLiteral("test_op_properties"); |
| 116 | + } |
| 117 | + explicit TestOpPropertiesDialect(MLIRContext *context) |
| 118 | + : Dialect(getDialectNamespace(), context, |
| 119 | + TypeID::get<TestOpPropertiesDialect>()) { |
| 120 | + addOperations<OpWithoutProperties>(); |
| 121 | + } |
| 122 | +}; |
| 123 | +} // namespace |
| 124 | + |
| 125 | +constexpr StringLiteral withoutPropertiesAttrsSrc = R"mlir( |
| 126 | + "test_op_properties.op_without_properties"() |
| 127 | + {inherent_attr = 42, other_attr = 56} : () -> () |
| 128 | +)mlir"; |
| 129 | + |
| 130 | +TEST(Bytecode, OpWithoutProperties) { |
| 131 | + MLIRContext context; |
| 132 | + context.getOrLoadDialect<TestOpPropertiesDialect>(); |
| 133 | + ParserConfig config(&context); |
| 134 | + OwningOpRef<Operation *> op = |
| 135 | + parseSourceString(withoutPropertiesAttrsSrc, config); |
| 136 | + |
| 137 | + std::string bytecode; |
| 138 | + llvm::raw_string_ostream os(bytecode); |
| 139 | + ASSERT_TRUE(succeeded(writeBytecodeToFile(op.get(), os))); |
| 140 | + std::unique_ptr<Block> block = std::make_unique<Block>(); |
| 141 | + ASSERT_TRUE(succeeded(readBytecodeFile( |
| 142 | + llvm::MemoryBufferRef(os.str(), "string-buffer"), block.get(), config))); |
| 143 | + Operation *roundtripped = &block->front(); |
| 144 | + EXPECT_EQ(roundtripped->getAttrs().size(), 2u); |
| 145 | + EXPECT_TRUE(roundtripped->getInherentAttr("inherent_attr") != std::nullopt); |
| 146 | + EXPECT_TRUE(roundtripped->getDiscardableAttr("other_attr") != Attribute()); |
| 147 | +} |
0 commit comments