forked from OSchip/llvm-project
[mlir][Pass] Add support for generating pass utilities via tablegen
This revision adds support for generating utilities for passes such as options/statistics/etc. that can be inferred from the tablegen definition. This removes additional boilerplate from the pass, and also makes it easier to remove the reliance on the pass registry to provide certain things(e.g. the pass argument). Differential Revision: https://reviews.llvm.org/D76659
This commit is contained in:
parent
3dddd8969f
commit
9a277af2d4
|
@ -119,11 +119,25 @@ def ConvertLoopToStandard : Pass<"convert-loop-to-std"> {
|
|||
def ConvertSimpleLoopsToGPU : Pass<"convert-loops-to-gpu"> {
|
||||
let summary = "Convert top-level loops to GPU kernels";
|
||||
let constructor = "mlir::createSimpleLoopsToGPUPass()";
|
||||
let options = [
|
||||
Option<"numBlockDims", "gpu-block-dims", "unsigned", /*default=*/"1u",
|
||||
"Number of GPU block dimensions for mapping">,
|
||||
Option<"numThreadDims", "gpu-thread-dims", "unsigned", /*default=*/"1u",
|
||||
"Number of GPU thread dimensions for mapping">
|
||||
];
|
||||
}
|
||||
|
||||
def ConvertLoopsToGPU : Pass<"convert-loop-op-to-gpu"> {
|
||||
let summary = "Convert top-level loop::ForOp to GPU kernels";
|
||||
let constructor = "mlir::createLoopToGPUPass()";
|
||||
let options = [
|
||||
ListOption<"numWorkGroups", "gpu-num-workgroups", "int64_t",
|
||||
"Num workgroups in the GPU launch",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">,
|
||||
ListOption<"workGroupSize", "gpu-workgroup-size", "int64_t",
|
||||
"Workgroup Size in the GPU launch",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
|
||||
];
|
||||
}
|
||||
|
||||
def ConvertParallelLoopToGpu : Pass<"convert-parallel-loops-to-gpu"> {
|
||||
|
@ -139,6 +153,20 @@ def ConvertStandardToLLVM : Pass<"convert-std-to-llvm"> {
|
|||
let summary = "Convert scalar and vector operations from the Standard to the "
|
||||
"LLVM dialect";
|
||||
let constructor = "mlir::createLowerToLLVMPass()";
|
||||
let options = [
|
||||
Option<"useAlloca", "use-alloca", "bool", /*default=*/"false",
|
||||
"Use `alloca` instead of `call @malloc` for converting std.alloc">,
|
||||
Option<"useBarePtrCallConv", "use-bare-ptr-memref-call-conv", "bool",
|
||||
/*default=*/"false",
|
||||
"Replace FuncOp's MemRef arguments with bare pointers to the MemRef "
|
||||
"element types">,
|
||||
Option<"emitCWrappers", "emit-c-wrappers", "bool", /*default=*/"false",
|
||||
"Emit wrappers for C-compatible pointer-to-struct memref "
|
||||
"descriptors">,
|
||||
Option<"indexBitwidth", "index-bitwidth", "unsigned",
|
||||
/*default=*/"kDeriveIndexBitwidthFromDataLayout",
|
||||
"Bitwidth of the index type, 0 to use size of machine word">,
|
||||
];
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -43,6 +43,22 @@ def AffineLoopUnrollAndJam : Pass<"affine-loop-unroll-jam"> {
|
|||
def AffineVectorize : Pass<"affine-super-vectorize"> {
|
||||
let summary = "Vectorize to a target independent n-D vector abstraction";
|
||||
let constructor = "mlir::createSuperVectorizePass()";
|
||||
let options = [
|
||||
ListOption<"vectorSizes", "virtual-vector-size", "int64_t",
|
||||
"Specify an n-D virtual vector size for vectorization",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">,
|
||||
// Optionally, the fixed mapping from loop to fastest varying MemRef
|
||||
// dimension for all the MemRefs within a loop pattern:
|
||||
// the index represents the loop depth, the value represents the k^th
|
||||
// fastest varying memory dimension.
|
||||
// This is voluntarily restrictive and is meant to precisely target a
|
||||
// particular loop/op pair, for testing purposes.
|
||||
ListOption<"fastestVaryingPattern", "test-fastest-varying", "int64_t",
|
||||
"Specify a 1-D, 2-D or 3-D pattern of fastest varying memory "
|
||||
"dimensions to match. See defaultPatterns in Vectorize.cpp for "
|
||||
"a description and examples. This is used for testing purposes",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
|
||||
];
|
||||
}
|
||||
|
||||
def SimplifyAffineStructures : Pass<"simplify-affine-structures"> {
|
||||
|
|
|
@ -41,16 +41,30 @@ def LinalgLowerToParallelLoops : Pass<"convert-linalg-to-parallel-loops"> {
|
|||
def LinalgPromotion : Pass<"linalg-promote-subviews"> {
|
||||
let summary = "Promote subview ops to local buffers";
|
||||
let constructor = "mlir::createLinalgPromotionPass()";
|
||||
let options = [
|
||||
Option<"dynamicBuffers", "test-promote-dynamic", "bool",
|
||||
/*default=*/"false", "Test generation of dynamic promoted buffers">
|
||||
];
|
||||
}
|
||||
|
||||
def LinalgTiling : Pass<"linalg-tile"> {
|
||||
let summary = "Tile operations in the linalg dialect";
|
||||
let constructor = "mlir::createLinalgTilingPass()";
|
||||
let options = [
|
||||
ListOption<"tileSizes", "linalg-tile-sizes", "int64_t",
|
||||
"Test generation of dynamic promoted buffers",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
|
||||
];
|
||||
}
|
||||
|
||||
def LinalgTilingToParallelLoops : Pass<"linalg-tile-to-parallel-loops"> {
|
||||
let summary = "Tile operations in the linalg dialect to parallel loops";
|
||||
let constructor = "mlir::createLinalgTilingToParallelLoopsPass()";
|
||||
let options = [
|
||||
ListOption<"tileSizes", "linalg-tile-sizes", "int64_t",
|
||||
"Test generation of dynamic promoted buffers",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
|
||||
];
|
||||
}
|
||||
|
||||
#endif // MLIR_DIALECT_LINALG_PASSES
|
||||
|
|
|
@ -24,6 +24,11 @@ def LoopParallelLoopSpecialization : Pass<"parallel-loop-specialization"> {
|
|||
def LoopParallelLoopTiling : Pass<"parallel-loop-tiling"> {
|
||||
let summary = "Tile parallel loops";
|
||||
let constructor = "mlir::createParallelLoopTilingPass()";
|
||||
let options = [
|
||||
ListOption<"tileSizes", "parallel-loop-tile-sizes", "int64_t",
|
||||
"Factors to tile parallel loops by",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
|
||||
];
|
||||
}
|
||||
|
||||
#endif // MLIR_DIALECT_LOOP_PASSES
|
||||
|
|
|
@ -14,6 +14,50 @@
|
|||
#ifndef MLIR_PASS_PASSBASE
|
||||
#define MLIR_PASS_PASSBASE
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Options
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Option<string varName, string arg, string valueType, string default,
|
||||
string desc, string additionalFlags = ""> {
|
||||
// The name for the C++ option variable.
|
||||
string cppName = varName;
|
||||
|
||||
// The command line argument to use for this option.
|
||||
string argument = arg;
|
||||
|
||||
// The C++ type of the option.
|
||||
string type = valueType;
|
||||
|
||||
// The default value of the option. "" corresponds to no default.
|
||||
string defaultValue = default;
|
||||
|
||||
// A description for this option.
|
||||
string description = desc;
|
||||
|
||||
// A set of additional flags to pass along to the option constructor.
|
||||
string additionalOptFlags = additionalFlags;
|
||||
}
|
||||
|
||||
class ListOption<string varName, string arg, string valueType,
|
||||
string desc, string additionalFlags = "">
|
||||
: Option<varName, arg, valueType, /*default=*/"", desc, additionalFlags> {}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Statistics
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Statistic<string varName, string statName, string desc> {
|
||||
// The C++ variable name for the statistic.
|
||||
string cppName = varName;
|
||||
|
||||
// The displayed name of the statistic, similar to the argument of an option.
|
||||
string name = statName;
|
||||
|
||||
// The description of the statistic.
|
||||
string description = desc;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -30,6 +74,12 @@ class Pass<string passArg> {
|
|||
|
||||
// A C++ constructor call to create an instance of this pass.
|
||||
code constructor = [{}];
|
||||
|
||||
// A set of options provided by this pass.
|
||||
list<Option> options = [];
|
||||
|
||||
// A set of statistics provided by this pass.
|
||||
list<Statistic> statistics = [];
|
||||
}
|
||||
|
||||
#endif // MLIR_PASS_PASSBASE
|
||||
|
|
|
@ -18,6 +18,58 @@ class Record;
|
|||
|
||||
namespace mlir {
|
||||
namespace tblgen {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PassOption
|
||||
//===----------------------------------------------------------------------===//
|
||||
class PassOption {
|
||||
public:
|
||||
explicit PassOption(const llvm::Record *def) : def(def) {}
|
||||
|
||||
/// Return the name for the C++ option variable.
|
||||
StringRef getCppVariableName() const;
|
||||
|
||||
/// Return the command line argument to use for this option.
|
||||
StringRef getArgument() const;
|
||||
|
||||
/// Return the C++ type of the option.
|
||||
StringRef getType() const;
|
||||
|
||||
/// Return the default value of the option.
|
||||
Optional<StringRef> getDefaultValue() const;
|
||||
|
||||
/// Return the description for this option.
|
||||
StringRef getDescription() const;
|
||||
|
||||
/// Return the additional flags passed to the option constructor.
|
||||
Optional<StringRef> getAdditionalFlags() const;
|
||||
|
||||
/// Flag indicating if this is a list option.
|
||||
bool isListOption() const;
|
||||
|
||||
private:
|
||||
const llvm::Record *def;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PassStatistic
|
||||
//===----------------------------------------------------------------------===//
|
||||
class PassStatistic {
|
||||
public:
|
||||
explicit PassStatistic(const llvm::Record *def) : def(def) {}
|
||||
|
||||
/// Return the name for the C++ statistic variable.
|
||||
StringRef getCppVariableName() const;
|
||||
|
||||
/// Return the name of the statistic.
|
||||
StringRef getName() const;
|
||||
|
||||
/// Return the description for this statistic.
|
||||
StringRef getDescription() const;
|
||||
|
||||
private:
|
||||
const llvm::Record *def;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -39,8 +91,18 @@ public:
|
|||
/// Return the C++ constructor call to create an instance of this pass.
|
||||
StringRef getConstructor() const;
|
||||
|
||||
/// Return the options provided by this pass.
|
||||
ArrayRef<PassOption> getOptions() const;
|
||||
|
||||
/// Return the statistics provided by this pass.
|
||||
ArrayRef<PassStatistic> getStatistics() const;
|
||||
|
||||
const llvm::Record *getDef() const { return def; }
|
||||
|
||||
private:
|
||||
const llvm::Record *def;
|
||||
std::vector<PassOption> options;
|
||||
std::vector<PassStatistic> statistics;
|
||||
};
|
||||
|
||||
} // end namespace tblgen
|
||||
|
|
|
@ -35,6 +35,10 @@ def Canonicalizer : Pass<"canonicalize"> {
|
|||
def CSE : Pass<"cse"> {
|
||||
let summary = "Eliminate common sub-expressions";
|
||||
let constructor = "mlir::createCSEPass()";
|
||||
let statistics = [
|
||||
Statistic<"numCSE", "num-cse'd", "Number of operations CSE'd">,
|
||||
Statistic<"numDCE", "num-dce'd", "Number of operations DCE'd">
|
||||
];
|
||||
}
|
||||
|
||||
def Inliner : Pass<"inline"> {
|
||||
|
@ -45,6 +49,13 @@ def Inliner : Pass<"inline"> {
|
|||
def LocationSnapshot : Pass<"snapshot-op-locations"> {
|
||||
let summary = "Generate new locations from the current IR";
|
||||
let constructor = "mlir::createLocationSnapshotPass()";
|
||||
let options = [
|
||||
Option<"fileName", "filename", "std::string", /*default=*/"",
|
||||
"The filename to print the generated IR.">,
|
||||
Option<"tag", "tag", "std::string", /*default=*/"",
|
||||
"A tag to use when fusing the new locations with the "
|
||||
"original. If unset, the locations are replaced.">,
|
||||
];
|
||||
}
|
||||
|
||||
def LoopCoalescing : Pass<"loop-coalescing"> {
|
||||
|
@ -66,6 +77,17 @@ def MemRefDataFlowOpt : Pass<"memref-dataflow-opt"> {
|
|||
def ParallelLoopCollapsing : Pass<"parallel-loop-collapsing"> {
|
||||
let summary = "Collapse parallel loops to use less induction variables";
|
||||
let constructor = "mlir::createParallelLoopCollapsingPass()";
|
||||
let options = [
|
||||
ListOption<"clCollapsedIndices0", "collapsed-indices-0", "unsigned",
|
||||
"Which loop indices to combine 0th loop index",
|
||||
"llvm::cl::MiscFlags::CommaSeparated">,
|
||||
ListOption<"clCollapsedIndices1", "collapsed-indices-1", "unsigned",
|
||||
"Which loop indices to combine into the position 1 loop index",
|
||||
"llvm::cl::MiscFlags::CommaSeparated">,
|
||||
ListOption<"clCollapsedIndices2", "collapsed-indices-2", "unsigned",
|
||||
"Which loop indices to combine into the position 2 loop index",
|
||||
"llvm::cl::MiscFlags::CommaSeparated">,
|
||||
];
|
||||
}
|
||||
|
||||
def PrintCFG : Pass<"print-cfg-graph"> {
|
||||
|
|
|
@ -164,6 +164,10 @@ void mlir::populateAVX512ToLLVMConversionPatterns(
|
|||
|
||||
namespace {
|
||||
struct ConvertAVX512ToLLVMPass : public ModulePass<ConvertAVX512ToLLVMPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertAVX512ToLLVM
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -578,6 +578,10 @@ void mlir::populateAffineToStdConversionPatterns(
|
|||
|
||||
namespace {
|
||||
class LowerAffinePass : public FunctionPass<LowerAffinePass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertAffineToStandard
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
OwningRewritePatternList patterns;
|
||||
populateAffineToStdConversionPatterns(patterns, &getContext());
|
||||
|
|
|
@ -63,6 +63,10 @@ namespace {
|
|||
class GpuLaunchFuncToCudaCallsPass
|
||||
: public ModulePass<GpuLaunchFuncToCudaCallsPass> {
|
||||
private:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertGpuLaunchFuncToCudaCalls
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
LLVM::LLVMDialect *getLLVMDialect() { return llvmDialect; }
|
||||
|
||||
llvm::LLVMContext &getLLVMContext() {
|
||||
|
|
|
@ -248,6 +248,10 @@ struct GPUReturnOpLowering : public ConvertToLLVMPattern {
|
|||
class LowerGpuOpsToNVVMOpsPass
|
||||
: public OperationPass<LowerGpuOpsToNVVMOpsPass, gpu::GPUModuleOp> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertGpuOpsToNVVMOps
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
gpu::GPUModuleOp m = getOperation();
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ namespace {
|
|||
class LowerGpuOpsToROCDLOpsPass
|
||||
: public OperationPass<LowerGpuOpsToROCDLOpsPass, gpu::GPUModuleOp> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertGpuOpsToROCDLOps
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
gpu::GPUModuleOp m = getOperation();
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ namespace {
|
|||
///
|
||||
/// 2) Lower the body of the spirv::ModuleOp.
|
||||
struct GPUToSPIRVPass : public ModulePass<GPUToSPIRVPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertGpuToSPIRV
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -40,6 +40,10 @@ namespace {
|
|||
class ConvertGpuLaunchFuncToVulkanLaunchFunc
|
||||
: public ModulePass<ConvertGpuLaunchFuncToVulkanLaunchFunc> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertGpuLaunchFuncToVulkanLaunchFunc
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -59,6 +59,10 @@ namespace {
|
|||
class VulkanLaunchFuncToVulkanCallsPass
|
||||
: public ModulePass<VulkanLaunchFuncToVulkanCallsPass> {
|
||||
private:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertVulkanLaunchFuncToVulkanCalls
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
LLVM::LLVMDialect *getLLVMDialect() { return llvmDialect; }
|
||||
|
||||
llvm::LLVMContext &getLLVMContext() {
|
||||
|
|
|
@ -557,6 +557,10 @@ void mlir::populateLinalgToLLVMConversionPatterns(
|
|||
|
||||
namespace {
|
||||
struct ConvertLinalgToLLVMPass : public ModulePass<ConvertLinalgToLLVMPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertLinalgToLLVM
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -17,6 +17,10 @@ using namespace mlir;
|
|||
namespace {
|
||||
/// A pass converting MLIR Linalg ops into SPIR-V ops.
|
||||
class LinalgToSPIRVPass : public ModulePass<LinalgToSPIRVPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertLinalgToSPIRV
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -31,6 +31,10 @@ using namespace mlir::loop;
|
|||
namespace {
|
||||
|
||||
struct LoopToStandardPass : public OperationPass<LoopToStandardPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertLoopToStandard
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace {
|
|||
// GPU launch operations. Nested launches are not allowed, so this does not
|
||||
// walk the function recursively to avoid considering nested loops.
|
||||
struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertSimpleLoopsToGPU
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
ForLoopMapper() = default;
|
||||
ForLoopMapper(const ForLoopMapper &) {}
|
||||
ForLoopMapper(unsigned numBlockDims, unsigned numThreadDims) {
|
||||
|
@ -50,15 +54,6 @@ struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Option<unsigned> numBlockDims{
|
||||
*this, "gpu-block-dims",
|
||||
llvm::cl::desc("Number of GPU block dimensions for mapping"),
|
||||
llvm::cl::init(1u)};
|
||||
Option<unsigned> numThreadDims{
|
||||
*this, "gpu-thread-dims",
|
||||
llvm::cl::desc("Number of GPU thread dimensions for mapping"),
|
||||
llvm::cl::init(1u)};
|
||||
};
|
||||
|
||||
// A pass that traverses top-level loops in the function and convertes them to
|
||||
|
@ -68,6 +63,10 @@ struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
|
|||
// to be perfectly nested upto depth equal to size of `workGroupSize`.
|
||||
struct ImperfectlyNestedForLoopMapper
|
||||
: public FunctionPass<ImperfectlyNestedForLoopMapper> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertLoopsToGPU
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
ImperfectlyNestedForLoopMapper() = default;
|
||||
ImperfectlyNestedForLoopMapper(const ImperfectlyNestedForLoopMapper &) {}
|
||||
ImperfectlyNestedForLoopMapper(ArrayRef<int64_t> numWorkGroups,
|
||||
|
@ -103,17 +102,13 @@ struct ImperfectlyNestedForLoopMapper
|
|||
}
|
||||
}
|
||||
}
|
||||
ListOption<int64_t> numWorkGroups{
|
||||
*this, "gpu-num-workgroups",
|
||||
llvm::cl::desc("Num workgroups in the GPU launch"), llvm::cl::ZeroOrMore,
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
ListOption<int64_t> workGroupSize{
|
||||
*this, "gpu-workgroup-size",
|
||||
llvm::cl::desc("Workgroup Size in the GPU launch"), llvm::cl::ZeroOrMore,
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
};
|
||||
|
||||
struct ParallelLoopToGpuPass : public OperationPass<ParallelLoopToGpuPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertParallelLoopToGpu
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
OwningRewritePatternList patterns;
|
||||
populateParallelLoopToGPUPatterns(patterns, &getContext());
|
||||
|
|
|
@ -2798,6 +2798,10 @@ LLVMTypeConverter::promoteMemRefDescriptors(Location loc, ValueRange opOperands,
|
|||
namespace {
|
||||
/// A pass converting MLIR operations into the LLVM IR dialect.
|
||||
struct LLVMLoweringPass : public ModulePass<LLVMLoweringPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertStandardToLLVM
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
/// Creates an LLVM lowering pass.
|
||||
LLVMLoweringPass(bool useAlloca, bool useBarePtrCallConv, bool emitCWrappers,
|
||||
unsigned indexBitwidth) {
|
||||
|
@ -2840,31 +2844,6 @@ struct LLVMLoweringPass : public ModulePass<LLVMLoweringPass> {
|
|||
signalPassFailure();
|
||||
}
|
||||
|
||||
/// Use `alloca` instead of `call @malloc` for converting std.alloc.
|
||||
Option<bool> useAlloca{
|
||||
*this, "use-alloca",
|
||||
llvm::cl::desc("Replace emission of malloc/free by alloca"),
|
||||
llvm::cl::init(false)};
|
||||
|
||||
/// Convert memrefs to bare pointers in function signatures.
|
||||
Option<bool> useBarePtrCallConv{
|
||||
*this, "use-bare-ptr-memref-call-conv",
|
||||
llvm::cl::desc("Replace FuncOp's MemRef arguments with "
|
||||
"bare pointers to the MemRef element types"),
|
||||
llvm::cl::init(false)};
|
||||
|
||||
/// Emit wrappers for C-compatible pointer-to-struct memref descriptors.
|
||||
Option<bool> emitCWrappers{
|
||||
*this, "emit-c-wrappers",
|
||||
llvm::cl::desc("Emit C-compatible wrapper functions"),
|
||||
llvm::cl::init(false)};
|
||||
|
||||
/// Configure the bitwidth of the index type when lowered to LLVM.
|
||||
Option<unsigned> indexBitwidth{
|
||||
*this, "index-bitwidth",
|
||||
llvm::cl::desc(
|
||||
"Bitwidth of the index type, 0 to use size of machine word"),
|
||||
llvm::cl::init(kDeriveIndexBitwidthFromDataLayout)};
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace {
|
|||
/// A pass converting MLIR Standard operations into the SPIR-V dialect.
|
||||
class ConvertStandardToSPIRVPass
|
||||
: public ModulePass<ConvertStandardToSPIRVPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertStandardToSPIRV
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -161,6 +161,10 @@ void mlir::populateStdLegalizationPatternsForSPIRVLowering(
|
|||
|
||||
namespace {
|
||||
struct SPIRVLegalization final : public OperationPass<SPIRVLegalization> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LegalizeStandardForSPIRV
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -1119,6 +1119,10 @@ void mlir::populateVectorToLLVMMatrixConversionPatterns(
|
|||
|
||||
namespace {
|
||||
struct LowerVectorToLLVMPass : public ModulePass<LowerVectorToLLVMPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ConvertVectorToLLVM
|
||||
#include "mlir/Conversion/Passes.h.inc"
|
||||
|
||||
void runOnModule() override;
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -75,6 +75,10 @@ namespace {
|
|||
// are strided. Check for strided stores.
|
||||
struct AffineDataCopyGeneration
|
||||
: public FunctionPass<AffineDataCopyGeneration> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineDataCopyGeneration
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
explicit AffineDataCopyGeneration(
|
||||
unsigned slowMemorySpace = 0,
|
||||
unsigned fastMemorySpace = clFastMemorySpace, unsigned tagMemorySpace = 0,
|
||||
|
|
|
@ -42,6 +42,10 @@ namespace {
|
|||
/// TODO: This code should be removed once the new LICM pass can handle its
|
||||
/// uses.
|
||||
struct LoopInvariantCodeMotion : public FunctionPass<LoopInvariantCodeMotion> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineLoopInvariantCodeMotion
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
void runOnAffineForOp(AffineForOp forOp);
|
||||
};
|
||||
|
|
|
@ -59,6 +59,10 @@ namespace {
|
|||
|
||||
/// A pass to perform loop tiling on all suitable loop nests of a Function.
|
||||
struct LoopTiling : public FunctionPass<LoopTiling> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineLoopTiling
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
explicit LoopTiling(uint64_t cacheSizeBytes = kDefaultCacheMemCapacity,
|
||||
bool avoidMaxMinBounds = true)
|
||||
: cacheSizeBytes(cacheSizeBytes), avoidMaxMinBounds(avoidMaxMinBounds) {}
|
||||
|
|
|
@ -59,6 +59,10 @@ namespace {
|
|||
/// with trip count less than the specified threshold. The latter is for testing
|
||||
/// purposes, especially for testing outer loop unrolling.
|
||||
struct LoopUnroll : public FunctionPass<LoopUnroll> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineUnroll
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
const Optional<unsigned> unrollFactor;
|
||||
const Optional<bool> unrollFull;
|
||||
// Callback to obtain unroll factors; if this has a callable target, takes
|
||||
|
|
|
@ -61,6 +61,10 @@ namespace {
|
|||
/// Loop unroll jam pass. Currently, this just unroll jams the first
|
||||
/// outer loop in a Function.
|
||||
struct LoopUnrollAndJam : public FunctionPass<LoopUnrollAndJam> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineLoopUnrollAndJam
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
Optional<unsigned> unrollJamFactor;
|
||||
static const unsigned kDefaultUnrollJamFactor = 4;
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ namespace {
|
|||
/// identity layout ones.
|
||||
struct SimplifyAffineStructures
|
||||
: public FunctionPass<SimplifyAffineStructures> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_SimplifyAffineStructures
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
|
||||
/// Utility to simplify an affine attribute and update its entry in the parent
|
||||
|
|
|
@ -574,29 +574,14 @@ namespace {
|
|||
/// Base state for the vectorize pass.
|
||||
/// Command line arguments are preempted by non-empty pass arguments.
|
||||
struct Vectorize : public FunctionPass<Vectorize> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineVectorize
|
||||
#include "mlir/Dialect/Affine/Passes.h.inc"
|
||||
|
||||
Vectorize() = default;
|
||||
Vectorize(const Vectorize &) {}
|
||||
Vectorize(ArrayRef<int64_t> virtualVectorSize);
|
||||
void runOnFunction() override;
|
||||
|
||||
/// The virtual vector size that we vectorize to.
|
||||
ListOption<int64_t> vectorSizes{
|
||||
*this, "virtual-vector-size",
|
||||
llvm::cl::desc("Specify an n-D virtual vector size for vectorization"),
|
||||
llvm::cl::ZeroOrMore, llvm::cl::CommaSeparated};
|
||||
/// Optionally, the fixed mapping from loop to fastest varying MemRef
|
||||
/// dimension for all the MemRefs within a loop pattern:
|
||||
/// the index represents the loop depth, the value represents the k^th
|
||||
/// fastest varying memory dimension.
|
||||
/// This is voluntarily restrictive and is meant to precisely target a
|
||||
/// particular loop/op pair, for testing purposes.
|
||||
ListOption<int64_t> fastestVaryingPattern{
|
||||
*this, "test-fastest-varying",
|
||||
llvm::cl::desc(
|
||||
"Specify a 1-D, 2-D or 3-D pattern of fastest varying memory"
|
||||
" dimensions to match. See defaultPatterns in Vectorize.cpp for a"
|
||||
" description and examples. This is used for testing purposes"),
|
||||
llvm::cl::ZeroOrMore, llvm::cl::CommaSeparated};
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
|
|
@ -21,13 +21,20 @@ using namespace mlir::fxpmath::detail;
|
|||
using namespace mlir::quant;
|
||||
|
||||
namespace {
|
||||
|
||||
struct LowerUniformRealMathPass
|
||||
: public FunctionPass<LowerUniformRealMathPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_FxpMathLowerUniformRealMath
|
||||
#include "mlir/Dialect/FxpMathOps/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
};
|
||||
|
||||
struct LowerUniformCastsPass : public FunctionPass<LowerUniformCastsPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_FxpMathLowerUniformCasts
|
||||
#include "mlir/Dialect/FxpMathOps/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -205,7 +205,6 @@ static void convertToLaunchFuncOp(gpu::LaunchOp launchOp,
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// Pass that moves the kernel of each LaunchOp into its separate nested module.
|
||||
///
|
||||
/// This pass moves the kernel code of each LaunchOp into a function created
|
||||
|
@ -217,6 +216,10 @@ namespace {
|
|||
/// symbol of the cubin accessor function.
|
||||
class GpuKernelOutliningPass : public ModulePass<GpuKernelOutliningPass> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_GpuKernelOutlining
|
||||
#include "mlir/Dialect/GPU/Passes.h.inc"
|
||||
|
||||
void runOnModule() override {
|
||||
SymbolTable symbolTable(getModule());
|
||||
bool modified = false;
|
||||
|
|
|
@ -58,6 +58,10 @@ void mlir::LLVM::ensureDistinctSuccessors(Operation *op) {
|
|||
|
||||
namespace {
|
||||
struct LegalizeForExportPass : public OperationPass<LegalizeForExportPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LLVMLegalizeForExport
|
||||
#include "mlir/Dialect/LLVMIR/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
LLVM::ensureDistinctSuccessors(getOperation());
|
||||
}
|
||||
|
|
|
@ -568,6 +568,10 @@ struct FuseGenericTensorOps : public OpRewritePattern<GenericOp> {
|
|||
|
||||
/// Pass that fuses generic ops on tensors. Used only for testing.
|
||||
struct FusionOfTensorOpsPass : public OperationPass<FusionOfTensorOpsPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgFusionOfTensorOps
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
OwningRewritePatternList patterns;
|
||||
Operation *op = getOperation();
|
||||
|
@ -577,6 +581,10 @@ struct FusionOfTensorOpsPass : public OperationPass<FusionOfTensorOpsPass> {
|
|||
};
|
||||
|
||||
struct LinalgFusionPass : public FunctionPass<LinalgFusionPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgFusion
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override { fuseLinalgOpsGreedily(getFunction()); }
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -640,14 +640,6 @@ void FillRewritePatterns(OwningRewritePatternList &patterns, MLIRContext *ctx) {
|
|||
>::build(patterns, ctx);
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename LoopType, typename IndexedValueType>
|
||||
struct LowerLinalgToLoopsPass
|
||||
: public FunctionPass<LowerLinalgToLoopsPass<LoopType, IndexedValueType>> {
|
||||
void runOnFunction() override;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Local folding pattern for AffineApplyOp that we can apply greedily.
|
||||
// This replaces AffineApplyOp by the proper value in cases where the associated
|
||||
// map is trivial. A trivial map here is defined as a map with a single result
|
||||
|
@ -687,8 +679,7 @@ struct FoldAffineOp : public RewritePattern {
|
|||
} // namespace
|
||||
|
||||
template <typename LoopType, typename IndexedValueType>
|
||||
void LowerLinalgToLoopsPass<LoopType, IndexedValueType>::runOnFunction() {
|
||||
auto *context = &this->getContext();
|
||||
static void lowerLinalgToLoopsImpl(Operation *op, MLIRContext *context) {
|
||||
OwningRewritePatternList patterns;
|
||||
// Canonicalization and folding patterns applied greedily allow cleaning up
|
||||
// the emitted IR on the fly.
|
||||
|
@ -698,24 +689,54 @@ void LowerLinalgToLoopsPass<LoopType, IndexedValueType>::runOnFunction() {
|
|||
AffineApplyOp::getCanonicalizationPatterns(patterns, context);
|
||||
patterns.insert<FoldAffineOp>(context);
|
||||
// Just apply the patterns greedily.
|
||||
applyPatternsGreedily(this->getFunction(), patterns);
|
||||
applyPatternsGreedily(op, patterns);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct LowerToAffineLoops : public FunctionPass<LowerToAffineLoops> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgLowerToAffineLoops
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
lowerLinalgToLoopsImpl<AffineForOp, AffineIndexedValue>(getFunction(),
|
||||
&getContext());
|
||||
}
|
||||
};
|
||||
struct LowerToLoops : public FunctionPass<LowerToLoops> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgLowerToLoops
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
lowerLinalgToLoopsImpl<loop::ForOp, StdIndexedValue>(getFunction(),
|
||||
&getContext());
|
||||
}
|
||||
};
|
||||
struct LowerToParallelLoops : public FunctionPass<LowerToParallelLoops> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgLowerToParallelLoops
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
lowerLinalgToLoopsImpl<loop::ParallelOp, StdIndexedValue>(getFunction(),
|
||||
&getContext());
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<OpPassBase<FuncOp>> mlir::createConvertLinalgToLoopsPass() {
|
||||
return std::make_unique<
|
||||
LowerLinalgToLoopsPass<loop::ForOp, StdIndexedValue>>();
|
||||
return std::make_unique<LowerToLoops>();
|
||||
}
|
||||
|
||||
std::unique_ptr<OpPassBase<FuncOp>>
|
||||
mlir::createConvertLinalgToParallelLoopsPass() {
|
||||
return std::make_unique<
|
||||
LowerLinalgToLoopsPass<loop::ParallelOp, StdIndexedValue>>();
|
||||
return std::make_unique<LowerToParallelLoops>();
|
||||
}
|
||||
|
||||
std::unique_ptr<OpPassBase<FuncOp>>
|
||||
mlir::createConvertLinalgToAffineLoopsPass() {
|
||||
return std::make_unique<
|
||||
LowerLinalgToLoopsPass<AffineForOp, AffineIndexedValue>>();
|
||||
return std::make_unique<LowerToAffineLoops>();
|
||||
}
|
||||
|
||||
/// Emits a loop nest of `loop.for` with the proper body for `op`.
|
||||
|
|
|
@ -231,6 +231,10 @@ static void promoteSubViews(FuncOp f, bool dynamicBuffers) {
|
|||
|
||||
namespace {
|
||||
struct LinalgPromotionPass : public FunctionPass<LinalgPromotionPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgPromotion
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
LinalgPromotionPass() = default;
|
||||
LinalgPromotionPass(const LinalgPromotionPass &) {}
|
||||
LinalgPromotionPass(bool dynamicBuffers) {
|
||||
|
@ -240,11 +244,6 @@ struct LinalgPromotionPass : public FunctionPass<LinalgPromotionPass> {
|
|||
void runOnFunction() override {
|
||||
promoteSubViews(getFunction(), dynamicBuffers);
|
||||
}
|
||||
|
||||
Option<bool> dynamicBuffers{
|
||||
*this, "test-promote-dynamic",
|
||||
llvm::cl::desc("Test generation of dynamic promoted buffers"),
|
||||
llvm::cl::init(false)};
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -507,33 +507,47 @@ static void tileLinalgOps(FuncOp f, ArrayRef<int64_t> tileSizes) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
struct LinalgTilingPass : public FunctionPass<LinalgTilingPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgTiling
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
template <typename LoopTy>
|
||||
struct LinalgTilingPass : public FunctionPass<LinalgTilingPass<LoopTy>> {
|
||||
LinalgTilingPass() = default;
|
||||
LinalgTilingPass(const LinalgTilingPass &) {}
|
||||
LinalgTilingPass(ArrayRef<int64_t> sizes) {
|
||||
this->tileSizes->assign(sizes.begin(), sizes.end());
|
||||
tileSizes->assign(sizes.begin(), sizes.end());
|
||||
}
|
||||
|
||||
void runOnFunction() override {
|
||||
tileLinalgOps<LoopTy>(this->getFunction(), tileSizes);
|
||||
tileLinalgOps<loop::ForOp>(getFunction(), tileSizes);
|
||||
}
|
||||
};
|
||||
|
||||
struct LinalgTilingToParallelLoopsPass
|
||||
: public FunctionPass<LinalgTilingToParallelLoopsPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LinalgTilingToParallelLoops
|
||||
#include "mlir/Dialect/Linalg/Passes.h.inc"
|
||||
|
||||
LinalgTilingToParallelLoopsPass() = default;
|
||||
LinalgTilingToParallelLoopsPass(const LinalgTilingToParallelLoopsPass &) {}
|
||||
LinalgTilingToParallelLoopsPass(ArrayRef<int64_t> sizes) {
|
||||
tileSizes->assign(sizes.begin(), sizes.end());
|
||||
}
|
||||
|
||||
Pass::ListOption<int64_t> tileSizes{
|
||||
*this, "linalg-tile-sizes",
|
||||
llvm::cl::desc("Tile sizes by which to tile linalg operations"),
|
||||
llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated};
|
||||
void runOnFunction() override {
|
||||
tileLinalgOps<loop::ParallelOp>(getFunction(), tileSizes);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<OpPassBase<FuncOp>>
|
||||
mlir::createLinalgTilingPass(ArrayRef<int64_t> tileSizes) {
|
||||
return std::make_unique<LinalgTilingPass<loop::ForOp>>(tileSizes);
|
||||
return std::make_unique<LinalgTilingPass>(tileSizes);
|
||||
}
|
||||
|
||||
std::unique_ptr<OpPassBase<FuncOp>>
|
||||
mlir::createLinalgTilingToParallelLoopsPass(ArrayRef<int64_t> tileSizes) {
|
||||
return std::make_unique<LinalgTilingPass<loop::ParallelOp>>(tileSizes);
|
||||
return std::make_unique<LinalgTilingToParallelLoopsPass>(tileSizes);
|
||||
}
|
||||
|
|
|
@ -160,8 +160,11 @@ void mlir::loop::naivelyFuseParallelOps(Region ®ion) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct ParallelLoopFusion : public OperationPass<ParallelLoopFusion> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LoopParallelLoopFusion
|
||||
#include "mlir/Dialect/LoopOps/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
for (Region ®ion : getOperation()->getRegions())
|
||||
naivelyFuseParallelOps(region);
|
||||
|
|
|
@ -61,6 +61,10 @@ static void specializeLoopForUnrolling(ParallelOp op) {
|
|||
namespace {
|
||||
struct ParallelLoopSpecialization
|
||||
: public FunctionPass<ParallelLoopSpecialization> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LoopParallelLoopSpecialization
|
||||
#include "mlir/Dialect/LoopOps/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
getFunction().walk([](ParallelOp op) { specializeLoopForUnrolling(op); });
|
||||
}
|
||||
|
|
|
@ -102,8 +102,12 @@ static bool getInnermostNestedLoops(Block *block,
|
|||
|
||||
namespace {
|
||||
struct ParallelLoopTiling : public FunctionPass<ParallelLoopTiling> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LoopParallelLoopTiling
|
||||
#include "mlir/Dialect/LoopOps/Passes.h.inc"
|
||||
|
||||
ParallelLoopTiling() = default;
|
||||
ParallelLoopTiling(const ParallelLoopTiling &) {} // tileSize is non-copyable.
|
||||
ParallelLoopTiling(const ParallelLoopTiling &) {}
|
||||
explicit ParallelLoopTiling(ArrayRef<int64_t> tileSizes) {
|
||||
this->tileSizes = tileSizes;
|
||||
}
|
||||
|
@ -117,11 +121,6 @@ struct ParallelLoopTiling : public FunctionPass<ParallelLoopTiling> {
|
|||
tileParallelLoop(pLoop, tileSizes);
|
||||
}
|
||||
}
|
||||
|
||||
ListOption<int64_t> tileSizes{
|
||||
*this, "parallel-loop-tile-sizes",
|
||||
llvm::cl::desc("factors to tile parallel loops by"), llvm::cl::ZeroOrMore,
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ using namespace mlir;
|
|||
using namespace mlir::quant;
|
||||
|
||||
namespace {
|
||||
struct ConvertConstPass : public FunctionPass<ConvertConstPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_QuantConvertConst
|
||||
#include "mlir/Dialect/Quant/Passes.h.inc"
|
||||
|
||||
class ConvertConstPass : public FunctionPass<ConvertConstPass> {
|
||||
public:
|
||||
void runOnFunction() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,10 +19,12 @@ using namespace mlir;
|
|||
using namespace mlir::quant;
|
||||
|
||||
namespace {
|
||||
|
||||
class ConvertSimulatedQuantPass
|
||||
struct ConvertSimulatedQuantPass
|
||||
: public FunctionPass<ConvertSimulatedQuantPass> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_QuantConvertSimulatedQuant
|
||||
#include "mlir/Dialect/Quant/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,9 +29,12 @@ using namespace mlir::quantizer;
|
|||
using namespace mlir::quant;
|
||||
|
||||
namespace {
|
||||
|
||||
class AddDefaultStatsPass : public FunctionPass<AddDefaultStatsPass> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_QuantizerAddDefaultStats
|
||||
#include "mlir/Quantizer/Transforms/Passes.h.inc"
|
||||
|
||||
AddDefaultStatsPass() = default;
|
||||
AddDefaultStatsPass(SolverContext &solverContext,
|
||||
const TargetConfiguration &config)
|
||||
|
|
|
@ -71,13 +71,17 @@ struct DOTGraphTraits<const CAGSlice *>
|
|||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
class InferQuantizedTypesPass : public ModulePass<InferQuantizedTypesPass> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_QuantizerInferQuantizedTypes
|
||||
#include "mlir/Quantizer/Transforms/Passes.h.inc"
|
||||
|
||||
InferQuantizedTypesPass() = default;
|
||||
InferQuantizedTypesPass(SolverContext &solverContext,
|
||||
const TargetConfiguration &config)
|
||||
: explicitSolverContext(&solverContext), explicitConfig(&config) {}
|
||||
|
||||
void runOnModule() override;
|
||||
void runWithConfig(SolverContext &solverContext,
|
||||
const TargetConfiguration &config);
|
||||
|
|
|
@ -23,9 +23,12 @@ using namespace mlir::quantizer;
|
|||
using namespace mlir::quant;
|
||||
|
||||
namespace {
|
||||
|
||||
class RemoveInstrumentationPass
|
||||
: public FunctionPass<RemoveInstrumentationPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_QuantizerRemoveInstrumentation
|
||||
#include "mlir/Quantizer/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,11 +12,64 @@
|
|||
using namespace mlir;
|
||||
using namespace mlir::tblgen;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PassOption
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
StringRef PassOption::getCppVariableName() const {
|
||||
return def->getValueAsString("cppName");
|
||||
}
|
||||
|
||||
StringRef PassOption::getArgument() const {
|
||||
return def->getValueAsString("argument");
|
||||
}
|
||||
|
||||
StringRef PassOption::getType() const { return def->getValueAsString("type"); }
|
||||
|
||||
Optional<StringRef> PassOption::getDefaultValue() const {
|
||||
StringRef defaultVal = def->getValueAsString("defaultValue");
|
||||
return defaultVal.empty() ? Optional<StringRef>() : defaultVal;
|
||||
}
|
||||
|
||||
StringRef PassOption::getDescription() const {
|
||||
return def->getValueAsString("description");
|
||||
}
|
||||
|
||||
Optional<StringRef> PassOption::getAdditionalFlags() const {
|
||||
StringRef additionalFlags = def->getValueAsString("additionalOptFlags");
|
||||
return additionalFlags.empty() ? Optional<StringRef>() : additionalFlags;
|
||||
}
|
||||
|
||||
bool PassOption::isListOption() const {
|
||||
return def->isSubClassOf("ListOption");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PassStatistic
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
StringRef PassStatistic::getCppVariableName() const {
|
||||
return def->getValueAsString("cppName");
|
||||
}
|
||||
|
||||
StringRef PassStatistic::getName() const {
|
||||
return def->getValueAsString("name");
|
||||
}
|
||||
|
||||
StringRef PassStatistic::getDescription() const {
|
||||
return def->getValueAsString("description");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Pass::Pass(const llvm::Record *def) : def(def) {}
|
||||
Pass::Pass(const llvm::Record *def) : def(def) {
|
||||
for (auto *init : def->getValueAsListOfDefs("options"))
|
||||
options.push_back(PassOption(init));
|
||||
for (auto *init : def->getValueAsListOfDefs("statistics"))
|
||||
statistics.push_back(PassStatistic(init));
|
||||
}
|
||||
|
||||
StringRef Pass::getArgument() const {
|
||||
return def->getValueAsString("argument");
|
||||
|
@ -31,3 +84,7 @@ StringRef Pass::getDescription() const {
|
|||
StringRef Pass::getConstructor() const {
|
||||
return def->getValueAsString("constructor");
|
||||
}
|
||||
|
||||
ArrayRef<PassOption> Pass::getOptions() const { return options; }
|
||||
|
||||
ArrayRef<PassStatistic> Pass::getStatistics() const { return statistics; }
|
||||
|
|
|
@ -74,6 +74,10 @@ struct SimpleOperationInfo : public llvm::DenseMapInfo<Operation *> {
|
|||
namespace {
|
||||
/// Simple common sub-expression elimination.
|
||||
struct CSE : public OperationPass<CSE> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_CSE
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
CSE() = default;
|
||||
CSE(const CSE &) {}
|
||||
|
||||
|
@ -114,10 +118,6 @@ struct CSE : public OperationPass<CSE> {
|
|||
private:
|
||||
/// Operations marked as dead and to be erased.
|
||||
std::vector<Operation *> opsToErase;
|
||||
|
||||
/// Statistics for CSE.
|
||||
Statistic numCSE{this, "num-cse'd", "Number of operations CSE'd"};
|
||||
Statistic numDCE{this, "num-dce'd", "Number of operations trivially DCE'd"};
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@ using namespace mlir;
|
|||
namespace {
|
||||
/// Canonicalize operations in nested regions.
|
||||
struct Canonicalizer : public OperationPass<Canonicalizer> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_Canonicalizer
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
OwningRewritePatternList patterns;
|
||||
|
||||
|
|
|
@ -590,6 +590,10 @@ static void inlineSCC(Inliner &inliner, CGUseList &useList,
|
|||
|
||||
namespace {
|
||||
struct InlinerPass : public OperationPass<InlinerPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_Inliner
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override {
|
||||
CallGraph &cg = getAnalysis<CallGraph>();
|
||||
auto *context = &getContext();
|
||||
|
|
|
@ -123,8 +123,11 @@ LogicalResult mlir::generateLocationsFromIR(StringRef fileName, StringRef tag,
|
|||
}
|
||||
|
||||
namespace {
|
||||
class LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
|
||||
public:
|
||||
struct LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LocationSnapshot
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
LocationSnapshotPass() = default;
|
||||
LocationSnapshotPass(const LocationSnapshotPass &) {}
|
||||
LocationSnapshotPass(OpPrintingFlags flags, StringRef fileName, StringRef tag)
|
||||
|
@ -139,14 +142,6 @@ public:
|
|||
return signalPassFailure();
|
||||
}
|
||||
|
||||
Option<std::string> fileName{
|
||||
*this, "filename",
|
||||
llvm::cl::desc("The filename to print the generated IR.")};
|
||||
Option<std::string> tag{
|
||||
*this, "tag",
|
||||
llvm::cl::desc("A tag to use when fusing the new locations with the "
|
||||
"original. If unset, the locations are replaced.")};
|
||||
|
||||
/// The printing flags to use when creating the snapshot.
|
||||
OpPrintingFlags flags;
|
||||
};
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
using namespace mlir;
|
||||
|
||||
namespace {
|
||||
class LoopCoalescingPass : public FunctionPass<LoopCoalescingPass> {
|
||||
public:
|
||||
struct LoopCoalescingPass : public FunctionPass<LoopCoalescingPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LoopCoalescing
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override {
|
||||
FuncOp func = getFunction();
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ static llvm::cl::opt<unsigned long long> clFusionLocalBufThreshold(
|
|||
llvm::cl::cat(clOptionsCategory));
|
||||
|
||||
namespace {
|
||||
|
||||
/// Loop fusion pass. This pass currently supports a greedy fusion policy,
|
||||
/// which fuses loop nests with single-writer/single-reader memref dependences
|
||||
/// with the goal of improving locality.
|
||||
|
@ -79,6 +78,10 @@ namespace {
|
|||
// and add support for more general loop fusion algorithms.
|
||||
|
||||
struct LoopFusion : public FunctionPass<LoopFusion> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffineLoopFusion
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
LoopFusion(unsigned fastMemorySpace = 0, uint64_t localBufSizeThreshold = 0,
|
||||
bool maximalFusion = false)
|
||||
: localBufSizeThreshold(localBufSizeThreshold),
|
||||
|
|
|
@ -28,7 +28,10 @@ using namespace mlir;
|
|||
namespace {
|
||||
/// Loop invariant code motion (LICM) pass.
|
||||
struct LoopInvariantCodeMotion : public OperationPass<LoopInvariantCodeMotion> {
|
||||
public:
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_LoopInvariantCodeMotion
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
using namespace mlir;
|
||||
|
||||
namespace {
|
||||
|
||||
// The store to load forwarding relies on three conditions:
|
||||
//
|
||||
// 1) they need to have mathematically equivalent affine access functions
|
||||
|
@ -62,6 +61,10 @@ namespace {
|
|||
// than dealloc) remain.
|
||||
//
|
||||
struct MemRefDataFlowOpt : public FunctionPass<MemRefDataFlowOpt> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_MemRefDataFlowOpt
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
|
||||
void forwardStoreToLoad(AffineLoadOp loadOp);
|
||||
|
|
|
@ -19,6 +19,10 @@ using namespace mlir;
|
|||
|
||||
namespace {
|
||||
struct PrintOpStatsPass : public ModulePass<PrintOpStatsPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_PrintOpStats
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
explicit PrintOpStatsPass(raw_ostream &os = llvm::errs()) : os(os) {}
|
||||
|
||||
// Prints the resultant operation statistics post iterating over the module.
|
||||
|
|
|
@ -21,6 +21,10 @@ using namespace mlir;
|
|||
|
||||
namespace {
|
||||
struct ParallelLoopCollapsing : public OperationPass<ParallelLoopCollapsing> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_ParallelLoopCollapsing
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
ParallelLoopCollapsing() = default;
|
||||
ParallelLoopCollapsing(const ParallelLoopCollapsing &) {}
|
||||
void runOnOperation() override {
|
||||
|
@ -39,23 +43,6 @@ struct ParallelLoopCollapsing : public OperationPass<ParallelLoopCollapsing> {
|
|||
collapseParallelLoops(op, combinedLoops);
|
||||
});
|
||||
}
|
||||
|
||||
ListOption<unsigned> clCollapsedIndices0{
|
||||
*this, "collapsed-indices-0",
|
||||
llvm::cl::desc("Which loop indices to combine 0th loop index"),
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
|
||||
ListOption<unsigned> clCollapsedIndices1{
|
||||
*this, "collapsed-indices-1",
|
||||
llvm::cl::desc(
|
||||
"Which loop indices to combine into the position 1 loop index"),
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
|
||||
ListOption<unsigned> clCollapsedIndices2{
|
||||
*this, "collapsed-indices-2",
|
||||
llvm::cl::desc(
|
||||
"Which loop indices to combine into the position 2 loop index"),
|
||||
llvm::cl::MiscFlags::CommaSeparated};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
using namespace mlir;
|
||||
|
||||
namespace {
|
||||
|
||||
struct PipelineDataTransfer : public FunctionPass<PipelineDataTransfer> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_AffinePipelineDataTransfer
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnFunction() override;
|
||||
void runOnAffineForOp(AffineForOp forOp);
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@ using namespace mlir;
|
|||
|
||||
namespace {
|
||||
struct StripDebugInfo : public OperationPass<StripDebugInfo> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_StripDebugInfo
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
|
|
@ -18,6 +18,10 @@ using namespace mlir;
|
|||
|
||||
namespace {
|
||||
struct SymbolDCE : public OperationPass<SymbolDCE> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_SymbolDCE
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
void runOnOperation() override;
|
||||
|
||||
/// Compute the liveness of the symbols within the given symbol table.
|
||||
|
|
|
@ -101,6 +101,10 @@ namespace {
|
|||
// Note: this is a module pass only to avoid interleaving on the same ostream
|
||||
// due to multi-threading over functions.
|
||||
struct PrintOpPass : public ModulePass<PrintOpPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_PrintOpGraph
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
explicit PrintOpPass(raw_ostream &os = llvm::errs(), bool short_names = false,
|
||||
const Twine &title = "")
|
||||
: os(os), title(title.str()), short_names(short_names) {}
|
||||
|
|
|
@ -61,6 +61,10 @@ void mlir::Region::viewGraph() { viewGraph("region"); }
|
|||
|
||||
namespace {
|
||||
struct PrintCFGPass : public FunctionPass<PrintCFGPass> {
|
||||
/// Include the generated pass utilities.
|
||||
#define GEN_PASS_PrintCFG
|
||||
#include "mlir/Transforms/Passes.h.inc"
|
||||
|
||||
PrintCFGPass(raw_ostream &os = llvm::errs(), bool shortNames = false,
|
||||
const Twine &title = "")
|
||||
: os(os), shortNames(shortNames), title(title.str()) {}
|
||||
|
|
|
@ -21,6 +21,64 @@
|
|||
using namespace mlir;
|
||||
using namespace mlir::tblgen;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GEN: Pass base class generation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// The code snippet used to generate the start of a pass base class.
|
||||
///
|
||||
/// {0}: The def name of the pass record.
|
||||
/// {1}: The command line argument for the pass.
|
||||
const char *const passDeclBegin = R"(
|
||||
//===----------------------------------------------------------------------===//
|
||||
// {0}
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifdef GEN_PASS_{0}
|
||||
/// Returns the command-line argument attached to this pass.
|
||||
static StringRef getPassArgument() { return "{1}"; }
|
||||
)";
|
||||
|
||||
/// The code snippet used to generate the end of a pass base class.
|
||||
///
|
||||
/// {0}: The def name of the pass record.
|
||||
const char *const passDeclEnd = R"(
|
||||
#undef GEN_PASS_{0}
|
||||
#endif // GEN_PASS_{0}
|
||||
)";
|
||||
|
||||
/// Emit the declarations for each of the pass options.
|
||||
static void emitPassOptionDecls(const Pass &pass, raw_ostream &os) {
|
||||
for (const PassOption &opt : pass.getOptions()) {
|
||||
os.indent(2) << "Pass::" << (opt.isListOption() ? "ListOption" : "Option");
|
||||
|
||||
os << llvm::formatv("<{0}> {1}{{*this, \"{2}\", llvm::cl::desc(\"{3}\")",
|
||||
opt.getType(), opt.getCppVariableName(),
|
||||
opt.getArgument(), opt.getDescription());
|
||||
if (Optional<StringRef> defaultVal = opt.getDefaultValue())
|
||||
os << ", llvm::cl::init(" << defaultVal << ")";
|
||||
if (Optional<StringRef> additionalFlags = opt.getAdditionalFlags())
|
||||
os << ", " << *additionalFlags;
|
||||
os << "};\n";
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit the declarations for each of the pass statistics.
|
||||
static void emitPassStatisticDecls(const Pass &pass, raw_ostream &os) {
|
||||
for (const PassStatistic &stat : pass.getStatistics()) {
|
||||
os << llvm::formatv(" Pass::Statistic {0}{{this, \"{1}\", \"{2}\"};\n",
|
||||
stat.getCppVariableName(), stat.getName(),
|
||||
stat.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
static void emitPassDecl(const Pass &pass, raw_ostream &os) {
|
||||
StringRef defName = pass.getDef()->getName();
|
||||
os << llvm::formatv(passDeclBegin, defName, pass.getArgument());
|
||||
emitPassOptionDecls(pass, os);
|
||||
emitPassStatisticDecls(pass, os);
|
||||
os << llvm::formatv(passDeclEnd, defName);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GEN: Pass registration generation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -47,8 +105,11 @@ static void emitDecls(const llvm::RecordKeeper &recordKeeper, raw_ostream &os) {
|
|||
os << "/* Autogenerated by mlir-tblgen; don't manually edit */\n";
|
||||
|
||||
std::vector<Pass> passes;
|
||||
for (const llvm::Record *def : recordKeeper.getAllDerivedDefinitions("Pass"))
|
||||
passes.push_back(Pass(def));
|
||||
for (const auto *def : recordKeeper.getAllDerivedDefinitions("Pass")) {
|
||||
Pass pass(def);
|
||||
passes.push_back(pass);
|
||||
emitPassDecl(pass, os);
|
||||
}
|
||||
emitRegistration(passes, os);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue