Since the recent MemRef refactoring that centralizes the lowering of complex MemRef operations outside of the conversion framework, the MemRefToLLVM pass doesn't directly convert these complex operations. Instead, to fully convert the whole MemRef dialect space, MemRefToLLVM needs to run after `expand-strided-metadata`. Make this more obvious by changing the name of the pass and the option associated with it from `convert-memref-to-llvm` to `finalize-memref-to-llvm`. The word "finalize" conveys that this pass needs to run after something else and that something else is documented in its tablegen description. This is a follow-up patch related to the conversation at: https://discourse.llvm.org/t/psa-you-need-to-run-expand-strided-metadata-before-memref-to-llvm-now/66956/14 Differential Revision: https://reviews.llvm.org/D142463
98 lines
4.0 KiB
C++
98 lines
4.0 KiB
C++
//===- TestLowerToLLVM.cpp - Test lowering to LLVM as a sink pass ---------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements a pass for testing the lowering to LLVM as a generally
|
|
// usable sink pass.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
|
|
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h"
|
|
#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
|
|
#include "mlir/Conversion/LinalgToLLVM/LinalgToLLVM.h"
|
|
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
|
|
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
|
|
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
|
|
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
|
|
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
|
|
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
|
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
|
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
|
#include "mlir/Dialect/Linalg/Passes.h"
|
|
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
|
|
#include "mlir/IR/DialectRegistry.h"
|
|
#include "mlir/Pass/Pass.h"
|
|
#include "mlir/Pass/PassManager.h"
|
|
#include "mlir/Pass/PassOptions.h"
|
|
#include "mlir/Transforms/Passes.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
struct TestLowerToLLVMOptions
|
|
: public PassPipelineOptions<TestLowerToLLVMOptions> {
|
|
PassOptions::Option<bool> reassociateFPReductions{
|
|
*this, "reassociate-fp-reductions",
|
|
llvm::cl::desc("Allow reassociation og FP reductions"),
|
|
llvm::cl::init(false)};
|
|
};
|
|
|
|
void buildTestLowerToLLVM(OpPassManager &pm,
|
|
const TestLowerToLLVMOptions &options) {
|
|
|
|
// TODO: it is feasible to scope lowering at arbitrary level and introduce
|
|
// unrealized casts, but there needs to be the final module-wise cleanup in
|
|
// the end. Keep module-level for now.
|
|
|
|
// Blanket-convert any remaining high-level vector ops to loops if any remain.
|
|
pm.addNestedPass<func::FuncOp>(createConvertVectorToSCFPass());
|
|
// Blanket-convert any remaining linalg ops to loops if any remain.
|
|
pm.addNestedPass<func::FuncOp>(createConvertLinalgToLoopsPass());
|
|
// Blanket-convert any remaining affine ops if any remain.
|
|
pm.addPass(createLowerAffinePass());
|
|
// Convert SCF to CF (always needed).
|
|
pm.addPass(createConvertSCFToCFPass());
|
|
// Sprinkle some cleanups.
|
|
pm.addPass(createCanonicalizerPass());
|
|
pm.addPass(createCSEPass());
|
|
// Blanket-convert any remaining linalg ops to LLVM if any remain.
|
|
pm.addPass(createConvertLinalgToLLVMPass());
|
|
// Convert vector to LLVM (always needed).
|
|
pm.addPass(createConvertVectorToLLVMPass(
|
|
// TODO: add more options on a per-need basis.
|
|
LowerVectorToLLVMOptions().enableReassociateFPReductions(
|
|
options.reassociateFPReductions)));
|
|
// Convert Math to LLVM (always needed).
|
|
pm.addNestedPass<func::FuncOp>(createConvertMathToLLVMPass());
|
|
// Expand complicated MemRef operations before lowering them.
|
|
pm.addPass(memref::createExpandStridedMetadataPass());
|
|
// The expansion may create affine expressions. Get rid of them.
|
|
pm.addPass(createLowerAffinePass());
|
|
// Convert MemRef to LLVM (always needed).
|
|
pm.addPass(createFinalizeMemRefToLLVMConversionPass());
|
|
// Convert Func to LLVM (always needed).
|
|
pm.addPass(createConvertFuncToLLVMPass());
|
|
// Convert Index to LLVM (always needed).
|
|
pm.addPass(createConvertIndexToLLVMPass());
|
|
// Convert remaining unrealized_casts (always needed).
|
|
pm.addPass(createReconcileUnrealizedCastsPass());
|
|
}
|
|
} // namespace
|
|
|
|
namespace mlir {
|
|
namespace test {
|
|
void registerTestLowerToLLVM() {
|
|
PassPipelineRegistration<TestLowerToLLVMOptions>(
|
|
"test-lower-to-llvm",
|
|
"An example of pipeline to lower the main dialects (arith, linalg, "
|
|
"memref, scf, vector) down to LLVM.",
|
|
buildTestLowerToLLVM);
|
|
}
|
|
} // namespace test
|
|
} // namespace mlir
|