xref: /llvm-project/mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp (revision 206fad0e218e83799e49ca15545d997c6c5e8a03)
1083ddffeSPeiming Liu //===- SparseStorageSpecifierToLLVM.cpp - convert specifier to llvm -------===//
2083ddffeSPeiming Liu //
3083ddffeSPeiming Liu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4083ddffeSPeiming Liu // See https://llvm.org/LICENSE.txt for license information.
5083ddffeSPeiming Liu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6083ddffeSPeiming Liu //
7083ddffeSPeiming Liu //===----------------------------------------------------------------------===//
8083ddffeSPeiming Liu 
9365777ecSAart Bik #include "Utils/CodegenUtils.h"
10083ddffeSPeiming Liu 
11afe78db7SPeiming Liu #include "mlir/Conversion/LLVMCommon/StructBuilder.h"
12afe78db7SPeiming Liu #include "mlir/Dialect/SparseTensor/IR/SparseTensorStorageLayout.h"
13083ddffeSPeiming Liu #include "mlir/Dialect/SparseTensor/Transforms/Passes.h"
14afe78db7SPeiming Liu 
15a1fe1f5fSKazu Hirata #include <optional>
16083ddffeSPeiming Liu 
17083ddffeSPeiming Liu using namespace mlir;
18083ddffeSPeiming Liu using namespace sparse_tensor;
19083ddffeSPeiming Liu 
20e568d001SAart Bik namespace {
21e568d001SAart Bik 
22e568d001SAart Bik //===----------------------------------------------------------------------===//
23e568d001SAart Bik // Helper methods.
24e568d001SAart Bik //===----------------------------------------------------------------------===//
25e568d001SAart Bik 
268237cac6SPeiming Liu static SmallVector<Type, 4> getSpecifierFields(StorageSpecifierType tp) {
27083ddffeSPeiming Liu   MLIRContext *ctx = tp.getContext();
28083ddffeSPeiming Liu   auto enc = tp.getEncoding();
29f708a549Swren romano   const Level lvlRank = enc.getLvlRank();
30083ddffeSPeiming Liu 
318237cac6SPeiming Liu   SmallVector<Type, 4> result;
3244ff23d5SPeiming Liu   // TODO: how can we get the lowering type for index type in the later pipeline
3344ff23d5SPeiming Liu   // to be consistent? LLVM::StructureType does not allow index fields.
3484cd51bbSwren romano   auto sizeType = IntegerType::get(tp.getContext(), 64);
3584cd51bbSwren romano   auto lvlSizes = LLVM::LLVMArrayType::get(ctx, sizeType, lvlRank);
3684cd51bbSwren romano   auto memSizes = LLVM::LLVMArrayType::get(ctx, sizeType,
37083ddffeSPeiming Liu                                            getNumDataFieldsFromEncoding(enc));
3884cd51bbSwren romano   result.push_back(lvlSizes);
39083ddffeSPeiming Liu   result.push_back(memSizes);
408237cac6SPeiming Liu 
418237cac6SPeiming Liu   if (enc.isSlice()) {
428237cac6SPeiming Liu     // Extra fields are required for the slice information.
438237cac6SPeiming Liu     auto dimOffset = LLVM::LLVMArrayType::get(ctx, sizeType, lvlRank);
448237cac6SPeiming Liu     auto dimStride = LLVM::LLVMArrayType::get(ctx, sizeType, lvlRank);
458237cac6SPeiming Liu 
468237cac6SPeiming Liu     result.push_back(dimOffset);
478237cac6SPeiming Liu     result.push_back(dimStride);
488237cac6SPeiming Liu   }
498237cac6SPeiming Liu 
50083ddffeSPeiming Liu   return result;
51083ddffeSPeiming Liu }
52083ddffeSPeiming Liu 
53083ddffeSPeiming Liu static Type convertSpecifier(StorageSpecifierType tp) {
54083ddffeSPeiming Liu   return LLVM::LLVMStructType::getLiteral(tp.getContext(),
55083ddffeSPeiming Liu                                           getSpecifierFields(tp));
56083ddffeSPeiming Liu }
57083ddffeSPeiming Liu 
58e568d001SAart Bik //===----------------------------------------------------------------------===//
59e568d001SAart Bik // Specifier struct builder.
60e568d001SAart Bik //===----------------------------------------------------------------------===//
61083ddffeSPeiming Liu 
6284cd51bbSwren romano constexpr uint64_t kLvlSizePosInSpecifier = 0;
63083ddffeSPeiming Liu constexpr uint64_t kMemSizePosInSpecifier = 1;
648237cac6SPeiming Liu constexpr uint64_t kDimOffsetPosInSpecifier = 2;
658237cac6SPeiming Liu constexpr uint64_t kDimStridePosInSpecifier = 3;
66083ddffeSPeiming Liu 
67083ddffeSPeiming Liu class SpecifierStructBuilder : public StructBuilder {
6844ff23d5SPeiming Liu private:
6944ff23d5SPeiming Liu   Value extractField(OpBuilder &builder, Location loc,
708237cac6SPeiming Liu                      ArrayRef<int64_t> indices) const {
7144ff23d5SPeiming Liu     return genCast(builder, loc,
7244ff23d5SPeiming Liu                    builder.create<LLVM::ExtractValueOp>(loc, value, indices),
7344ff23d5SPeiming Liu                    builder.getIndexType());
7444ff23d5SPeiming Liu   }
7544ff23d5SPeiming Liu 
7644ff23d5SPeiming Liu   void insertField(OpBuilder &builder, Location loc, ArrayRef<int64_t> indices,
7744ff23d5SPeiming Liu                    Value v) {
7844ff23d5SPeiming Liu     value = builder.create<LLVM::InsertValueOp>(
7944ff23d5SPeiming Liu         loc, value, genCast(builder, loc, v, builder.getIntegerType(64)),
8044ff23d5SPeiming Liu         indices);
8144ff23d5SPeiming Liu   }
8244ff23d5SPeiming Liu 
83083ddffeSPeiming Liu public:
84083ddffeSPeiming Liu   explicit SpecifierStructBuilder(Value specifier) : StructBuilder(specifier) {
85083ddffeSPeiming Liu     assert(value);
86083ddffeSPeiming Liu   }
87083ddffeSPeiming Liu 
888237cac6SPeiming Liu   // Undef value for dimension sizes, all zero value for memory sizes.
898237cac6SPeiming Liu   static Value getInitValue(OpBuilder &builder, Location loc, Type structType,
908237cac6SPeiming Liu                             Value source);
91083ddffeSPeiming Liu 
928237cac6SPeiming Liu   Value lvlSize(OpBuilder &builder, Location loc, Level lvl) const;
9384cd51bbSwren romano   void setLvlSize(OpBuilder &builder, Location loc, Level lvl, Value size);
94083ddffeSPeiming Liu 
958237cac6SPeiming Liu   Value dimOffset(OpBuilder &builder, Location loc, Dimension dim) const;
968237cac6SPeiming Liu   void setDimOffset(OpBuilder &builder, Location loc, Dimension dim,
978237cac6SPeiming Liu                     Value size);
988237cac6SPeiming Liu 
998237cac6SPeiming Liu   Value dimStride(OpBuilder &builder, Location loc, Dimension dim) const;
1008237cac6SPeiming Liu   void setDimStride(OpBuilder &builder, Location loc, Dimension dim,
1018237cac6SPeiming Liu                     Value size);
1028237cac6SPeiming Liu 
1038237cac6SPeiming Liu   Value memSize(OpBuilder &builder, Location loc, FieldIndex fidx) const;
10484cd51bbSwren romano   void setMemSize(OpBuilder &builder, Location loc, FieldIndex fidx,
10584cd51bbSwren romano                   Value size);
1068237cac6SPeiming Liu 
1078237cac6SPeiming Liu   Value memSizeArray(OpBuilder &builder, Location loc) const;
1088237cac6SPeiming Liu   void setMemSizeArray(OpBuilder &builder, Location loc, Value array);
109083ddffeSPeiming Liu };
110083ddffeSPeiming Liu 
111083ddffeSPeiming Liu Value SpecifierStructBuilder::getInitValue(OpBuilder &builder, Location loc,
1128237cac6SPeiming Liu                                            Type structType, Value source) {
113083ddffeSPeiming Liu   Value metaData = builder.create<LLVM::UndefOp>(loc, structType);
114083ddffeSPeiming Liu   SpecifierStructBuilder md(metaData);
1158237cac6SPeiming Liu   if (!source) {
1165550c821STres Popp     auto memSizeArrayType =
1175550c821STres Popp         cast<LLVM::LLVMArrayType>(cast<LLVM::LLVMStructType>(structType)
1185550c821STres Popp                                       .getBody()[kMemSizePosInSpecifier]);
119083ddffeSPeiming Liu 
120083ddffeSPeiming Liu     Value zero = constantZero(builder, loc, memSizeArrayType.getElementType());
121083ddffeSPeiming Liu     // Fill memSizes array with zero.
122083ddffeSPeiming Liu     for (int i = 0, e = memSizeArrayType.getNumElements(); i < e; i++)
123083ddffeSPeiming Liu       md.setMemSize(builder, loc, i, zero);
1248237cac6SPeiming Liu   } else {
1258237cac6SPeiming Liu     // We copy non-slice information (memory sizes array) from source
1268237cac6SPeiming Liu     SpecifierStructBuilder sourceMd(source);
1278237cac6SPeiming Liu     md.setMemSizeArray(builder, loc, sourceMd.memSizeArray(builder, loc));
1288237cac6SPeiming Liu   }
129083ddffeSPeiming Liu   return md;
130083ddffeSPeiming Liu }
131083ddffeSPeiming Liu 
1328237cac6SPeiming Liu /// Builds IR extracting the pos-th offset from the descriptor.
1338237cac6SPeiming Liu Value SpecifierStructBuilder::dimOffset(OpBuilder &builder, Location loc,
1348237cac6SPeiming Liu                                         Dimension dim) const {
1356db397a8SPeiming Liu   return extractField(
1366db397a8SPeiming Liu       builder, loc,
1376db397a8SPeiming Liu       ArrayRef<int64_t>{kDimOffsetPosInSpecifier, static_cast<int64_t>(dim)});
1388237cac6SPeiming Liu }
1398237cac6SPeiming Liu 
1408237cac6SPeiming Liu /// Builds IR inserting the pos-th offset into the descriptor.
1418237cac6SPeiming Liu void SpecifierStructBuilder::setDimOffset(OpBuilder &builder, Location loc,
1428237cac6SPeiming Liu                                           Dimension dim, Value size) {
1436db397a8SPeiming Liu   insertField(
1446db397a8SPeiming Liu       builder, loc,
1456db397a8SPeiming Liu       ArrayRef<int64_t>{kDimOffsetPosInSpecifier, static_cast<int64_t>(dim)},
1466db397a8SPeiming Liu       size);
1478237cac6SPeiming Liu }
1488237cac6SPeiming Liu 
14984cd51bbSwren romano /// Builds IR extracting the `lvl`-th level-size from the descriptor.
15084cd51bbSwren romano Value SpecifierStructBuilder::lvlSize(OpBuilder &builder, Location loc,
1518237cac6SPeiming Liu                                       Level lvl) const {
15284cd51bbSwren romano   // This static_cast makes the narrowing of `lvl` explicit, as required
15384cd51bbSwren romano   // by the braces notation for the ctor.
15484cd51bbSwren romano   return extractField(
15584cd51bbSwren romano       builder, loc,
15684cd51bbSwren romano       ArrayRef<int64_t>{kLvlSizePosInSpecifier, static_cast<int64_t>(lvl)});
157083ddffeSPeiming Liu }
158083ddffeSPeiming Liu 
15984cd51bbSwren romano /// Builds IR inserting the `lvl`-th level-size into the descriptor.
16084cd51bbSwren romano void SpecifierStructBuilder::setLvlSize(OpBuilder &builder, Location loc,
16184cd51bbSwren romano                                         Level lvl, Value size) {
16284cd51bbSwren romano   // This static_cast makes the narrowing of `lvl` explicit, as required
16384cd51bbSwren romano   // by the braces notation for the ctor.
16484cd51bbSwren romano   insertField(
16584cd51bbSwren romano       builder, loc,
16684cd51bbSwren romano       ArrayRef<int64_t>{kLvlSizePosInSpecifier, static_cast<int64_t>(lvl)},
16744ff23d5SPeiming Liu       size);
168083ddffeSPeiming Liu }
169083ddffeSPeiming Liu 
1708237cac6SPeiming Liu /// Builds IR extracting the pos-th stride from the descriptor.
1718237cac6SPeiming Liu Value SpecifierStructBuilder::dimStride(OpBuilder &builder, Location loc,
1728237cac6SPeiming Liu                                         Dimension dim) const {
1738237cac6SPeiming Liu   return extractField(
1748237cac6SPeiming Liu       builder, loc,
1758237cac6SPeiming Liu       ArrayRef<int64_t>{kDimStridePosInSpecifier, static_cast<int64_t>(dim)});
1768237cac6SPeiming Liu }
1778237cac6SPeiming Liu 
1788237cac6SPeiming Liu /// Builds IR inserting the pos-th stride into the descriptor.
1798237cac6SPeiming Liu void SpecifierStructBuilder::setDimStride(OpBuilder &builder, Location loc,
1808237cac6SPeiming Liu                                           Dimension dim, Value size) {
1818237cac6SPeiming Liu   insertField(
1828237cac6SPeiming Liu       builder, loc,
1838237cac6SPeiming Liu       ArrayRef<int64_t>{kDimStridePosInSpecifier, static_cast<int64_t>(dim)},
1848237cac6SPeiming Liu       size);
1858237cac6SPeiming Liu }
1868237cac6SPeiming Liu 
1878237cac6SPeiming Liu /// Builds IR extracting the pos-th memory size into the descriptor.
188083ddffeSPeiming Liu Value SpecifierStructBuilder::memSize(OpBuilder &builder, Location loc,
1898237cac6SPeiming Liu                                       FieldIndex fidx) const {
1908237cac6SPeiming Liu   return extractField(
1918237cac6SPeiming Liu       builder, loc,
1928237cac6SPeiming Liu       ArrayRef<int64_t>{kMemSizePosInSpecifier, static_cast<int64_t>(fidx)});
193083ddffeSPeiming Liu }
194083ddffeSPeiming Liu 
19584cd51bbSwren romano /// Builds IR inserting the `fidx`-th memory-size into the descriptor.
196083ddffeSPeiming Liu void SpecifierStructBuilder::setMemSize(OpBuilder &builder, Location loc,
19784cd51bbSwren romano                                         FieldIndex fidx, Value size) {
1988237cac6SPeiming Liu   insertField(
1998237cac6SPeiming Liu       builder, loc,
2008237cac6SPeiming Liu       ArrayRef<int64_t>{kMemSizePosInSpecifier, static_cast<int64_t>(fidx)},
20144ff23d5SPeiming Liu       size);
202083ddffeSPeiming Liu }
203083ddffeSPeiming Liu 
2048237cac6SPeiming Liu /// Builds IR extracting the memory size array from the descriptor.
2058237cac6SPeiming Liu Value SpecifierStructBuilder::memSizeArray(OpBuilder &builder,
2068237cac6SPeiming Liu                                            Location loc) const {
2078237cac6SPeiming Liu   return builder.create<LLVM::ExtractValueOp>(loc, value,
2088237cac6SPeiming Liu                                               kMemSizePosInSpecifier);
2098237cac6SPeiming Liu }
2108237cac6SPeiming Liu 
2118237cac6SPeiming Liu /// Builds IR inserting the memory size array into the descriptor.
2128237cac6SPeiming Liu void SpecifierStructBuilder::setMemSizeArray(OpBuilder &builder, Location loc,
2138237cac6SPeiming Liu                                              Value array) {
2148237cac6SPeiming Liu   value = builder.create<LLVM::InsertValueOp>(loc, value, array,
2158237cac6SPeiming Liu                                               kMemSizePosInSpecifier);
2168237cac6SPeiming Liu }
2178237cac6SPeiming Liu 
218e568d001SAart Bik } // namespace
219e568d001SAart Bik 
220e568d001SAart Bik //===----------------------------------------------------------------------===//
221e568d001SAart Bik // The sparse storage specifier type converter (defined in Passes.h).
222e568d001SAart Bik //===----------------------------------------------------------------------===//
223e568d001SAart Bik 
224e568d001SAart Bik StorageSpecifierToLLVMTypeConverter::StorageSpecifierToLLVMTypeConverter() {
225e568d001SAart Bik   addConversion([](Type type) { return type; });
22684cd51bbSwren romano   addConversion(convertSpecifier);
227e568d001SAart Bik }
228e568d001SAart Bik 
229e568d001SAart Bik //===----------------------------------------------------------------------===//
230e568d001SAart Bik // Storage specifier conversion rules.
231e568d001SAart Bik //===----------------------------------------------------------------------===//
232e568d001SAart Bik 
233083ddffeSPeiming Liu template <typename Base, typename SourceOp>
234083ddffeSPeiming Liu class SpecifierGetterSetterOpConverter : public OpConversionPattern<SourceOp> {
235083ddffeSPeiming Liu public:
236083ddffeSPeiming Liu   using OpAdaptor = typename SourceOp::Adaptor;
237083ddffeSPeiming Liu   using OpConversionPattern<SourceOp>::OpConversionPattern;
238083ddffeSPeiming Liu 
239083ddffeSPeiming Liu   LogicalResult
240083ddffeSPeiming Liu   matchAndRewrite(SourceOp op, OpAdaptor adaptor,
241083ddffeSPeiming Liu                   ConversionPatternRewriter &rewriter) const override {
242083ddffeSPeiming Liu     SpecifierStructBuilder spec(adaptor.getSpecifier());
2438237cac6SPeiming Liu     switch (op.getSpecifierKind()) {
2448237cac6SPeiming Liu     case StorageSpecifierKind::LvlSize: {
2458237cac6SPeiming Liu       Value v = Base::onLvlSize(rewriter, op, spec, (*op.getLevel()));
246083ddffeSPeiming Liu       rewriter.replaceOp(op, v);
247083ddffeSPeiming Liu       return success();
248083ddffeSPeiming Liu     }
2498237cac6SPeiming Liu     case StorageSpecifierKind::DimOffset: {
2508237cac6SPeiming Liu       Value v = Base::onDimOffset(rewriter, op, spec, (*op.getLevel()));
2518237cac6SPeiming Liu       rewriter.replaceOp(op, v);
2528237cac6SPeiming Liu       return success();
2538237cac6SPeiming Liu     }
2548237cac6SPeiming Liu     case StorageSpecifierKind::DimStride: {
2558237cac6SPeiming Liu       Value v = Base::onDimStride(rewriter, op, spec, (*op.getLevel()));
2568237cac6SPeiming Liu       rewriter.replaceOp(op, v);
2578237cac6SPeiming Liu       return success();
2588237cac6SPeiming Liu     }
2598237cac6SPeiming Liu     case StorageSpecifierKind::CrdMemSize:
2608237cac6SPeiming Liu     case StorageSpecifierKind::PosMemSize:
2618237cac6SPeiming Liu     case StorageSpecifierKind::ValMemSize: {
2628237cac6SPeiming Liu       auto enc = op.getSpecifier().getType().getEncoding();
2638237cac6SPeiming Liu       StorageLayout layout(enc);
2648237cac6SPeiming Liu       std::optional<unsigned> lvl;
2658237cac6SPeiming Liu       if (op.getLevel())
2668237cac6SPeiming Liu         lvl = (*op.getLevel());
267afe78db7SPeiming Liu       unsigned idx =
268afe78db7SPeiming Liu           layout.getMemRefFieldIndex(toFieldKind(op.getSpecifierKind()), lvl);
2698237cac6SPeiming Liu       Value v = Base::onMemSize(rewriter, op, spec, idx);
2708237cac6SPeiming Liu       rewriter.replaceOp(op, v);
2718237cac6SPeiming Liu       return success();
2728237cac6SPeiming Liu     }
2738237cac6SPeiming Liu     }
2748237cac6SPeiming Liu     llvm_unreachable("unrecognized specifer kind");
2758237cac6SPeiming Liu   }
276083ddffeSPeiming Liu };
277083ddffeSPeiming Liu 
278083ddffeSPeiming Liu struct StorageSpecifierSetOpConverter
279083ddffeSPeiming Liu     : public SpecifierGetterSetterOpConverter<StorageSpecifierSetOpConverter,
280083ddffeSPeiming Liu                                               SetStorageSpecifierOp> {
281083ddffeSPeiming Liu   using SpecifierGetterSetterOpConverter::SpecifierGetterSetterOpConverter;
2828237cac6SPeiming Liu 
28384cd51bbSwren romano   static Value onLvlSize(OpBuilder &builder, SetStorageSpecifierOp op,
28484cd51bbSwren romano                          SpecifierStructBuilder &spec, Level lvl) {
28584cd51bbSwren romano     spec.setLvlSize(builder, op.getLoc(), lvl, op.getValue());
286083ddffeSPeiming Liu     return spec;
287083ddffeSPeiming Liu   }
288083ddffeSPeiming Liu 
2898237cac6SPeiming Liu   static Value onDimOffset(OpBuilder &builder, SetStorageSpecifierOp op,
2908237cac6SPeiming Liu                            SpecifierStructBuilder &spec, Dimension d) {
2918237cac6SPeiming Liu     spec.setDimOffset(builder, op.getLoc(), d, op.getValue());
2928237cac6SPeiming Liu     return spec;
2938237cac6SPeiming Liu   }
2948237cac6SPeiming Liu 
2958237cac6SPeiming Liu   static Value onDimStride(OpBuilder &builder, SetStorageSpecifierOp op,
2968237cac6SPeiming Liu                            SpecifierStructBuilder &spec, Dimension d) {
2978237cac6SPeiming Liu     spec.setDimStride(builder, op.getLoc(), d, op.getValue());
2988237cac6SPeiming Liu     return spec;
2998237cac6SPeiming Liu   }
3008237cac6SPeiming Liu 
301083ddffeSPeiming Liu   static Value onMemSize(OpBuilder &builder, SetStorageSpecifierOp op,
30284cd51bbSwren romano                          SpecifierStructBuilder &spec, FieldIndex fidx) {
30384cd51bbSwren romano     spec.setMemSize(builder, op.getLoc(), fidx, op.getValue());
304083ddffeSPeiming Liu     return spec;
305083ddffeSPeiming Liu   }
306083ddffeSPeiming Liu };
307083ddffeSPeiming Liu 
308083ddffeSPeiming Liu struct StorageSpecifierGetOpConverter
309083ddffeSPeiming Liu     : public SpecifierGetterSetterOpConverter<StorageSpecifierGetOpConverter,
310083ddffeSPeiming Liu                                               GetStorageSpecifierOp> {
311083ddffeSPeiming Liu   using SpecifierGetterSetterOpConverter::SpecifierGetterSetterOpConverter;
3128237cac6SPeiming Liu 
31384cd51bbSwren romano   static Value onLvlSize(OpBuilder &builder, GetStorageSpecifierOp op,
31484cd51bbSwren romano                          SpecifierStructBuilder &spec, Level lvl) {
31584cd51bbSwren romano     return spec.lvlSize(builder, op.getLoc(), lvl);
316083ddffeSPeiming Liu   }
3178237cac6SPeiming Liu 
3188237cac6SPeiming Liu   static Value onDimOffset(OpBuilder &builder, GetStorageSpecifierOp op,
3198237cac6SPeiming Liu                            const SpecifierStructBuilder &spec, Dimension d) {
3208237cac6SPeiming Liu     return spec.dimOffset(builder, op.getLoc(), d);
3218237cac6SPeiming Liu   }
3228237cac6SPeiming Liu 
3238237cac6SPeiming Liu   static Value onDimStride(OpBuilder &builder, GetStorageSpecifierOp op,
3248237cac6SPeiming Liu                            const SpecifierStructBuilder &spec, Dimension d) {
3258237cac6SPeiming Liu     return spec.dimStride(builder, op.getLoc(), d);
3268237cac6SPeiming Liu   }
3278237cac6SPeiming Liu 
328083ddffeSPeiming Liu   static Value onMemSize(OpBuilder &builder, GetStorageSpecifierOp op,
32984cd51bbSwren romano                          SpecifierStructBuilder &spec, FieldIndex fidx) {
33084cd51bbSwren romano     return spec.memSize(builder, op.getLoc(), fidx);
331083ddffeSPeiming Liu   }
332083ddffeSPeiming Liu };
333083ddffeSPeiming Liu 
334083ddffeSPeiming Liu struct StorageSpecifierInitOpConverter
335083ddffeSPeiming Liu     : public OpConversionPattern<StorageSpecifierInitOp> {
336083ddffeSPeiming Liu public:
337083ddffeSPeiming Liu   using OpConversionPattern::OpConversionPattern;
338083ddffeSPeiming Liu   LogicalResult
339083ddffeSPeiming Liu   matchAndRewrite(StorageSpecifierInitOp op, OpAdaptor adaptor,
340083ddffeSPeiming Liu                   ConversionPatternRewriter &rewriter) const override {
341083ddffeSPeiming Liu     Type llvmType = getTypeConverter()->convertType(op.getResult().getType());
3428237cac6SPeiming Liu     rewriter.replaceOp(
3438237cac6SPeiming Liu         op, SpecifierStructBuilder::getInitValue(
3448237cac6SPeiming Liu                 rewriter, op.getLoc(), llvmType, adaptor.getSource()));
345083ddffeSPeiming Liu     return success();
346083ddffeSPeiming Liu   }
347083ddffeSPeiming Liu };
348083ddffeSPeiming Liu 
349e568d001SAart Bik //===----------------------------------------------------------------------===//
350e568d001SAart Bik // Public method for populating conversion rules.
351e568d001SAart Bik //===----------------------------------------------------------------------===//
352e568d001SAart Bik 
353*206fad0eSMatthias Springer void mlir::populateStorageSpecifierToLLVMPatterns(
354*206fad0eSMatthias Springer     const TypeConverter &converter, RewritePatternSet &patterns) {
355083ddffeSPeiming Liu   patterns.add<StorageSpecifierGetOpConverter, StorageSpecifierSetOpConverter,
356083ddffeSPeiming Liu                StorageSpecifierInitOpConverter>(converter,
357083ddffeSPeiming Liu                                                 patterns.getContext());
358083ddffeSPeiming Liu }
359