13f050f6aSKirsten Lee //===- MemRefTransformOps.cpp - Implementation of Memref transform ops ----===// 23f050f6aSKirsten Lee // 33f050f6aSKirsten Lee // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43f050f6aSKirsten Lee // See https://llvm.org/LICENSE.txt for license information. 53f050f6aSKirsten Lee // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63f050f6aSKirsten Lee // 73f050f6aSKirsten Lee //===----------------------------------------------------------------------===// 83f050f6aSKirsten Lee 93f050f6aSKirsten Lee #include "mlir/Dialect/MemRef/TransformOps/MemRefTransformOps.h" 107ec88f06SMatthias Springer 11e55e36deSOleksandr "Alex" Zinenko #include "mlir/Analysis/DataLayoutAnalysis.h" 127ec88f06SMatthias Springer #include "mlir/Conversion/LLVMCommon/TypeConverter.h" 133f050f6aSKirsten Lee #include "mlir/Dialect/Affine/IR/AffineOps.h" 14abc362a1SJakub Kuderski #include "mlir/Dialect/Arith/IR/Arith.h" 153f050f6aSKirsten Lee #include "mlir/Dialect/MemRef/IR/MemRef.h" 163f050f6aSKirsten Lee #include "mlir/Dialect/MemRef/Transforms/Passes.h" 1754cda2ecSQuentin Colombet #include "mlir/Dialect/MemRef/Transforms/Transforms.h" 18c5dee18bSHanhan Wang #include "mlir/Dialect/MemRef/Utils/MemRefUtils.h" 1954cda2ecSQuentin Colombet #include "mlir/Dialect/NVGPU/IR/NVGPUDialect.h" 2076100870SMatthias Springer #include "mlir/Dialect/SCF/IR/SCF.h" 213f050f6aSKirsten Lee #include "mlir/Dialect/Transform/IR/TransformDialect.h" 225a9bdd85SOleksandr "Alex" Zinenko #include "mlir/Dialect/Transform/IR/TransformTypes.h" 235a9bdd85SOleksandr "Alex" Zinenko #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" 2454cda2ecSQuentin Colombet #include "mlir/Dialect/Vector/IR/VectorOps.h" 25c5dee18bSHanhan Wang #include "mlir/Dialect/Vector/Transforms/VectorTransforms.h" 26b838b628SQuentin Colombet #include "mlir/Interfaces/LoopLikeInterface.h" 2754cda2ecSQuentin Colombet #include "mlir/Transforms/GreedyPatternRewriteDriver.h" 28c888a0ceSNicolas Vasilache #include "llvm/Support/Debug.h" 293f050f6aSKirsten Lee 303f050f6aSKirsten Lee using namespace mlir; 313f050f6aSKirsten Lee 32c888a0ceSNicolas Vasilache #define DEBUG_TYPE "memref-transforms" 33c888a0ceSNicolas Vasilache #define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ") 34c888a0ceSNicolas Vasilache 353f050f6aSKirsten Lee //===----------------------------------------------------------------------===// 367ec88f06SMatthias Springer // Apply...ConversionPatternsOp 377ec88f06SMatthias Springer //===----------------------------------------------------------------------===// 387ec88f06SMatthias Springer 397ec88f06SMatthias Springer std::unique_ptr<TypeConverter> 407ec88f06SMatthias Springer transform::MemrefToLLVMTypeConverterOp::getTypeConverter() { 417ec88f06SMatthias Springer LowerToLLVMOptions options(getContext()); 427ec88f06SMatthias Springer options.allocLowering = 437ec88f06SMatthias Springer (getUseAlignedAlloc() ? LowerToLLVMOptions::AllocLowering::AlignedAlloc 447ec88f06SMatthias Springer : LowerToLLVMOptions::AllocLowering::Malloc); 457ec88f06SMatthias Springer options.useGenericFunctions = getUseGenericFunctions(); 467ec88f06SMatthias Springer 477ec88f06SMatthias Springer if (getIndexBitwidth() != kDeriveIndexBitwidthFromDataLayout) 487ec88f06SMatthias Springer options.overrideIndexBitwidth(getIndexBitwidth()); 497ec88f06SMatthias Springer 50920c4612SNicolas Vasilache // TODO: the following two options don't really make sense for 51920c4612SNicolas Vasilache // memref_to_llvm_type_converter specifically but we should have a single 52920c4612SNicolas Vasilache // to_llvm_type_converter. 53920c4612SNicolas Vasilache if (getDataLayout().has_value()) 54920c4612SNicolas Vasilache options.dataLayout = llvm::DataLayout(getDataLayout().value()); 55920c4612SNicolas Vasilache options.useBarePtrCallConv = getUseBarePtrCallConv(); 56920c4612SNicolas Vasilache 577ec88f06SMatthias Springer return std::make_unique<LLVMTypeConverter>(getContext(), options); 587ec88f06SMatthias Springer } 597ec88f06SMatthias Springer 607ec88f06SMatthias Springer StringRef transform::MemrefToLLVMTypeConverterOp::getTypeConverterType() { 617ec88f06SMatthias Springer return "LLVMTypeConverter"; 627ec88f06SMatthias Springer } 637ec88f06SMatthias Springer 647ec88f06SMatthias Springer //===----------------------------------------------------------------------===// 65cc7f5243SMatthias Springer // Apply...PatternsOp 66cc7f5243SMatthias Springer //===----------------------------------------------------------------------===// 67cc7f5243SMatthias Springer 68e55e36deSOleksandr "Alex" Zinenko namespace { 69e55e36deSOleksandr "Alex" Zinenko class AllocToAllocaPattern : public OpRewritePattern<memref::AllocOp> { 70e55e36deSOleksandr "Alex" Zinenko public: 71e55e36deSOleksandr "Alex" Zinenko explicit AllocToAllocaPattern(Operation *analysisRoot, int64_t maxSize = 0) 72e55e36deSOleksandr "Alex" Zinenko : OpRewritePattern<memref::AllocOp>(analysisRoot->getContext()), 73e55e36deSOleksandr "Alex" Zinenko dataLayoutAnalysis(analysisRoot), maxSize(maxSize) {} 74e55e36deSOleksandr "Alex" Zinenko 75e55e36deSOleksandr "Alex" Zinenko LogicalResult matchAndRewrite(memref::AllocOp op, 76e55e36deSOleksandr "Alex" Zinenko PatternRewriter &rewriter) const override { 77e55e36deSOleksandr "Alex" Zinenko return success(memref::allocToAlloca( 78e55e36deSOleksandr "Alex" Zinenko rewriter, op, [this](memref::AllocOp alloc, memref::DeallocOp dealloc) { 79e55e36deSOleksandr "Alex" Zinenko MemRefType type = alloc.getMemref().getType(); 80e55e36deSOleksandr "Alex" Zinenko if (!type.hasStaticShape()) 81e55e36deSOleksandr "Alex" Zinenko return false; 82e55e36deSOleksandr "Alex" Zinenko 83e55e36deSOleksandr "Alex" Zinenko const DataLayout &dataLayout = dataLayoutAnalysis.getAtOrAbove(alloc); 84e55e36deSOleksandr "Alex" Zinenko int64_t elementSize = dataLayout.getTypeSize(type.getElementType()); 85e55e36deSOleksandr "Alex" Zinenko return maxSize == 0 || type.getNumElements() * elementSize < maxSize; 86e55e36deSOleksandr "Alex" Zinenko })); 87e55e36deSOleksandr "Alex" Zinenko } 88e55e36deSOleksandr "Alex" Zinenko 89e55e36deSOleksandr "Alex" Zinenko private: 90e55e36deSOleksandr "Alex" Zinenko DataLayoutAnalysis dataLayoutAnalysis; 91e55e36deSOleksandr "Alex" Zinenko int64_t maxSize; 92e55e36deSOleksandr "Alex" Zinenko }; 93e55e36deSOleksandr "Alex" Zinenko } // namespace 94e55e36deSOleksandr "Alex" Zinenko 95e55e36deSOleksandr "Alex" Zinenko void transform::ApplyAllocToAllocaOp::populatePatterns( 96e55e36deSOleksandr "Alex" Zinenko RewritePatternSet &patterns) {} 97e55e36deSOleksandr "Alex" Zinenko 98e55e36deSOleksandr "Alex" Zinenko void transform::ApplyAllocToAllocaOp::populatePatternsWithState( 99e55e36deSOleksandr "Alex" Zinenko RewritePatternSet &patterns, transform::TransformState &state) { 100e55e36deSOleksandr "Alex" Zinenko patterns.insert<AllocToAllocaPattern>( 101e55e36deSOleksandr "Alex" Zinenko state.getTopLevel(), static_cast<int64_t>(getSizeLimit().value_or(0))); 102e55e36deSOleksandr "Alex" Zinenko } 103e55e36deSOleksandr "Alex" Zinenko 104cc7f5243SMatthias Springer void transform::ApplyExpandOpsPatternsOp::populatePatterns( 105cc7f5243SMatthias Springer RewritePatternSet &patterns) { 106cc7f5243SMatthias Springer memref::populateExpandOpsPatterns(patterns); 107cc7f5243SMatthias Springer } 108cc7f5243SMatthias Springer 109cc7f5243SMatthias Springer void transform::ApplyExpandStridedMetadataPatternsOp::populatePatterns( 110cc7f5243SMatthias Springer RewritePatternSet &patterns) { 111cc7f5243SMatthias Springer memref::populateExpandStridedMetadataPatterns(patterns); 112cc7f5243SMatthias Springer } 113cc7f5243SMatthias Springer 114cc7f5243SMatthias Springer void transform::ApplyExtractAddressComputationsPatternsOp::populatePatterns( 115cc7f5243SMatthias Springer RewritePatternSet &patterns) { 116cc7f5243SMatthias Springer memref::populateExtractAddressComputationsPatterns(patterns); 117cc7f5243SMatthias Springer } 118cc7f5243SMatthias Springer 119cc7f5243SMatthias Springer void transform::ApplyFoldMemrefAliasOpsPatternsOp::populatePatterns( 120cc7f5243SMatthias Springer RewritePatternSet &patterns) { 121cc7f5243SMatthias Springer memref::populateFoldMemRefAliasOpPatterns(patterns); 122cc7f5243SMatthias Springer } 123cc7f5243SMatthias Springer 124cc7f5243SMatthias Springer void transform::ApplyResolveRankedShapedTypeResultDimsPatternsOp:: 125cc7f5243SMatthias Springer populatePatterns(RewritePatternSet &patterns) { 126cc7f5243SMatthias Springer memref::populateResolveRankedShapedTypeResultDimsPatterns(patterns); 127cc7f5243SMatthias Springer } 128cc7f5243SMatthias Springer 129cc7f5243SMatthias Springer //===----------------------------------------------------------------------===// 130991cb147SIngo Müller // AllocaToGlobalOp 131991cb147SIngo Müller //===----------------------------------------------------------------------===// 132991cb147SIngo Müller 133991cb147SIngo Müller DiagnosedSilenceableFailure 134991cb147SIngo Müller transform::MemRefAllocaToGlobalOp::apply(transform::TransformRewriter &rewriter, 135991cb147SIngo Müller transform::TransformResults &results, 136991cb147SIngo Müller transform::TransformState &state) { 137991cb147SIngo Müller auto allocaOps = state.getPayloadOps(getAlloca()); 138991cb147SIngo Müller 139991cb147SIngo Müller SmallVector<memref::GlobalOp> globalOps; 140991cb147SIngo Müller SmallVector<memref::GetGlobalOp> getGlobalOps; 141991cb147SIngo Müller 142991cb147SIngo Müller // Transform `memref.alloca`s. 143991cb147SIngo Müller for (auto *op : allocaOps) { 144991cb147SIngo Müller auto alloca = cast<memref::AllocaOp>(op); 145991cb147SIngo Müller MLIRContext *ctx = rewriter.getContext(); 146991cb147SIngo Müller Location loc = alloca->getLoc(); 147991cb147SIngo Müller 148991cb147SIngo Müller memref::GlobalOp globalOp; 149991cb147SIngo Müller { 150991cb147SIngo Müller // Find nearest symbol table. 151991cb147SIngo Müller Operation *symbolTableOp = SymbolTable::getNearestSymbolTable(op); 152991cb147SIngo Müller assert(symbolTableOp && "expected alloca payload to be in symbol table"); 153991cb147SIngo Müller SymbolTable symbolTable(symbolTableOp); 154991cb147SIngo Müller 155991cb147SIngo Müller // Insert a `memref.global` into the symbol table. 156991cb147SIngo Müller Type resultType = alloca.getResult().getType(); 157991cb147SIngo Müller OpBuilder builder(rewriter.getContext()); 158991cb147SIngo Müller // TODO: Add a better builder for this. 159991cb147SIngo Müller globalOp = builder.create<memref::GlobalOp>( 160991cb147SIngo Müller loc, StringAttr::get(ctx, "alloca"), StringAttr::get(ctx, "private"), 161991cb147SIngo Müller TypeAttr::get(resultType), Attribute{}, UnitAttr{}, IntegerAttr{}); 162991cb147SIngo Müller symbolTable.insert(globalOp); 163991cb147SIngo Müller } 164991cb147SIngo Müller 165991cb147SIngo Müller // Replace the `memref.alloca` with a `memref.get_global` accessing the 166991cb147SIngo Müller // global symbol inserted above. 167991cb147SIngo Müller rewriter.setInsertionPoint(alloca); 168991cb147SIngo Müller auto getGlobalOp = rewriter.replaceOpWithNewOp<memref::GetGlobalOp>( 169991cb147SIngo Müller alloca, globalOp.getType(), globalOp.getName()); 170991cb147SIngo Müller 171991cb147SIngo Müller globalOps.push_back(globalOp); 172991cb147SIngo Müller getGlobalOps.push_back(getGlobalOp); 173991cb147SIngo Müller } 174991cb147SIngo Müller 175991cb147SIngo Müller // Assemble results. 176a5757c5bSChristian Sigg results.set(cast<OpResult>(getGlobal()), globalOps); 177a5757c5bSChristian Sigg results.set(cast<OpResult>(getGetGlobal()), getGlobalOps); 178991cb147SIngo Müller 179991cb147SIngo Müller return DiagnosedSilenceableFailure::success(); 180991cb147SIngo Müller } 181991cb147SIngo Müller 182991cb147SIngo Müller void transform::MemRefAllocaToGlobalOp::getEffects( 183991cb147SIngo Müller SmallVectorImpl<MemoryEffects::EffectInstance> &effects) { 1842c1ae801Sdonald chen producesHandle(getOperation()->getOpResults(), effects); 1852c1ae801Sdonald chen consumesHandle(getAllocaMutable(), effects); 186991cb147SIngo Müller modifiesPayload(effects); 187991cb147SIngo Müller } 188991cb147SIngo Müller 189991cb147SIngo Müller //===----------------------------------------------------------------------===// 1903f050f6aSKirsten Lee // MemRefMultiBufferOp 1913f050f6aSKirsten Lee //===----------------------------------------------------------------------===// 1923f050f6aSKirsten Lee 193b838b628SQuentin Colombet DiagnosedSilenceableFailure transform::MemRefMultiBufferOp::apply( 194c63d2b2cSMatthias Springer transform::TransformRewriter &rewriter, 195b838b628SQuentin Colombet transform::TransformResults &transformResults, 1963f050f6aSKirsten Lee transform::TransformState &state) { 197b838b628SQuentin Colombet SmallVector<Operation *> results; 1980e37ef08SMatthias Springer for (Operation *op : state.getPayloadOps(getTarget())) { 199b838b628SQuentin Colombet bool canApplyMultiBuffer = true; 200b838b628SQuentin Colombet auto target = cast<memref::AllocOp>(op); 201c888a0ceSNicolas Vasilache LLVM_DEBUG(DBGS() << "Start multibuffer transform op: " << target << "\n";); 202b838b628SQuentin Colombet // Skip allocations not used in a loop. 203b838b628SQuentin Colombet for (Operation *user : target->getUsers()) { 204c888a0ceSNicolas Vasilache if (isa<memref::DeallocOp>(user)) 205c888a0ceSNicolas Vasilache continue; 206b838b628SQuentin Colombet auto loop = user->getParentOfType<LoopLikeOpInterface>(); 207b838b628SQuentin Colombet if (!loop) { 208c888a0ceSNicolas Vasilache LLVM_DEBUG(DBGS() << "--allocation not used in a loop\n"; 209c888a0ceSNicolas Vasilache DBGS() << "----due to user: " << *user;); 210b838b628SQuentin Colombet canApplyMultiBuffer = false; 211b838b628SQuentin Colombet break; 212b838b628SQuentin Colombet } 213b838b628SQuentin Colombet } 214c888a0ceSNicolas Vasilache if (!canApplyMultiBuffer) { 215c888a0ceSNicolas Vasilache LLVM_DEBUG(DBGS() << "--cannot apply multibuffering -> Skip\n";); 216b838b628SQuentin Colombet continue; 217c888a0ceSNicolas Vasilache } 218b838b628SQuentin Colombet 219ddeb55abSThomas Raoux auto newBuffer = 220c888a0ceSNicolas Vasilache memref::multiBuffer(rewriter, target, getFactor(), getSkipAnalysis()); 221c888a0ceSNicolas Vasilache 222c888a0ceSNicolas Vasilache if (failed(newBuffer)) { 223c888a0ceSNicolas Vasilache LLVM_DEBUG(DBGS() << "--op failed to multibuffer\n";); 2248b28500fSQuentin Colombet return emitSilenceableFailure(target->getLoc()) 2258b28500fSQuentin Colombet << "op failed to multibuffer"; 226c888a0ceSNicolas Vasilache } 2273f050f6aSKirsten Lee 228cbb09813SFangrui Song results.push_back(*newBuffer); 229b838b628SQuentin Colombet } 2305550c821STres Popp transformResults.set(cast<OpResult>(getResult()), results); 2317d5bef77SAlex Zinenko return DiagnosedSilenceableFailure::success(); 2323f050f6aSKirsten Lee } 2333f050f6aSKirsten Lee 2343f050f6aSKirsten Lee //===----------------------------------------------------------------------===// 235c5dee18bSHanhan Wang // MemRefEraseDeadAllocAndStoresOp 236c5dee18bSHanhan Wang //===----------------------------------------------------------------------===// 237c5dee18bSHanhan Wang 238c5dee18bSHanhan Wang DiagnosedSilenceableFailure 239c5dee18bSHanhan Wang transform::MemRefEraseDeadAllocAndStoresOp::applyToOne( 240c5dee18bSHanhan Wang transform::TransformRewriter &rewriter, Operation *target, 241c5dee18bSHanhan Wang transform::ApplyToEachResultList &results, 242c5dee18bSHanhan Wang transform::TransformState &state) { 243c5dee18bSHanhan Wang // Apply store to load forwarding and dead store elimination. 244c5dee18bSHanhan Wang vector::transferOpflowOpt(rewriter, target); 245c5dee18bSHanhan Wang memref::eraseDeadAllocAndStores(rewriter, target); 246c5dee18bSHanhan Wang return DiagnosedSilenceableFailure::success(); 247c5dee18bSHanhan Wang } 248c5dee18bSHanhan Wang 249c5dee18bSHanhan Wang void transform::MemRefEraseDeadAllocAndStoresOp::getEffects( 250c5dee18bSHanhan Wang SmallVectorImpl<MemoryEffects::EffectInstance> &effects) { 2512c1ae801Sdonald chen transform::onlyReadsHandle(getTargetMutable(), effects); 252c5dee18bSHanhan Wang transform::modifiesPayload(effects); 253c5dee18bSHanhan Wang } 254c5dee18bSHanhan Wang void transform::MemRefEraseDeadAllocAndStoresOp::build(OpBuilder &builder, 255c5dee18bSHanhan Wang OperationState &result, 256c5dee18bSHanhan Wang Value target) { 257c5dee18bSHanhan Wang result.addOperands(target); 258c5dee18bSHanhan Wang } 259c5dee18bSHanhan Wang 260c5dee18bSHanhan Wang //===----------------------------------------------------------------------===// 26176100870SMatthias Springer // MemRefMakeLoopIndependentOp 26276100870SMatthias Springer //===----------------------------------------------------------------------===// 26376100870SMatthias Springer 26476100870SMatthias Springer DiagnosedSilenceableFailure transform::MemRefMakeLoopIndependentOp::applyToOne( 265c63d2b2cSMatthias Springer transform::TransformRewriter &rewriter, Operation *target, 266c63d2b2cSMatthias Springer transform::ApplyToEachResultList &results, 26776100870SMatthias Springer transform::TransformState &state) { 26876100870SMatthias Springer // Gather IVs. 26976100870SMatthias Springer SmallVector<Value> ivs; 27076100870SMatthias Springer Operation *nextOp = target; 27176100870SMatthias Springer for (uint64_t i = 0, e = getNumLoops(); i < e; ++i) { 27276100870SMatthias Springer nextOp = nextOp->getParentOfType<scf::ForOp>(); 27376100870SMatthias Springer if (!nextOp) { 27476100870SMatthias Springer DiagnosedSilenceableFailure diag = emitSilenceableError() 27576100870SMatthias Springer << "could not find " << i 27676100870SMatthias Springer << "-th enclosing loop"; 27776100870SMatthias Springer diag.attachNote(target->getLoc()) << "target op"; 27876100870SMatthias Springer return diag; 27976100870SMatthias Springer } 28076100870SMatthias Springer ivs.push_back(cast<scf::ForOp>(nextOp).getInductionVar()); 28176100870SMatthias Springer } 28276100870SMatthias Springer 28376100870SMatthias Springer // Rewrite IR. 28476100870SMatthias Springer FailureOr<Value> replacement = failure(); 28576100870SMatthias Springer if (auto allocaOp = dyn_cast<memref::AllocaOp>(target)) { 28676100870SMatthias Springer replacement = memref::replaceWithIndependentOp(rewriter, allocaOp, ivs); 28776100870SMatthias Springer } else { 28876100870SMatthias Springer DiagnosedSilenceableFailure diag = emitSilenceableError() 28976100870SMatthias Springer << "unsupported target op"; 29076100870SMatthias Springer diag.attachNote(target->getLoc()) << "target op"; 29176100870SMatthias Springer return diag; 29276100870SMatthias Springer } 29376100870SMatthias Springer if (failed(replacement)) { 29476100870SMatthias Springer DiagnosedSilenceableFailure diag = 29576100870SMatthias Springer emitSilenceableError() << "could not make target op loop-independent"; 29676100870SMatthias Springer diag.attachNote(target->getLoc()) << "target op"; 29776100870SMatthias Springer return diag; 29876100870SMatthias Springer } 29976100870SMatthias Springer results.push_back(replacement->getDefiningOp()); 30076100870SMatthias Springer return DiagnosedSilenceableFailure::success(); 30176100870SMatthias Springer } 30276100870SMatthias Springer 30376100870SMatthias Springer //===----------------------------------------------------------------------===// 3043f050f6aSKirsten Lee // Transform op registration 3053f050f6aSKirsten Lee //===----------------------------------------------------------------------===// 3063f050f6aSKirsten Lee 3073f050f6aSKirsten Lee namespace { 3083f050f6aSKirsten Lee class MemRefTransformDialectExtension 3093f050f6aSKirsten Lee : public transform::TransformDialectExtension< 3103f050f6aSKirsten Lee MemRefTransformDialectExtension> { 3113f050f6aSKirsten Lee public: 312*84cc1865SNikhil Kalra MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(MemRefTransformDialectExtension) 313*84cc1865SNikhil Kalra 3143f050f6aSKirsten Lee using Base::Base; 3153f050f6aSKirsten Lee 3163f050f6aSKirsten Lee void init() { 3174c48f016SMatthias Springer declareGeneratedDialect<affine::AffineDialect>(); 318abc362a1SJakub Kuderski declareGeneratedDialect<arith::ArithDialect>(); 31954cda2ecSQuentin Colombet declareGeneratedDialect<memref::MemRefDialect>(); 32054cda2ecSQuentin Colombet declareGeneratedDialect<nvgpu::NVGPUDialect>(); 32154cda2ecSQuentin Colombet declareGeneratedDialect<vector::VectorDialect>(); 3223f050f6aSKirsten Lee 3233f050f6aSKirsten Lee registerTransformOps< 3243f050f6aSKirsten Lee #define GET_OP_LIST 3253f050f6aSKirsten Lee #include "mlir/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp.inc" 3263f050f6aSKirsten Lee >(); 3273f050f6aSKirsten Lee } 3283f050f6aSKirsten Lee }; 3293f050f6aSKirsten Lee } // namespace 3303f050f6aSKirsten Lee 3313f050f6aSKirsten Lee #define GET_OP_CLASSES 3323f050f6aSKirsten Lee #include "mlir/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp.inc" 3333f050f6aSKirsten Lee 3343f050f6aSKirsten Lee void mlir::memref::registerTransformDialectExtension( 3353f050f6aSKirsten Lee DialectRegistry ®istry) { 3363f050f6aSKirsten Lee registry.addExtensions<MemRefTransformDialectExtension>(); 3373f050f6aSKirsten Lee } 338