1 //===- SparseTensorPipelines.cpp - Pipelines for sparse tensor code -------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "mlir/Dialect/SparseTensor/Pipelines/Passes.h" 10 11 #include "mlir/Conversion/Passes.h" 12 #include "mlir/Dialect/Bufferization/Transforms/Bufferize.h" 13 #include "mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h" 14 #include "mlir/Dialect/Bufferization/Transforms/Passes.h" 15 #include "mlir/Dialect/Func/IR/FuncOps.h" 16 #include "mlir/Dialect/Linalg/Passes.h" 17 #include "mlir/Dialect/SparseTensor/IR/SparseTensor.h" 18 #include "mlir/Dialect/SparseTensor/Transforms/Passes.h" 19 #include "mlir/Pass/PassManager.h" 20 21 using namespace mlir; 22 using namespace mlir::sparse_tensor; 23 24 /// Return configuration options for One-Shot Bufferize. 25 static bufferization::OneShotBufferizationOptions 26 getBufferizationOptions(bool analysisOnly) { 27 using namespace bufferization; 28 OneShotBufferizationOptions options; 29 options.bufferizeFunctionBoundaries = true; 30 // TODO(springerm): To spot memory leaks more easily, returning dense allocs 31 // should be disallowed. 32 options.allowReturnAllocs = true; 33 options.functionBoundaryTypeConversion = 34 BufferizationOptions::LayoutMapOption::IdentityLayoutMap; 35 options.unknownTypeConverterFn = [](Value value, unsigned memorySpace, 36 const BufferizationOptions &options) { 37 return getMemRefTypeWithStaticIdentityLayout( 38 value.getType().cast<TensorType>(), memorySpace); 39 }; 40 if (analysisOnly) { 41 options.testAnalysisOnly = true; 42 options.printConflicts = true; 43 } 44 return options; 45 } 46 47 //===----------------------------------------------------------------------===// 48 // Pipeline implementation. 49 //===----------------------------------------------------------------------===// 50 51 void mlir::sparse_tensor::buildSparseCompiler( 52 OpPassManager &pm, const SparseCompilerOptions &options) { 53 // TODO(wrengr): ensure the original `pm` is for ModuleOp 54 pm.addNestedPass<func::FuncOp>(createLinalgGeneralizationPass()); 55 pm.addPass( 56 bufferization::createTensorCopyInsertionPass(getBufferizationOptions( 57 /*analysisOnly=*/options.testBufferizationAnalysisOnly))); 58 if (options.testBufferizationAnalysisOnly) 59 return; 60 pm.addPass(createSparsificationPass(options.sparsificationOptions())); 61 pm.addPass(createSparseTensorConversionPass( 62 options.sparseTensorConversionOptions())); 63 pm.addPass(createDenseBufferizationPass( 64 getBufferizationOptions(/*analysisOnly=*/false))); 65 pm.addNestedPass<func::FuncOp>( 66 mlir::bufferization::createFinalizingBufferizePass()); 67 // TODO(springerm): Add sparse support to the BufferDeallocation pass and add 68 // it to this pipeline. 69 pm.addNestedPass<func::FuncOp>(createConvertLinalgToLoopsPass()); 70 pm.addNestedPass<func::FuncOp>(createConvertVectorToSCFPass()); 71 pm.addNestedPass<func::FuncOp>(createConvertSCFToCFPass()); 72 pm.addPass(createLowerAffinePass()); 73 pm.addPass(createConvertVectorToLLVMPass(options.lowerVectorToLLVMOptions())); 74 pm.addPass(createMemRefToLLVMPass()); 75 pm.addNestedPass<func::FuncOp>(createConvertComplexToStandardPass()); 76 pm.addNestedPass<func::FuncOp>(createConvertMathToLLVMPass()); 77 pm.addPass(createConvertMathToLibmPass()); 78 pm.addPass(createConvertComplexToLibmPass()); 79 pm.addPass(createConvertComplexToLLVMPass()); 80 pm.addPass(createConvertFuncToLLVMPass()); 81 pm.addPass(createReconcileUnrealizedCastsPass()); 82 } 83 84 //===----------------------------------------------------------------------===// 85 // Pipeline registration. 86 //===----------------------------------------------------------------------===// 87 88 void mlir::sparse_tensor::registerSparseTensorPipelines() { 89 PassPipelineRegistration<SparseCompilerOptions>( 90 "sparse-compiler", 91 "The standard pipeline for taking sparsity-agnostic IR using the" 92 " sparse-tensor type, and lowering it to LLVM IR with concrete" 93 " representations and algorithms for sparse tensors.", 94 buildSparseCompiler); 95 } 96