This revision removes all of the CRTP from the pass hierarchy in preparation for using the tablegen backend instead. This creates a much cleaner interface in the C++ code, and naturally fits with the rest of the infrastructure. A new utility class, PassWrapper, is added to replicate the existing behavior for passes not suitable for using the tablegen backend.
Differential Revision: https://reviews.llvm.org/D77350
`mlir::FunctionPass` and overriding the `runOnFunction()` method.
```c++
-class ShapeInferencePass : public mlir::FunctionPass<ShapeInferencePass> {
+class ShapeInferencePass
+ : public mlir::PassWrapper<ShapeInferencePass, FunctionPass> {
void runOnFunction() override {
FuncOp function = getFunction();
...
/// d) infer the shape of its output from the argument types.
/// 3) If the worklist is empty, the algorithm succeeded.
///
-class ShapeInferencePass : public mlir::FunctionPass<ShapeInferencePass> {
+class ShapeInferencePass
+ : public mlir::PassWrapper<ShapeInferencePass, FunctionPass> {
public:
void runOnFunction() override {
auto f = getFunction();
/// computationally intensive (like matmul for example...) while keeping the
/// rest of the code in the Toy dialect.
namespace {
-struct ToyToAffineLoweringPass : public FunctionPass<ToyToAffineLoweringPass> {
+struct ToyToAffineLoweringPass
+ : public PassWrapper<ToyToAffineLoweringPass, FunctionPass> {
void runOnFunction() final;
};
} // end anonymous namespace.
/// d) infer the shape of its output from the argument types.
/// 3) If the worklist is empty, the algorithm succeeded.
///
-class ShapeInferencePass : public mlir::FunctionPass<ShapeInferencePass> {
+class ShapeInferencePass
+ : public mlir::PassWrapper<ShapeInferencePass, FunctionPass> {
public:
void runOnFunction() override {
auto f = getFunction();
/// computationally intensive (like matmul for example...) while keeping the
/// rest of the code in the Toy dialect.
namespace {
-struct ToyToAffineLoweringPass : public FunctionPass<ToyToAffineLoweringPass> {
+struct ToyToAffineLoweringPass
+ : public PassWrapper<ToyToAffineLoweringPass, FunctionPass> {
void runOnFunction() final;
};
} // end anonymous namespace.
namespace {
struct ToyToLLVMLoweringPass
- : public OperationPass<ToyToLLVMLoweringPass, ModuleOp> {
+ : public PassWrapper<ToyToLLVMLoweringPass, OperationPass<ModuleOp>> {
void runOnOperation() final;
};
} // end anonymous namespace
/// d) infer the shape of its output from the argument types.
/// 3) If the worklist is empty, the algorithm succeeded.
///
-class ShapeInferencePass : public mlir::FunctionPass<ShapeInferencePass> {
+class ShapeInferencePass
+ : public mlir::PassWrapper<ShapeInferencePass, FunctionPass> {
public:
void runOnFunction() override {
auto f = getFunction();
/// computationally intensive (like matmul for example...) while keeping the
/// rest of the code in the Toy dialect.
namespace {
-struct ToyToAffineLoweringPass : public FunctionPass<ToyToAffineLoweringPass> {
+struct ToyToAffineLoweringPass
+ : public PassWrapper<ToyToAffineLoweringPass, FunctionPass> {
void runOnFunction() final;
};
} // end anonymous namespace.
namespace {
struct ToyToLLVMLoweringPass
- : public OperationPass<ToyToLLVMLoweringPass, ModuleOp> {
+ : public PassWrapper<ToyToLLVMLoweringPass, OperationPass<ModuleOp>> {
void runOnOperation() final;
};
} // end anonymous namespace
/// d) infer the shape of its output from the argument types.
/// 3) If the worklist is empty, the algorithm succeeded.
///
-class ShapeInferencePass : public mlir::FunctionPass<ShapeInferencePass> {
+class ShapeInferencePass
+ : public mlir::PassWrapper<ShapeInferencePass, FunctionPass> {
public:
void runOnFunction() override {
auto f = getFunction();
namespace mlir {
class LLVMTypeConverter;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class OwningRewritePatternList;
/// Collect a set of patterns to convert from the AVX512 dialect to LLVM.
OwningRewritePatternList &patterns);
/// Create a pass to convert AVX512 operations to the LLVMIR dialect.
-std::unique_ptr<OpPassBase<ModuleOp>> createConvertAVX512ToLLVMPass();
+std::unique_ptr<OperationPass<ModuleOp>> createConvertAVX512ToLLVMPass();
} // namespace mlir
class Location;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
namespace gpu {
class GPUModuleOp;
/// attached as a string attribute named 'nvvm.cubin' to the kernel function.
/// After the transformation, the body of the kernel function is removed (i.e.,
/// it is turned into a declaration).
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>>
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
createConvertGPUKernelToCubinPass(CubinGenerator cubinGenerator);
/// Creates a pass to convert a gpu.launch_func operation into a sequence of
/// This pass does not generate code to call CUDA directly but instead uses a
/// small wrapper library that exports a stable and conveniently typed ABI
/// on top of CUDA.
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
createConvertGpuLaunchFuncToCudaCallsPass();
} // namespace mlir
class LLVMTypeConverter;
class OwningRewritePatternList;
-template <typename OpT> class OpPassBase;
+template <typename OpT> class OperationPass;
namespace gpu {
class GPUModuleOp;
OwningRewritePatternList &patterns);
/// Creates a pass that lowers GPU dialect operations to NVVM counterparts.
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>> createLowerGpuOpsToNVVMOpsPass();
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
+createLowerGpuOpsToNVVMOpsPass();
} // namespace mlir
namespace gpu {
class GPUModuleOp;
} // namespace gpu
-template <typename OpT> class OpPassBase;
+template <typename OpT> class OperationPass;
/// Creates a pass that lowers GPU dialect operations to ROCDL counterparts.
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>> createLowerGpuOpsToROCDLOpsPass();
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
+createLowerGpuOpsToROCDLOpsPass();
} // namespace mlir
namespace mlir {
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Pass to convert GPU Ops to SPIR-V ops. For a gpu.func to be converted, it
/// should have a spv.entry_point_abi attribute.
-std::unique_ptr<OpPassBase<ModuleOp>> createConvertGPUToSPIRVPass();
+std::unique_ptr<OperationPass<ModuleOp>> createConvertGPUToSPIRVPass();
} // namespace mlir
#endif // MLIR_CONVERSION_GPUTOSPIRV_CONVERTGPUTOSPIRVPASS_H
namespace mlir {
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
createConvertVulkanLaunchFuncToVulkanCallsPass();
-std::unique_ptr<OpPassBase<mlir::ModuleOp>>
+std::unique_ptr<OperationPass<mlir::ModuleOp>>
createConvertGpuLaunchFuncToVulkanLaunchFuncPass();
} // namespace mlir
namespace mlir {
class MLIRContext;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Populate the given list with patterns that convert from Linalg to LLVM.
void populateLinalgToLLVMConversionPatterns(LLVMTypeConverter &converter,
MLIRContext *ctx);
/// Create a pass to convert Linalg operations to the LLVMIR dialect.
-std::unique_ptr<OpPassBase<ModuleOp>> createConvertLinalgToLLVMPass();
+std::unique_ptr<OperationPass<ModuleOp>> createConvertLinalgToLLVMPass();
} // namespace mlir
namespace mlir {
/// Creates and returns a pass to convert Linalg ops to SPIR-V ops.
-std::unique_ptr<OpPassBase<ModuleOp>> createLinalgToSPIRVPass();
+std::unique_ptr<OperationPass<ModuleOp>> createLinalgToSPIRVPass();
} // namespace mlir
namespace mlir {
class FuncOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class Pass;
/// Create a pass that converts loop nests into GPU kernels. It considers
/// parallelization is performed, it is under the responsibility of the caller
/// to strip-mine the loops and to perform the dependence analysis before
/// calling the conversion.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createSimpleLoopsToGPUPass(unsigned numBlockDims, unsigned numThreadDims);
-std::unique_ptr<OpPassBase<FuncOp>> createSimpleLoopsToGPUPass();
+std::unique_ptr<OperationPass<FuncOp>> createSimpleLoopsToGPUPass();
/// Create a pass that converts every loop operation within the body of the
/// FuncOp into a GPU launch. The number of workgroups and workgroup size for
/// method. For testing, the values are set as constants obtained from a command
/// line flag. See convertLoopToGPULaunch for a description of the required
/// semantics of the converted loop operation.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLoopToGPUPass(ArrayRef<int64_t> numWorkGroups,
ArrayRef<int64_t> workGroupSize);
-std::unique_ptr<OpPassBase<FuncOp>> createLoopToGPUPass();
+std::unique_ptr<OperationPass<FuncOp>> createLoopToGPUPass();
/// Creates a pass that converts loop.parallel operations into a gpu.launch
/// operation. The mapping of loop dimensions to launch dimensions is derived
namespace mlir {
class LLVMTypeConverter;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class OwningRewritePatternList;
/// Collect a set of patterns to convert memory-related operations from the
/// Creates a pass to convert the Standard dialect into the LLVMIR dialect.
/// stdlib malloc/free is used for allocating memrefs allocated with std.alloc,
/// while LLVM's alloca is used for those allocated with std.alloca.
-std::unique_ptr<OpPassBase<ModuleOp>> createLowerToLLVMPass(
+std::unique_ptr<OperationPass<ModuleOp>> createLowerToLLVMPass(
const LowerToLLVMOptions &options = {
/*useBarePtrCallConv=*/false, /*emitCWrappers=*/false,
/*indexBitwidth=*/kDeriveIndexBitwidthFromDataLayout});
namespace mlir {
/// Pass to convert StandardOps to SPIR-V ops.
-std::unique_ptr<OpPassBase<ModuleOp>> createConvertStandardToSPIRVPass();
+std::unique_ptr<OperationPass<ModuleOp>> createConvertStandardToSPIRVPass();
/// Pass to legalize ops that are not directly lowered to SPIR-V.
std::unique_ptr<Pass> createLegalizeStdOpsForSPIRVLoweringPass();
namespace mlir {
class LLVMTypeConverter;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Collect a set of patterns to convert from Vector contractions to LLVM Matrix
/// Intrinsics. To lower to assembly, the LLVM flag -lower-matrix-intrinsics
OwningRewritePatternList &patterns);
/// Create a pass to convert vector operations to the LLVMIR dialect.
-std::unique_ptr<OpPassBase<ModuleOp>> createConvertVectorToLLVMPass();
+std::unique_ptr<OperationPass<ModuleOp>> createConvertVectorToLLVMPass();
} // namespace mlir
class FuncOp;
class ModuleOp;
class Pass;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Creates a simplification pass for affine structures (maps and sets). In
/// addition, this pass also normalizes memrefs to have the trivial (identity)
/// layout map.
-std::unique_ptr<OpPassBase<FuncOp>> createSimplifyAffineStructuresPass();
+std::unique_ptr<OperationPass<FuncOp>> createSimplifyAffineStructuresPass();
/// Creates a loop invariant code motion pass that hoists loop invariant
/// operations out of affine loops.
-std::unique_ptr<OpPassBase<FuncOp>> createAffineLoopInvariantCodeMotionPass();
+std::unique_ptr<OperationPass<FuncOp>>
+createAffineLoopInvariantCodeMotionPass();
/// Performs packing (or explicit copying) of accessed memref regions into
/// buffers in the specified faster memory space through either pointwise copies
/// or DMA operations.
-std::unique_ptr<OpPassBase<FuncOp>> createAffineDataCopyGenerationPass(
+std::unique_ptr<OperationPass<FuncOp>> createAffineDataCopyGenerationPass(
unsigned slowMemorySpace, unsigned fastMemorySpace,
unsigned tagMemorySpace = 0, int minDmaTransferSize = 1024,
uint64_t fastMemCapacityBytes = std::numeric_limits<uint64_t>::max());
/// Overload relying on pass options for initialization.
-std::unique_ptr<OpPassBase<FuncOp>> createAffineDataCopyGenerationPass();
+std::unique_ptr<OperationPass<FuncOp>> createAffineDataCopyGenerationPass();
/// Creates a pass to perform tiling on loop nests.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLoopTilingPass(uint64_t cacheSizeBytes);
/// Overload relying on pass options for initialization.
-std::unique_ptr<OpPassBase<FuncOp>> createLoopTilingPass();
+std::unique_ptr<OperationPass<FuncOp>> createLoopTilingPass();
/// Creates a loop unrolling pass with the provided parameters.
/// 'getUnrollFactor' is a function callback for clients to supply a function
/// factors supplied through other means. If -1 is passed as the unrollFactor
/// and no callback is provided, anything passed from the command-line (if at
/// all) or the default unroll factor is used (LoopUnroll:kDefaultUnrollFactor).
-std::unique_ptr<OpPassBase<FuncOp>> createLoopUnrollPass(
+std::unique_ptr<OperationPass<FuncOp>> createLoopUnrollPass(
int unrollFactor = -1, int unrollFull = -1,
const std::function<unsigned(AffineForOp)> &getUnrollFactor = nullptr);
/// Creates a loop unroll jam pass to unroll jam by the specified factor. A
/// factor of -1 lets the pass use the default factor or the one on the command
/// line if provided.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLoopUnrollAndJamPass(int unrollJamFactor = -1);
/// Creates a pass to vectorize loops, operations and data types using a
/// target-independent, n-D super-vector abstraction.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createSuperVectorizePass(ArrayRef<int64_t> virtualVectorSize);
/// Overload relying on pass options for initialization.
-std::unique_ptr<OpPassBase<FuncOp>> createSuperVectorizePass();
+std::unique_ptr<OperationPass<FuncOp>> createSuperVectorizePass();
} // end namespace mlir
class MLIRContext;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class OwningRewritePatternList;
-std::unique_ptr<OpPassBase<ModuleOp>> createGpuKernelOutliningPass();
+std::unique_ptr<OperationPass<ModuleOp>> createGpuKernelOutliningPass();
/// Collect a set of patterns to rewrite ops within the GPU dialect.
void populateGpuRewritePatterns(MLIRContext *context,
namespace mlir {
class FuncOp;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class Pass;
-std::unique_ptr<OpPassBase<FuncOp>> createLinalgFusionPass();
+std::unique_ptr<OperationPass<FuncOp>> createLinalgFusionPass();
std::unique_ptr<Pass> createLinalgFusionOfTensorOpsPass();
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLinalgTilingPass(ArrayRef<int64_t> tileSizes = {});
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLinalgTilingToParallelLoopsPass(ArrayRef<int64_t> tileSizes = {});
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLinalgPromotionPass(bool dynamicBuffers);
-std::unique_ptr<OpPassBase<FuncOp>> createLinalgPromotionPass();
+std::unique_ptr<OperationPass<FuncOp>> createLinalgPromotionPass();
/// Create a pass to convert Linalg operations to loop.for loops and
/// std.load/std.store accesses.
-std::unique_ptr<OpPassBase<FuncOp>> createConvertLinalgToLoopsPass();
+std::unique_ptr<OperationPass<FuncOp>> createConvertLinalgToLoopsPass();
/// Create a pass to convert Linalg operations to loop.parallel loops and
/// std.load/std.store accesses.
-std::unique_ptr<OpPassBase<FuncOp>> createConvertLinalgToParallelLoopsPass();
+std::unique_ptr<OperationPass<FuncOp>> createConvertLinalgToParallelLoopsPass();
/// Create a pass to convert Linalg operations to affine.for loops and
/// affine_load/affine_store accesses.
/// Placeholder for now, this is NYI.
-std::unique_ptr<OpPassBase<FuncOp>> createConvertLinalgToAffineLoopsPass();
+std::unique_ptr<OperationPass<FuncOp>> createConvertLinalgToAffineLoopsPass();
} // namespace mlir
namespace mlir {
class FuncOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
namespace quant {
/// Creates a pass that converts quantization simulation operations (i.e.
/// FakeQuant and those like it) to casts into/out of supported QuantizedTypes.
-std::unique_ptr<OpPassBase<FuncOp>> createConvertSimulatedQuantPass();
+std::unique_ptr<OperationPass<FuncOp>> createConvertSimulatedQuantPass();
/// Creates a pass that converts constants followed by a qbarrier to a
/// constant whose value is quantized. This is typically one of the last
/// passes done when lowering to express actual quantized arithmetic in a
/// low level representation. Because it modifies the constant, it is
/// destructive and cannot be undone.
-std::unique_ptr<OpPassBase<FuncOp>> createConvertConstPass();
+std::unique_ptr<OperationPass<FuncOp>> createConvertConstPass();
} // namespace quant
} // namespace mlir
/// StorageBuffer, PhysicalStorageBuffer, Uniform, and PushConstant storage
/// classes with layout information.
/// Right now this pass only supports Vulkan layout rules.
-std::unique_ptr<OpPassBase<mlir::ModuleOp>>
+std::unique_ptr<OperationPass<mlir::ModuleOp>>
createDecorateSPIRVCompositeTypeLayoutPass();
/// Creates an operation pass that deduces and attaches the minimal version/
/// to know which one to pick. `spv.target_env` gives the hard limit as for
/// what the target environment can support; this pass deduces what are
/// actually needed for a specific spv.module op.
-std::unique_ptr<OpPassBase<spirv::ModuleOp>>
+std::unique_ptr<OperationPass<spirv::ModuleOp>>
createUpdateVersionCapabilityExtensionPass();
/// Creates an operation pass that lowers the ABI attributes specified during
/// argument.
/// 2. Inserts the EntryPointOp and the ExecutionModeOp for entry point
/// functions using the specification in the `spv.entry_point_abi` attribute.
-std::unique_ptr<OpPassBase<spirv::ModuleOp>> createLowerABIAttributesPass();
+std::unique_ptr<OperationPass<spirv::ModuleOp>> createLowerABIAttributesPass();
} // namespace spirv
} // namespace mlir
virtual void runOnOperation() = 0;
/// A clone method to create a copy of this pass.
- virtual std::unique_ptr<Pass> clone() const = 0;
+ std::unique_ptr<Pass> clone() const {
+ auto newInst = clonePass();
+ newInst->copyOptionValuesFrom(this);
+ return newInst;
+ }
/// Return the current operation being transformed.
Operation *getOperation() {
return getPassState().irAndPassFailed.getPointer();
}
- /// Returns the current analysis manager.
- AnalysisManager getAnalysisManager() {
- return getPassState().analysisManager;
- }
-
- /// Copy the option values from 'other', which is another instance of this
- /// pass.
- void copyOptionValuesFrom(const Pass *other);
-
-private:
- /// Forwarding function to execute this pass on the given operation.
- LLVM_NODISCARD
- LogicalResult run(Operation *op, AnalysisManager am);
-
- /// Out of line virtual method to ensure vtables and metadata are emitted to a
- /// single .o file.
- virtual void anchor();
-
- /// Represents a unique identifier for the pass.
- const PassID *passID;
-
- /// The name of the operation that this pass operates on, or None if this is a
- /// generic OperationPass.
- Optional<StringRef> opName;
-
- /// The current execution state for the pass.
- Optional<detail::PassExecutionState> passState;
-
- /// The set of statistics held by this pass.
- std::vector<Statistic *> statistics;
-
- /// The pass options registered to this pass instance.
- detail::PassOptions passOptions;
-
- /// Allow access to 'clone' and 'run'.
- friend class OpPassManager;
-
- /// Allow access to 'passOptions'.
- friend class PassInfo;
-};
-
-//===----------------------------------------------------------------------===//
-// Pass Model Definitions
-//===----------------------------------------------------------------------===//
-namespace detail {
-/// The opaque CRTP model of a pass. This class provides utilities for derived
-/// pass execution and handles all of the necessary polymorphic API.
-template <typename PassT, typename BasePassT>
-class PassModel : public BasePassT {
-public:
- /// Support isa/dyn_cast functionality for the derived pass class.
- static bool classof(const Pass *pass) {
- return pass->getPassID() == PassID::getID<PassT>();
- }
-
-protected:
- explicit PassModel(Optional<StringRef> opName = llvm::None)
- : BasePassT(PassID::getID<PassT>(), opName) {}
-
/// Signal that some invariant was broken when running. The IR is allowed to
/// be in an invalid state.
- void signalPassFailure() {
- this->getPassState().irAndPassFailed.setInt(true);
- }
+ void signalPassFailure() { getPassState().irAndPassFailed.setInt(true); }
/// Query an analysis for the current ir unit.
template <typename AnalysisT> AnalysisT &getAnalysis() {
- return this->getAnalysisManager().template getAnalysis<AnalysisT>();
+ return getAnalysisManager().getAnalysis<AnalysisT>();
}
/// Query a cached instance of an analysis for the current ir unit if one
/// exists.
template <typename AnalysisT>
Optional<std::reference_wrapper<AnalysisT>> getCachedAnalysis() {
- return this->getAnalysisManager().template getCachedAnalysis<AnalysisT>();
+ return getAnalysisManager().getCachedAnalysis<AnalysisT>();
}
/// Mark all analyses as preserved.
void markAllAnalysesPreserved() {
- this->getPassState().preservedAnalyses.preserveAll();
+ getPassState().preservedAnalyses.preserveAll();
}
/// Mark the provided analyses as preserved.
template <typename... AnalysesT> void markAnalysesPreserved() {
- this->getPassState().preservedAnalyses.template preserve<AnalysesT...>();
+ getPassState().preservedAnalyses.preserve<AnalysesT...>();
}
void markAnalysesPreserved(const AnalysisID *id) {
- this->getPassState().preservedAnalyses.preserve(id);
- }
-
- /// Returns the derived pass name.
- StringRef getName() override {
- StringRef name = llvm::getTypeName<PassT>();
- if (!name.consume_front("mlir::"))
- name.consume_front("(anonymous namespace)::");
- return name;
- }
-
- /// A clone method to create a copy of this pass.
- std::unique_ptr<Pass> clone() const override {
- auto newInst = std::make_unique<PassT>(*static_cast<const PassT *>(this));
- newInst->copyOptionValuesFrom(this);
- return newInst;
+ getPassState().preservedAnalyses.preserve(id);
}
/// Returns the analysis for the parent operation if it exists.
template <typename AnalysisT>
Optional<std::reference_wrapper<AnalysisT>>
getCachedParentAnalysis(Operation *parent) {
- return this->getAnalysisManager()
- .template getCachedParentAnalysis<AnalysisT>(parent);
+ return getAnalysisManager().getCachedParentAnalysis<AnalysisT>(parent);
}
template <typename AnalysisT>
Optional<std::reference_wrapper<AnalysisT>> getCachedParentAnalysis() {
- return this->getAnalysisManager()
- .template getCachedParentAnalysis<AnalysisT>(
- this->getOperation()->getParentOp());
+ return getAnalysisManager().getCachedParentAnalysis<AnalysisT>(
+ getOperation()->getParentOp());
}
/// Returns the analysis for the given child operation if it exists.
template <typename AnalysisT>
Optional<std::reference_wrapper<AnalysisT>>
getCachedChildAnalysis(Operation *child) {
- return this->getAnalysisManager()
- .template getCachedChildAnalysis<AnalysisT>(child);
+ return getAnalysisManager().getCachedChildAnalysis<AnalysisT>(child);
}
/// Returns the analysis for the given child operation, or creates it if it
/// doesn't exist.
template <typename AnalysisT> AnalysisT &getChildAnalysis(Operation *child) {
- return this->getAnalysisManager().template getChildAnalysis<AnalysisT>(
- child);
+ return getAnalysisManager().getChildAnalysis<AnalysisT>(child);
}
-};
-} // end namespace detail
-/// Utility base class for OpPass below to denote an opaque pass operating on a
-/// specific operation type.
-template <typename OpT> class OpPassBase : public Pass {
-public:
- using Pass::Pass;
-
- /// Support isa/dyn_cast functionality.
- static bool classof(const Pass *pass) {
- return pass->getOpName() == OpT::getOperationName();
+ /// Returns the current analysis manager.
+ AnalysisManager getAnalysisManager() {
+ return getPassState().analysisManager;
}
+
+ /// Create a copy of this pass, ignoring statistics and options.
+ virtual std::unique_ptr<Pass> clonePass() const = 0;
+
+ /// Copy the option values from 'other', which is another instance of this
+ /// pass.
+ void copyOptionValuesFrom(const Pass *other);
+
+private:
+ /// Forwarding function to execute this pass on the given operation.
+ LLVM_NODISCARD
+ LogicalResult run(Operation *op, AnalysisManager am);
+
+ /// Out of line virtual method to ensure vtables and metadata are emitted to a
+ /// single .o file.
+ virtual void anchor();
+
+ /// Represents a unique identifier for the pass.
+ const PassID *passID;
+
+ /// The name of the operation that this pass operates on, or None if this is a
+ /// generic OperationPass.
+ Optional<StringRef> opName;
+
+ /// The current execution state for the pass.
+ Optional<detail::PassExecutionState> passState;
+
+ /// The set of statistics held by this pass.
+ std::vector<Statistic *> statistics;
+
+ /// The pass options registered to this pass instance.
+ detail::PassOptions passOptions;
+
+ /// Allow access to 'clone' and 'run'.
+ friend class OpPassManager;
+
+ /// Allow access to 'passOptions'.
+ friend class PassInfo;
};
+//===----------------------------------------------------------------------===//
+// Pass Model Definitions
+//===----------------------------------------------------------------------===//
+
/// Pass to transform an operation of a specific type.
///
/// Operation passes must not:
///
/// Derived function passes are expected to provide the following:
/// - A 'void runOnOperation()' method.
-template <typename PassT, typename OpT = void>
-class OperationPass : public detail::PassModel<PassT, OpPassBase<OpT>> {
+/// - A 'StringRef getName() const' method.
+/// - A 'std::unique_ptr<Pass> clonePass() const' method.
+template <typename OpT = void> class OperationPass : public Pass {
protected:
- OperationPass()
- : detail::PassModel<PassT, OpPassBase<OpT>>(OpT::getOperationName()) {}
+ OperationPass(const PassID *passID) : Pass(passID, OpT::getOperationName()) {}
+
+ /// Support isa/dyn_cast functionality.
+ static bool classof(const Pass *pass) {
+ return pass->getOpName() == OpT::getOperationName();
+ }
/// Return the current operation being transformed.
OpT getOperation() { return cast<OpT>(Pass::getOperation()); }
///
/// Derived function passes are expected to provide the following:
/// - A 'void runOnOperation()' method.
-template <typename PassT>
-struct OperationPass<PassT, void> : public detail::PassModel<PassT, Pass> {};
+/// - A 'StringRef getName() const' method.
+/// - A 'std::unique_ptr<Pass> clonePass() const' method.
+template <> class OperationPass<void> : public Pass {
+protected:
+ OperationPass(const PassID *passID) : Pass(passID) {}
+};
/// A model for providing function pass specific utilities.
///
/// Derived function passes are expected to provide the following:
/// - A 'void runOnFunction()' method.
-template <typename T> struct FunctionPass : public OperationPass<T, FuncOp> {
+/// - A 'StringRef getName() const' method.
+/// - A 'std::unique_ptr<Pass> clonePass() const' method.
+class FunctionPass : public OperationPass<FuncOp> {
+public:
+ using OperationPass<FuncOp>::OperationPass;
+
/// The polymorphic API that runs the pass over the currently held function.
virtual void runOnFunction() = 0;
/// Return the current function being transformed.
FuncOp getFunction() { return this->getOperation(); }
};
+
+/// This class provides a CRTP wrapper around a base pass class to define
+/// several necessary utility methods. This should only be used for passes that
+/// are not suitably represented using the declarative pass specification(i.e.
+/// tablegen backend).
+template <typename PassT, typename BaseT> class PassWrapper : public BaseT {
+public:
+ /// Support isa/dyn_cast functionality for the derived pass class.
+ static bool classof(const Pass *pass) {
+ return pass->getPassID() == PassID::getID<PassT>();
+ }
+
+protected:
+ PassWrapper() : BaseT(PassID::getID<PassT>()) {}
+
+ /// Returns the derived pass name.
+ StringRef getName() override {
+ StringRef name = llvm::getTypeName<PassT>();
+ if (!name.consume_front("mlir::"))
+ name.consume_front("(anonymous namespace)::");
+ return name;
+ }
+
+ /// A clone method to create a copy of this pass.
+ std::unique_ptr<Pass> clonePass() const override {
+ return std::make_unique<PassT>(*static_cast<const PassT *>(this));
+ }
+};
+
} // end namespace mlir
#endif // MLIR_PASS_PASS_H
class FuncOp;
class ModuleOp;
class Pass;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Creates an instance of the Canonicalizer pass.
std::unique_ptr<Pass> createCanonicalizerPass();
/// Creates a loop fusion pass which fuses loops. Buffers of size less than or
/// equal to `localBufSizeThreshold` are promoted to memory space
/// `fastMemorySpace'.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
createLoopFusionPass(unsigned fastMemorySpace = 0,
uint64_t localBufSizeThreshold = 0,
bool maximalFusion = false);
/// Creates a pass to pipeline explicit movement of data across levels of the
/// memory hierarchy.
-std::unique_ptr<OpPassBase<FuncOp>> createPipelineDataTransferPass();
+std::unique_ptr<OperationPass<FuncOp>> createPipelineDataTransferPass();
/// Lowers affine control flow operations (ForStmt, IfStmt and AffineApplyOp)
/// to equivalent lower-level constructs (flow of basic blocks and arithmetic
/// primitives).
-std::unique_ptr<OpPassBase<FuncOp>> createLowerAffinePass();
+std::unique_ptr<OperationPass<FuncOp>> createLowerAffinePass();
/// Creates a pass that transforms perfectly nested loops with independent
/// bounds into a single loop.
-std::unique_ptr<OpPassBase<FuncOp>> createLoopCoalescingPass();
+std::unique_ptr<OperationPass<FuncOp>> createLoopCoalescingPass();
/// Creates a pass that transforms a single ParallelLoop over N induction
/// variables into another ParallelLoop over less than N induction variables.
/// Creates a pass to perform optimizations relying on memref dataflow such as
/// store to load forwarding, elimination of dead stores, and dead allocs.
-std::unique_ptr<OpPassBase<FuncOp>> createMemRefDataFlowOptPass();
+std::unique_ptr<OperationPass<FuncOp>> createMemRefDataFlowOptPass();
/// Creates a pass to strip debug information from a function.
std::unique_ptr<Pass> createStripDebugInfoPass();
/// Creates a pass which prints the list of ops and the number of occurrences in
/// the module.
-std::unique_ptr<OpPassBase<ModuleOp>> createPrintOpStatsPass();
+std::unique_ptr<OperationPass<ModuleOp>> createPrintOpStatsPass();
/// Creates a pass which inlines calls and callable operations as defined by
/// the CallGraph.
namespace mlir {
class Block;
class ModuleOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
/// Displays the graph in a window. This is for use from the debugger and
/// depends on Graphviz to generate the graph.
const Twine &title = "");
/// Creates a pass to print op graphs.
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
createPrintOpGraphPass(raw_ostream &os = llvm::errs(), bool shortNames = false,
const Twine &title = "");
namespace mlir {
class FuncOp;
-template <typename T> class OpPassBase;
+template <typename T> class OperationPass;
class Region;
/// Displays the CFG in a window. This is for use from the debugger and
bool shortNames = false, const Twine &title = "");
/// Creates a pass to print CFG graphs.
-std::unique_ptr<mlir::OpPassBase<mlir::FuncOp>>
+std::unique_ptr<mlir::OperationPass<mlir::FuncOp>>
createPrintCFGGraphPass(raw_ostream &os = llvm::errs(), bool shortNames = false,
const Twine &title = "");
namespace {
struct ConvertAVX512ToLLVMPass
- : public OperationPass<ConvertAVX512ToLLVMPass, ModuleOp> {
+ : public PassWrapper<ConvertAVX512ToLLVMPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertAVX512ToLLVM
#include "mlir/Conversion/Passes.h.inc"
}
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createConvertAVX512ToLLVMPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertAVX512ToLLVMPass() {
return std::make_unique<ConvertAVX512ToLLVMPass>();
}
}
namespace {
-class LowerAffinePass : public FunctionPass<LowerAffinePass> {
+class LowerAffinePass : public PassWrapper<LowerAffinePass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertAffineToStandard
#include "mlir/Conversion/Passes.h.inc"
/// Lowers If and For operations within a function into their lower level CFG
/// equivalent blocks.
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLowerAffinePass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLowerAffinePass() {
return std::make_unique<LowerAffinePass>();
}
/// GPU binary code, which is then attached as an attribute to the function. The
/// function body is erased.
class GpuKernelToCubinPass
- : public OperationPass<GpuKernelToCubinPass, gpu::GPUModuleOp> {
+ : public PassWrapper<GpuKernelToCubinPass,
+ OperationPass<gpu::GPUModuleOp>> {
public:
GpuKernelToCubinPass(CubinGenerator cubinGenerator)
: cubinGenerator(cubinGenerator) {}
return StringAttr::get({cubin->data(), cubin->size()}, loc->getContext());
}
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>>
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
mlir::createConvertGPUKernelToCubinPass(CubinGenerator cubinGenerator) {
return std::make_unique<GpuKernelToCubinPass>(cubinGenerator);
}
///
/// Intermediate data structures are allocated on the stack.
class GpuLaunchFuncToCudaCallsPass
- : public OperationPass<GpuLaunchFuncToCudaCallsPass, ModuleOp> {
+ : public PassWrapper<GpuLaunchFuncToCudaCallsPass,
+ OperationPass<ModuleOp>> {
private:
/// Include the generated pass utilities.
#define GEN_PASS_ConvertGpuLaunchFuncToCudaCalls
launchOp.erase();
}
-std::unique_ptr<mlir::OpPassBase<mlir::ModuleOp>>
+std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
mlir::createConvertGpuLaunchFuncToCudaCallsPass() {
return std::make_unique<GpuLaunchFuncToCudaCallsPass>();
}
/// This pass only handles device code and is not meant to be run on GPU host
/// code.
class LowerGpuOpsToNVVMOpsPass
- : public OperationPass<LowerGpuOpsToNVVMOpsPass, gpu::GPUModuleOp> {
+ : public PassWrapper<LowerGpuOpsToNVVMOpsPass,
+ OperationPass<gpu::GPUModuleOp>> {
public:
/// Include the generated pass utilities.
#define GEN_PASS_ConvertGpuOpsToNVVMOps
"__nv_tanh");
}
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>>
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
mlir::createLowerGpuOpsToNVVMOpsPass() {
return std::make_unique<LowerGpuOpsToNVVMOpsPass>();
}
// This pass only handles device code and is not meant to be run on GPU host
// code.
class LowerGpuOpsToROCDLOpsPass
- : public OperationPass<LowerGpuOpsToROCDLOpsPass, gpu::GPUModuleOp> {
+ : public PassWrapper<LowerGpuOpsToROCDLOpsPass,
+ OperationPass<gpu::GPUModuleOp>> {
public:
/// Include the generated pass utilities.
#define GEN_PASS_ConvertGpuOpsToROCDLOps
} // anonymous namespace
-std::unique_ptr<OpPassBase<gpu::GPUModuleOp>>
+std::unique_ptr<OperationPass<gpu::GPUModuleOp>>
mlir::createLowerGpuOpsToROCDLOpsPass() {
return std::make_unique<LowerGpuOpsToROCDLOpsPass>();
}
-
/// replace it).
///
/// 2) Lower the body of the spirv::ModuleOp.
-struct GPUToSPIRVPass : public OperationPass<GPUToSPIRVPass, ModuleOp> {
+struct GPUToSPIRVPass
+ : public PassWrapper<GPUToSPIRVPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertGpuToSPIRV
#include "mlir/Conversion/Passes.h.inc"
}
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createConvertGPUToSPIRVPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertGPUToSPIRVPass() {
return std::make_unique<GPUToSPIRVPass>();
}
/// function and attaching binary data and entry point name as an attributes to
/// created vulkan launch call op.
class ConvertGpuLaunchFuncToVulkanLaunchFunc
- : public OperationPass<ConvertGpuLaunchFuncToVulkanLaunchFunc, ModuleOp> {
+ : public PassWrapper<ConvertGpuLaunchFuncToVulkanLaunchFunc,
+ OperationPass<ModuleOp>> {
public:
/// Include the generated pass utilities.
#define GEN_PASS_ConvertGpuLaunchFuncToVulkanLaunchFunc
launchOp.erase();
}
-std::unique_ptr<mlir::OpPassBase<mlir::ModuleOp>>
+std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
mlir::createConvertGpuLaunchFuncToVulkanLaunchFuncPass() {
return std::make_unique<ConvertGpuLaunchFuncToVulkanLaunchFunc>();
}
/// * deinitVulkan -- deinitializes vulkan runtime
///
class VulkanLaunchFuncToVulkanCallsPass
- : public OperationPass<VulkanLaunchFuncToVulkanCallsPass, ModuleOp> {
+ : public PassWrapper<VulkanLaunchFuncToVulkanCallsPass,
+ OperationPass<ModuleOp>> {
private:
/// Include the generated pass utilities.
#define GEN_PASS_ConvertVulkanLaunchFuncToVulkanCalls
cInterfaceVulkanLaunchCallOp.erase();
}
-std::unique_ptr<mlir::OpPassBase<mlir::ModuleOp>>
+std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
mlir::createConvertVulkanLaunchFuncToVulkanCallsPass() {
return std::make_unique<VulkanLaunchFuncToVulkanCallsPass>();
}
namespace {
struct ConvertLinalgToLLVMPass
- : public OperationPass<ConvertLinalgToLLVMPass, ModuleOp> {
+ : public PassWrapper<ConvertLinalgToLLVMPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertLinalgToLLVM
#include "mlir/Conversion/Passes.h.inc"
signalPassFailure();
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createConvertLinalgToLLVMPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertLinalgToLLVMPass() {
return std::make_unique<ConvertLinalgToLLVMPass>();
}
namespace {
/// A pass converting MLIR Linalg ops into SPIR-V ops.
-class LinalgToSPIRVPass : public OperationPass<LinalgToSPIRVPass, ModuleOp> {
+class LinalgToSPIRVPass
+ : public PassWrapper<LinalgToSPIRVPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertLinalgToSPIRV
#include "mlir/Conversion/Passes.h.inc"
return signalPassFailure();
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createLinalgToSPIRVPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createLinalgToSPIRVPass() {
return std::make_unique<LinalgToSPIRVPass>();
}
namespace {
-struct LoopToStandardPass : public OperationPass<LoopToStandardPass> {
+struct LoopToStandardPass
+ : public PassWrapper<LoopToStandardPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertLoopToStandard
#include "mlir/Conversion/Passes.h.inc"
// A pass that traverses top-level loops in the function and converts them to
// 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> {
+struct ForLoopMapper : public PassWrapper<ForLoopMapper, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertSimpleLoopsToGPU
#include "mlir/Conversion/Passes.h.inc"
// nested loops as the size of `numWorkGroups`. Within these any loop nest has
// to be perfectly nested upto depth equal to size of `workGroupSize`.
struct ImperfectlyNestedForLoopMapper
- : public FunctionPass<ImperfectlyNestedForLoopMapper> {
+ : public PassWrapper<ImperfectlyNestedForLoopMapper, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertLoopsToGPU
#include "mlir/Conversion/Passes.h.inc"
}
};
-struct ParallelLoopToGpuPass : public OperationPass<ParallelLoopToGpuPass> {
+struct ParallelLoopToGpuPass
+ : public PassWrapper<ParallelLoopToGpuPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertParallelLoopToGpu
#include "mlir/Conversion/Passes.h.inc"
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createSimpleLoopsToGPUPass(unsigned numBlockDims,
unsigned numThreadDims) {
return std::make_unique<ForLoopMapper>(numBlockDims, numThreadDims);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createSimpleLoopsToGPUPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createSimpleLoopsToGPUPass() {
return std::make_unique<ForLoopMapper>();
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLoopToGPUPass(ArrayRef<int64_t> numWorkGroups,
ArrayRef<int64_t> workGroupSize) {
return std::make_unique<ImperfectlyNestedForLoopMapper>(numWorkGroups,
workGroupSize);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLoopToGPUPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLoopToGPUPass() {
return std::make_unique<ImperfectlyNestedForLoopMapper>();
}
namespace {
/// A pass converting MLIR operations into the LLVM IR dialect.
-struct LLVMLoweringPass : public OperationPass<LLVMLoweringPass, ModuleOp> {
+struct LLVMLoweringPass
+ : public PassWrapper<LLVMLoweringPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertStandardToLLVM
#include "mlir/Conversion/Passes.h.inc"
this->addIllegalOp<TanhOp>();
}
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
mlir::createLowerToLLVMPass(const LowerToLLVMOptions &options) {
return std::make_unique<LLVMLoweringPass>(
options.useBarePtrCallConv, options.emitCWrappers, options.indexBitwidth);
namespace {
/// A pass converting MLIR Standard operations into the SPIR-V dialect.
class ConvertStandardToSPIRVPass
- : public OperationPass<ConvertStandardToSPIRVPass, ModuleOp> {
+ : public PassWrapper<ConvertStandardToSPIRVPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertStandardToSPIRV
#include "mlir/Conversion/Passes.h.inc"
}
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createConvertStandardToSPIRVPass() {
+std::unique_ptr<OperationPass<ModuleOp>>
+mlir::createConvertStandardToSPIRVPass() {
return std::make_unique<ConvertStandardToSPIRVPass>();
}
//===----------------------------------------------------------------------===//
namespace {
-struct SPIRVLegalization final : public OperationPass<SPIRVLegalization> {
+struct SPIRVLegalization final
+ : public PassWrapper<SPIRVLegalization, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LegalizeStandardForSPIRV
#include "mlir/Conversion/Passes.h.inc"
namespace {
struct LowerVectorToLLVMPass
- : public OperationPass<LowerVectorToLLVMPass, ModuleOp> {
+ : public PassWrapper<LowerVectorToLLVMPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_ConvertVectorToLLVM
#include "mlir/Conversion/Passes.h.inc"
}
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createConvertVectorToLLVMPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertVectorToLLVMPass() {
return std::make_unique<LowerVectorToLLVMPass>();
}
// TODO(bondhugula): We currently can't generate copies correctly when stores
// are strided. Check for strided stores.
struct AffineDataCopyGeneration
- : public FunctionPass<AffineDataCopyGeneration> {
+ : public PassWrapper<AffineDataCopyGeneration, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineDataCopyGeneration
#include "mlir/Dialect/Affine/Passes.h.inc"
/// buffers in 'fastMemorySpace', and replaces memory operations to the former
/// by the latter. Only load op's handled for now.
/// TODO(bondhugula): extend this to store op's.
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createAffineDataCopyGenerationPass(
+std::unique_ptr<OperationPass<FuncOp>> mlir::createAffineDataCopyGenerationPass(
unsigned slowMemorySpace, unsigned fastMemorySpace, unsigned tagMemorySpace,
int minDmaTransferSize, uint64_t fastMemCapacityBytes) {
return std::make_unique<AffineDataCopyGeneration>(
slowMemorySpace, fastMemorySpace, tagMemorySpace, minDmaTransferSize,
fastMemCapacityBytes);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createAffineDataCopyGenerationPass() {
+std::unique_ptr<OperationPass<FuncOp>>
+mlir::createAffineDataCopyGenerationPass() {
return std::make_unique<AffineDataCopyGeneration>();
}
/// TODO(asabne) : Check for the presence of side effects before hoisting.
/// TODO: This code should be removed once the new LICM pass can handle its
/// uses.
-struct LoopInvariantCodeMotion : public FunctionPass<LoopInvariantCodeMotion> {
+struct LoopInvariantCodeMotion
+ : public PassWrapper<LoopInvariantCodeMotion, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineLoopInvariantCodeMotion
#include "mlir/Dialect/Affine/Passes.h.inc"
});
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createAffineLoopInvariantCodeMotionPass() {
return std::make_unique<LoopInvariantCodeMotion>();
}
namespace {
/// A pass to perform loop tiling on all suitable loop nests of a Function.
-struct LoopTiling : public FunctionPass<LoopTiling> {
+struct LoopTiling : public PassWrapper<LoopTiling, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineLoopTiling
#include "mlir/Dialect/Affine/Passes.h.inc"
/// Creates a pass to perform loop tiling on all suitable loop nests of a
/// Function.
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLoopTilingPass(uint64_t cacheSizeBytes) {
return std::make_unique<LoopTiling>(cacheSizeBytes);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLoopTilingPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLoopTilingPass() {
return std::make_unique<LoopTiling>();
}
/// full unroll threshold was specified, in which case, fully unrolls all loops
/// 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> {
+struct LoopUnroll : public PassWrapper<LoopUnroll, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineUnroll
#include "mlir/Dialect/Affine/Passes.h.inc"
return loopUnrollByFactor(forOp, kDefaultUnrollFactor);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLoopUnrollPass(
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLoopUnrollPass(
int unrollFactor, int unrollFull,
const std::function<unsigned(AffineForOp)> &getUnrollFactor) {
return std::make_unique<LoopUnroll>(
namespace {
/// Loop unroll jam pass. Currently, this just unroll jams the first
/// outer loop in a Function.
-struct LoopUnrollAndJam : public FunctionPass<LoopUnrollAndJam> {
+struct LoopUnrollAndJam : public PassWrapper<LoopUnrollAndJam, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineLoopUnrollAndJam
#include "mlir/Dialect/Affine/Passes.h.inc"
};
} // end anonymous namespace
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLoopUnrollAndJamPass(int unrollJamFactor) {
return std::make_unique<LoopUnrollAndJam>(
unrollJamFactor == -1 ? None : Optional<unsigned>(unrollJamFactor));
/// all memrefs with non-trivial layout maps are converted to ones with trivial
/// identity layout ones.
struct SimplifyAffineStructures
- : public FunctionPass<SimplifyAffineStructures> {
+ : public PassWrapper<SimplifyAffineStructures, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_SimplifyAffineStructures
#include "mlir/Dialect/Affine/Passes.h.inc"
} // end anonymous namespace
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createSimplifyAffineStructuresPass() {
+std::unique_ptr<OperationPass<FuncOp>>
+mlir::createSimplifyAffineStructuresPass() {
return std::make_unique<SimplifyAffineStructures>();
}
/// Base state for the vectorize pass.
/// Command line arguments are preempted by non-empty pass arguments.
-struct Vectorize : public FunctionPass<Vectorize> {
+struct Vectorize : public PassWrapper<Vectorize, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineVectorize
#include "mlir/Dialect/Affine/Passes.h.inc"
LLVM_DEBUG(dbgs() << "\n");
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createSuperVectorizePass(ArrayRef<int64_t> virtualVectorSize) {
return std::make_unique<Vectorize>(virtualVectorSize);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createSuperVectorizePass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createSuperVectorizePass() {
return std::make_unique<Vectorize>();
}
/// a separate pass. The external functions can then be annotated with the
/// symbol of the cubin accessor function.
class GpuKernelOutliningPass
- : public OperationPass<GpuKernelOutliningPass, ModuleOp> {
+ : public PassWrapper<GpuKernelOutliningPass, OperationPass<ModuleOp>> {
public:
/// Include the generated pass utilities.
#define GEN_PASS_GpuKernelOutlining
} // namespace
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createGpuKernelOutliningPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createGpuKernelOutliningPass() {
return std::make_unique<GpuKernelOutliningPass>();
}
}
namespace {
-struct LegalizeForExportPass : public OperationPass<LegalizeForExportPass> {
+struct LegalizeForExportPass
+ : public PassWrapper<LegalizeForExportPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LLVMLegalizeForExport
#include "mlir/Dialect/LLVMIR/Transforms/Passes.h.inc"
};
/// Pass that fuses generic ops on tensors. Used only for testing.
-struct FusionOfTensorOpsPass : public OperationPass<FusionOfTensorOpsPass> {
+struct FusionOfTensorOpsPass
+ : public PassWrapper<FusionOfTensorOpsPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgFusionOfTensorOps
#include "mlir/Dialect/Linalg/Passes.h.inc"
};
};
-struct LinalgFusionPass : public FunctionPass<LinalgFusionPass> {
+struct LinalgFusionPass : public PassWrapper<LinalgFusionPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgFusion
#include "mlir/Dialect/Linalg/Passes.h.inc"
};
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLinalgFusionPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLinalgFusionPass() {
return std::make_unique<LinalgFusionPass>();
}
}
namespace {
-struct LowerToAffineLoops : public FunctionPass<LowerToAffineLoops> {
+struct LowerToAffineLoops
+ : public PassWrapper<LowerToAffineLoops, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgLowerToAffineLoops
#include "mlir/Dialect/Linalg/Passes.h.inc"
&getContext());
}
};
-struct LowerToLoops : public FunctionPass<LowerToLoops> {
+struct LowerToLoops : public PassWrapper<LowerToLoops, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgLowerToLoops
#include "mlir/Dialect/Linalg/Passes.h.inc"
&getContext());
}
};
-struct LowerToParallelLoops : public FunctionPass<LowerToParallelLoops> {
+struct LowerToParallelLoops
+ : public PassWrapper<LowerToParallelLoops, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgLowerToParallelLoops
#include "mlir/Dialect/Linalg/Passes.h.inc"
};
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createConvertLinalgToLoopsPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createConvertLinalgToLoopsPass() {
return std::make_unique<LowerToLoops>();
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createConvertLinalgToParallelLoopsPass() {
return std::make_unique<LowerToParallelLoops>();
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createConvertLinalgToAffineLoopsPass() {
return std::make_unique<LowerToAffineLoops>();
}
}
namespace {
-struct LinalgPromotionPass : public FunctionPass<LinalgPromotionPass> {
+struct LinalgPromotionPass
+ : public PassWrapper<LinalgPromotionPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgPromotion
#include "mlir/Dialect/Linalg/Passes.h.inc"
};
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLinalgPromotionPass(bool dynamicBuffers) {
return std::make_unique<LinalgPromotionPass>(dynamicBuffers);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLinalgPromotionPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLinalgPromotionPass() {
return std::make_unique<LinalgPromotionPass>();
}
}
namespace {
-struct LinalgTilingPass : public FunctionPass<LinalgTilingPass> {
+struct LinalgTilingPass : public PassWrapper<LinalgTilingPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgTiling
#include "mlir/Dialect/Linalg/Passes.h.inc"
};
struct LinalgTilingToParallelLoopsPass
- : public FunctionPass<LinalgTilingToParallelLoopsPass> {
+ : public PassWrapper<LinalgTilingToParallelLoopsPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LinalgTilingToParallelLoops
#include "mlir/Dialect/Linalg/Passes.h.inc"
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLinalgTilingPass(ArrayRef<int64_t> tileSizes) {
return std::make_unique<LinalgTilingPass>(tileSizes);
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLinalgTilingToParallelLoopsPass(ArrayRef<int64_t> tileSizes) {
return std::make_unique<LinalgTilingToParallelLoopsPass>(tileSizes);
}
}
namespace {
-struct ParallelLoopFusion : public OperationPass<ParallelLoopFusion> {
+struct ParallelLoopFusion
+ : public PassWrapper<ParallelLoopFusion, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LoopParallelLoopFusion
#include "mlir/Dialect/LoopOps/Passes.h.inc"
namespace {
struct ParallelLoopSpecialization
- : public FunctionPass<ParallelLoopSpecialization> {
+ : public PassWrapper<ParallelLoopSpecialization, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LoopParallelLoopSpecialization
#include "mlir/Dialect/LoopOps/Passes.h.inc"
}
namespace {
-struct ParallelLoopTiling : public FunctionPass<ParallelLoopTiling> {
+struct ParallelLoopTiling
+ : public PassWrapper<ParallelLoopTiling, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LoopParallelLoopTiling
#include "mlir/Dialect/LoopOps/Passes.h.inc"
using namespace mlir::quant;
namespace {
-struct ConvertConstPass : public FunctionPass<ConvertConstPass> {
+struct ConvertConstPass : public PassWrapper<ConvertConstPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_QuantConvertConst
#include "mlir/Dialect/Quant/Passes.h.inc"
applyPatternsGreedily(func, patterns);
}
-std::unique_ptr<OpPassBase<FuncOp>> mlir::quant::createConvertConstPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::quant::createConvertConstPass() {
return std::make_unique<ConvertConstPass>();
}
namespace {
struct ConvertSimulatedQuantPass
- : public FunctionPass<ConvertSimulatedQuantPass> {
+ : public PassWrapper<ConvertSimulatedQuantPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_QuantConvertSimulatedQuant
#include "mlir/Dialect/Quant/Passes.h.inc"
signalPassFailure();
}
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::quant::createConvertSimulatedQuantPass() {
return std::make_unique<ConvertSimulatedQuantPass>();
}
namespace {
class DecorateSPIRVCompositeTypeLayoutPass
- : public OperationPass<DecorateSPIRVCompositeTypeLayoutPass, ModuleOp> {
+ : public PassWrapper<DecorateSPIRVCompositeTypeLayoutPass,
+ OperationPass<ModuleOp>> {
private:
void runOnOperation() override;
};
}
}
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
mlir::spirv::createDecorateSPIRVCompositeTypeLayoutPass() {
return std::make_unique<DecorateSPIRVCompositeTypeLayoutPass>();
}
/// Pass to implement the ABI information specified as attributes.
class LowerABIAttributesPass final
- : public OperationPass<LowerABIAttributesPass, spirv::ModuleOp> {
+ : public PassWrapper<LowerABIAttributesPass,
+ OperationPass<spirv::ModuleOp>> {
private:
void runOnOperation() override;
};
}
}
-std::unique_ptr<OpPassBase<spirv::ModuleOp>>
+std::unique_ptr<OperationPass<spirv::ModuleOp>>
mlir::spirv::createLowerABIAttributesPass() {
return std::make_unique<LowerABIAttributesPass>();
}
/// Pass to deduce minimal version/extension/capability requirements for a
/// spirv::ModuleOp.
class UpdateVCEPass final
- : public OperationPass<UpdateVCEPass, spirv::ModuleOp> {
+ : public PassWrapper<UpdateVCEPass, OperationPass<spirv::ModuleOp>> {
private:
void runOnOperation() override;
};
module.setAttr(spirv::ModuleOp::getVCETripleAttrName(), triple);
}
-std::unique_ptr<OpPassBase<spirv::ModuleOp>>
+std::unique_ptr<OperationPass<spirv::ModuleOp>>
mlir::spirv::createUpdateVersionCapabilityExtensionPass() {
return std::make_unique<UpdateVCEPass>();
}
//===----------------------------------------------------------------------===//
/// Pass to verify an operation and signal failure if necessary.
-class VerifierPass : public OperationPass<VerifierPass> {
+class VerifierPass : public PassWrapper<VerifierPass, OperationPass<>> {
void runOnOperation() override;
};
/// An adaptor pass used to run operation passes over nested operations
/// synchronously on a single thread.
-class OpToOpPassAdaptor : public OperationPass<OpToOpPassAdaptor>,
- public OpToOpPassAdaptorBase {
+class OpToOpPassAdaptor
+ : public PassWrapper<OpToOpPassAdaptor, OperationPass<>>,
+ public OpToOpPassAdaptorBase {
public:
OpToOpPassAdaptor(OpPassManager &&mgr);
/// An adaptor pass used to run operation passes over nested operations
/// asynchronously across multiple threads.
class OpToOpPassAdaptorParallel
- : public OperationPass<OpToOpPassAdaptorParallel>,
+ : public PassWrapper<OpToOpPassAdaptorParallel, OperationPass<>>,
public OpToOpPassAdaptorBase {
public:
OpToOpPassAdaptorParallel(OpPassManager &&mgr);
namespace {
/// Simple common sub-expression elimination.
-struct CSE : public OperationPass<CSE> {
+struct CSE : public PassWrapper<CSE, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_CSE
#include "mlir/Transforms/Passes.h.inc"
namespace {
/// Canonicalize operations in nested regions.
-struct Canonicalizer : public OperationPass<Canonicalizer> {
+struct Canonicalizer : public PassWrapper<Canonicalizer, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_Canonicalizer
#include "mlir/Transforms/Passes.h.inc"
//===----------------------------------------------------------------------===//
namespace {
-struct InlinerPass : public OperationPass<InlinerPass> {
+struct InlinerPass : public PassWrapper<InlinerPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_Inliner
#include "mlir/Transforms/Passes.h.inc"
}
namespace {
-struct LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
+struct LocationSnapshotPass
+ : public PassWrapper<LocationSnapshotPass, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LocationSnapshot
#include "mlir/Transforms/Passes.h.inc"
using namespace mlir;
namespace {
-struct LoopCoalescingPass : public FunctionPass<LoopCoalescingPass> {
+struct LoopCoalescingPass
+ : public PassWrapper<LoopCoalescingPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_LoopCoalescing
#include "mlir/Transforms/Passes.h.inc"
} // namespace
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createLoopCoalescingPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createLoopCoalescingPass() {
return std::make_unique<LoopCoalescingPass>();
}
// TODO(andydavis) Extend this pass to check for fusion preventing dependences,
// and add support for more general loop fusion algorithms.
-struct LoopFusion : public FunctionPass<LoopFusion> {
+struct LoopFusion : public PassWrapper<LoopFusion, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffineLoopFusion
#include "mlir/Transforms/Passes.h.inc"
} // end anonymous namespace
-std::unique_ptr<OpPassBase<FuncOp>>
+std::unique_ptr<OperationPass<FuncOp>>
mlir::createLoopFusionPass(unsigned fastMemorySpace,
uint64_t localBufSizeThreshold, bool maximalFusion) {
return std::make_unique<LoopFusion>(fastMemorySpace, localBufSizeThreshold,
namespace {
/// Loop invariant code motion (LICM) pass.
-struct LoopInvariantCodeMotion : public OperationPass<LoopInvariantCodeMotion> {
+struct LoopInvariantCodeMotion
+ : public PassWrapper<LoopInvariantCodeMotion, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_LoopInvariantCodeMotion
#include "mlir/Transforms/Passes.h.inc"
// currently only eliminates the stores only if no other loads/uses (other
// than dealloc) remain.
//
-struct MemRefDataFlowOpt : public FunctionPass<MemRefDataFlowOpt> {
+struct MemRefDataFlowOpt : public PassWrapper<MemRefDataFlowOpt, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_MemRefDataFlowOpt
#include "mlir/Transforms/Passes.h.inc"
/// Creates a pass to perform optimizations relying on memref dataflow such as
/// store to load forwarding, elimination of dead stores, and dead allocs.
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createMemRefDataFlowOptPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createMemRefDataFlowOptPass() {
return std::make_unique<MemRefDataFlowOpt>();
}
using namespace mlir;
namespace {
-struct PrintOpStatsPass : public OperationPass<PrintOpStatsPass, ModuleOp> {
+struct PrintOpStatsPass
+ : public PassWrapper<PrintOpStatsPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_PrintOpStats
#include "mlir/Transforms/Passes.h.inc"
}
}
-std::unique_ptr<OpPassBase<ModuleOp>> mlir::createPrintOpStatsPass() {
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createPrintOpStatsPass() {
return std::make_unique<PrintOpStatsPass>();
}
using namespace mlir;
namespace {
-struct ParallelLoopCollapsing : public OperationPass<ParallelLoopCollapsing> {
+struct ParallelLoopCollapsing
+ : public PassWrapper<ParallelLoopCollapsing, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_ParallelLoopCollapsing
#include "mlir/Transforms/Passes.h.inc"
using namespace mlir;
namespace {
-struct PipelineDataTransfer : public FunctionPass<PipelineDataTransfer> {
+struct PipelineDataTransfer
+ : public PassWrapper<PipelineDataTransfer, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_AffinePipelineDataTransfer
#include "mlir/Transforms/Passes.h.inc"
/// Creates a pass to pipeline explicit movement of data across levels of the
/// memory hierarchy.
-std::unique_ptr<OpPassBase<FuncOp>> mlir::createPipelineDataTransferPass() {
+std::unique_ptr<OperationPass<FuncOp>> mlir::createPipelineDataTransferPass() {
return std::make_unique<PipelineDataTransfer>();
}
using namespace mlir;
namespace {
-struct StripDebugInfo : public OperationPass<StripDebugInfo> {
+struct StripDebugInfo : public PassWrapper<StripDebugInfo, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_StripDebugInfo
#include "mlir/Transforms/Passes.h.inc"
using namespace mlir;
namespace {
-struct SymbolDCE : public OperationPass<SymbolDCE> {
+struct SymbolDCE : public PassWrapper<SymbolDCE, OperationPass<>> {
/// Include the generated pass utilities.
#define GEN_PASS_SymbolDCE
#include "mlir/Transforms/Passes.h.inc"
// PrintOpPass is simple pass to write graph per function.
// Note: this is a module pass only to avoid interleaving on the same ostream
// due to multi-threading over functions.
-struct PrintOpPass : public OperationPass<PrintOpPass, ModuleOp> {
+struct PrintOpPass : public PassWrapper<PrintOpPass, OperationPass<ModuleOp>> {
/// Include the generated pass utilities.
#define GEN_PASS_PrintOpGraph
#include "mlir/Transforms/Passes.h.inc"
return llvm::WriteGraph(os, &block, shortNames, title);
}
-std::unique_ptr<OpPassBase<ModuleOp>>
+std::unique_ptr<OperationPass<ModuleOp>>
mlir::createPrintOpGraphPass(raw_ostream &os, bool shortNames,
const Twine &title) {
return std::make_unique<PrintOpPass>(os, shortNames, title);
void mlir::Region::viewGraph() { viewGraph("region"); }
namespace {
-struct PrintCFGPass : public FunctionPass<PrintCFGPass> {
+struct PrintCFGPass : public PassWrapper<PrintCFGPass, FunctionPass> {
/// Include the generated pass utilities.
#define GEN_PASS_PrintCFG
#include "mlir/Transforms/Passes.h.inc"
};
} // namespace
-std::unique_ptr<mlir::OpPassBase<mlir::FuncOp>>
+std::unique_ptr<mlir::OperationPass<mlir::FuncOp>>
mlir::createPrintCFGGraphPass(raw_ostream &os, bool shortNames,
const Twine &title) {
return std::make_unique<PrintCFGPass>(os, shortNames, title);
namespace {
-struct TestAffineDataCopy : public FunctionPass<TestAffineDataCopy> {
+struct TestAffineDataCopy
+ : public PassWrapper<TestAffineDataCopy, FunctionPass> {
TestAffineDataCopy() = default;
TestAffineDataCopy(const TestAffineDataCopy &pass){};
namespace {
/// This pass applies the permutation on the first maximal perfect nest.
-struct TestLoopPermutation : public FunctionPass<TestLoopPermutation> {
+struct TestLoopPermutation
+ : public PassWrapper<TestLoopPermutation, FunctionPass> {
TestLoopPermutation() = default;
TestLoopPermutation(const TestLoopPermutation &pass){};
namespace {
struct TestParallelismDetection
- : public FunctionPass<TestParallelismDetection> {
+ : public PassWrapper<TestParallelismDetection, FunctionPass> {
void runOnFunction() override;
};
llvm::cl::cat(clOptionsCategory));
namespace {
-struct VectorizerTestPass : public FunctionPass<VectorizerTestPass> {
+struct VectorizerTestPass
+ : public PassWrapper<VectorizerTestPass, FunctionPass> {
static constexpr auto kTestAffineMapOpName = "test_affine_map";
static constexpr auto kTestAffineMapAttrName = "affine_map";
namespace {
/// A pass for testing SPIR-V op availability.
-struct PrintOpAvailability : public FunctionPass<PrintOpAvailability> {
+struct PrintOpAvailability
+ : public PassWrapper<PrintOpAvailability, FunctionPass> {
void runOnFunction() override;
};
} // end anonymous namespace
namespace {
/// A pass for testing SPIR-V op availability.
-struct ConvertToTargetEnv : public FunctionPass<ConvertToTargetEnv> {
+struct ConvertToTargetEnv
+ : public PassWrapper<ConvertToTargetEnv, FunctionPass> {
void runOnFunction() override;
};
//===----------------------------------------------------------------------===//
namespace {
-struct TestPatternDriver : public FunctionPass<TestPatternDriver> {
+struct TestPatternDriver : public PassWrapper<TestPatternDriver, FunctionPass> {
void runOnFunction() override {
mlir::OwningRewritePatternList patterns;
populateWithGenerated(&getContext(), &patterns);
<< it.value().getDefiningOp();
}
-struct TestReturnTypeDriver : public FunctionPass<TestReturnTypeDriver> {
+struct TestReturnTypeDriver
+ : public PassWrapper<TestReturnTypeDriver, FunctionPass> {
void runOnFunction() override {
if (getFunction().getName() == "testCreateFunctions") {
std::vector<Operation *> ops;
};
struct TestLegalizePatternDriver
- : public OperationPass<TestLegalizePatternDriver, ModuleOp> {
+ : public PassWrapper<TestLegalizePatternDriver, OperationPass<ModuleOp>> {
/// The mode of conversion to use with the driver.
enum class ConversionMode { Analysis, Full, Partial };
}
};
-struct TestRemappedValue : public mlir::FunctionPass<TestRemappedValue> {
+struct TestRemappedValue
+ : public mlir::PassWrapper<TestRemappedValue, FunctionPass> {
void runOnFunction() override {
mlir::OwningRewritePatternList patterns;
patterns.insert<OneVResOneVOperandOp1Converter>(&getContext());
namespace {
/// This is a test pass for verifying FuncOp's eraseArgument method.
-struct TestFuncEraseArg : public OperationPass<TestFuncEraseArg, ModuleOp> {
+struct TestFuncEraseArg
+ : public PassWrapper<TestFuncEraseArg, OperationPass<ModuleOp>> {
void runOnOperation() override {
auto module = getOperation();
};
/// This is a test pass for verifying FuncOp's setType method.
-struct TestFuncSetType : public OperationPass<TestFuncSetType, ModuleOp> {
+struct TestFuncSetType
+ : public PassWrapper<TestFuncSetType, OperationPass<ModuleOp>> {
void runOnOperation() override {
auto module = getOperation();
SymbolTable symbolTable(module);
namespace {
/// This is a test pass for verifying matchers.
-struct TestMatchers : public FunctionPass<TestMatchers> {
+struct TestMatchers : public PassWrapper<TestMatchers, FunctionPass> {
void runOnFunction() override;
};
} // end anonymous namespace
using namespace mlir;
namespace {
-struct SideEffectsPass : public OperationPass<SideEffectsPass, ModuleOp> {
+struct SideEffectsPass
+ : public PassWrapper<SideEffectsPass, OperationPass<ModuleOp>> {
void runOnOperation() override {
auto module = getOperation();
namespace {
/// This is a symbol test pass that tests the symbol uselist functionality
/// provided by the symbol table along with erasing from the symbol table.
-struct SymbolUsesPass : public OperationPass<SymbolUsesPass, ModuleOp> {
+struct SymbolUsesPass
+ : public PassWrapper<SymbolUsesPass, OperationPass<ModuleOp>> {
WalkResult operateOnSymbol(Operation *symbol, ModuleOp module,
SmallVectorImpl<FuncOp> &deadFunctions) {
// Test computing uses on a non symboltable op.
/// This is a symbol test pass that tests the symbol use replacement
/// functionality provided by the symbol table.
struct SymbolReplacementPass
- : public OperationPass<SymbolReplacementPass, ModuleOp> {
+ : public PassWrapper<SymbolReplacementPass, OperationPass<ModuleOp>> {
void runOnOperation() override {
auto module = getOperation();
using namespace mlir;
namespace {
-struct TestModulePass : public OperationPass<TestModulePass, ModuleOp> {
+struct TestModulePass
+ : public PassWrapper<TestModulePass, OperationPass<ModuleOp>> {
void runOnOperation() final {}
};
-struct TestFunctionPass : public FunctionPass<TestFunctionPass> {
+struct TestFunctionPass : public PassWrapper<TestFunctionPass, FunctionPass> {
void runOnFunction() final {}
};
-class TestOptionsPass : public FunctionPass<TestOptionsPass> {
+class TestOptionsPass : public PassWrapper<TestOptionsPass, FunctionPass> {
public:
struct Options : public PassPipelineOptions<Options> {
ListOption<int> listOption{*this, "list",
/// A test pass that always aborts to enable testing the crash recovery
/// mechanism of the pass manager.
-class TestCrashRecoveryPass : public OperationPass<TestCrashRecoveryPass> {
+class TestCrashRecoveryPass
+ : public PassWrapper<TestCrashRecoveryPass, OperationPass<>> {
void runOnOperation() final { abort(); }
};
/// A test pass that contains a statistic.
-struct TestStatisticPass : public OperationPass<TestStatisticPass> {
+struct TestStatisticPass
+ : public PassWrapper<TestStatisticPass, OperationPass<>> {
TestStatisticPass() = default;
TestStatisticPass(const TestStatisticPass &) {}
namespace {
struct TestAllReduceLoweringPass
- : public OperationPass<TestAllReduceLoweringPass, ModuleOp> {
+ : public PassWrapper<TestAllReduceLoweringPass, OperationPass<ModuleOp>> {
void runOnOperation() override {
OwningRewritePatternList patterns;
populateGpuRewritePatterns(&getContext(), patterns);
using namespace mlir;
namespace {
-struct TestCallGraphPass : public OperationPass<TestCallGraphPass, ModuleOp> {
+struct TestCallGraphPass
+ : public PassWrapper<TestCallGraphPass, OperationPass<ModuleOp>> {
void runOnOperation() override {
llvm::errs() << "Testing : " << getOperation().getAttr("test.name") << "\n";
getAnalysis<CallGraph>().print(llvm::errs());
namespace {
/// Simple constant folding pass.
-struct TestConstantFold : public FunctionPass<TestConstantFold> {
+struct TestConstantFold : public PassWrapper<TestConstantFold, FunctionPass> {
// All constants in the function post folding.
SmallVector<Operation *, 8> existingConstants;
DenseMap<Block *, size_t> blockIds;
};
-struct TestDominancePass : public FunctionPass<TestDominancePass> {
+struct TestDominancePass : public PassWrapper<TestDominancePass, FunctionPass> {
void runOnFunction() override {
llvm::errs() << "Testing : " << getFunction().getName() << "\n";
/// does not check whether the promotion is legal (e.g., amount of memory used)
/// or beneficial (e.g., makes previously uncoalesced loads coalesced).
class TestGpuMemoryPromotionPass
- : public OperationPass<TestGpuMemoryPromotionPass, gpu::GPUFuncOp> {
+ : public PassWrapper<TestGpuMemoryPromotionPass,
+ OperationPass<gpu::GPUFuncOp>> {
void runOnOperation() override {
gpu::GPUFuncOp op = getOperation();
for (unsigned i = 0, e = op.getNumArguments(); i < e; ++i) {
/// Simple pass for testing the mapping of parallel loops to hardware ids using
/// a greedy mapping strategy.
class TestGpuGreedyParallelLoopMappingPass
- : public OperationPass<TestGpuGreedyParallelLoopMappingPass, FuncOp> {
+ : public PassWrapper<TestGpuGreedyParallelLoopMappingPass,
+ OperationPass<FuncOp>> {
void runOnOperation() override {
Operation *op = getOperation();
for (Region ®ion : op->getRegions())
using namespace mlir;
namespace {
-struct Inliner : public FunctionPass<Inliner> {
+struct Inliner : public PassWrapper<Inliner, FunctionPass> {
void runOnFunction() override {
auto function = getFunction();
} // end namespace mlir
namespace {
-struct TestLinalgTransforms : public FunctionPass<TestLinalgTransforms> {
+struct TestLinalgTransforms
+ : public PassWrapper<TestLinalgTransforms, FunctionPass> {
void runOnFunction() override;
};
} // end anonymous namespace
namespace {
-struct TestLivenessPass : public FunctionPass<TestLivenessPass> {
+struct TestLivenessPass : public PassWrapper<TestLivenessPass, FunctionPass> {
void runOnFunction() override {
llvm::errs() << "Testing : " << getFunction().getName() << "\n";
getAnalysis<Liveness>().print(llvm::errs());
namespace {
-struct TestLoopFusion : public FunctionPass<TestLoopFusion> {
+struct TestLoopFusion : public PassWrapper<TestLoopFusion, FunctionPass> {
void runOnFunction() override;
};
using namespace mlir;
namespace {
-class TestLoopMappingPass : public FunctionPass<TestLoopMappingPass> {
+class TestLoopMappingPass
+ : public PassWrapper<TestLoopMappingPass, FunctionPass> {
public:
explicit TestLoopMappingPass() {}
// Extracts fixed-range loops for top-level loop nests with ranges defined in
// the pass constructor. Assumes loops are permutable.
class SimpleParametricLoopTilingPass
- : public FunctionPass<SimpleParametricLoopTilingPass> {
+ : public PassWrapper<SimpleParametricLoopTilingPass, FunctionPass> {
public:
SimpleParametricLoopTilingPass() = default;
SimpleParametricLoopTilingPass(const SimpleParametricLoopTilingPass &) {}
namespace {
/// Checks for out of bound memef access subscripts..
-struct TestMemRefBoundCheck : public FunctionPass<TestMemRefBoundCheck> {
+struct TestMemRefBoundCheck
+ : public PassWrapper<TestMemRefBoundCheck, FunctionPass> {
void runOnFunction() override;
};
// TODO(andydavis) Add common surrounding loop depth-wise dependence checks.
/// Checks dependences between all pairs of memref accesses in a Function.
struct TestMemRefDependenceCheck
- : public FunctionPass<TestMemRefDependenceCheck> {
+ : public PassWrapper<TestMemRefDependenceCheck, FunctionPass> {
SmallVector<Operation *, 4> loadsAndStores;
void runOnFunction() override;
};
using namespace mlir;
namespace {
-/// Simple constant folding pass.
struct TestMemRefStrideCalculation
- : public FunctionPass<struct TestMemRefStrideCalculation> {
+ : public PassWrapper<TestMemRefStrideCalculation, FunctionPass> {
void runOnFunction() override;
};
} // end anonymous namespace
-// Traverse AllocOp and compute strides of each MemRefType independently.
+/// Traverse AllocOp and compute strides of each MemRefType independently.
void TestMemRefStrideCalculation::runOnFunction() {
llvm::outs() << "Testing: " << getFunction().getName() << "\n";
getFunction().walk([&](AllocOp allocOp) {
/// It also takes all operations that are not function operations or
/// terminators and clones them with opaque locations which store the initial
/// locations.
-struct TestOpaqueLoc : public OperationPass<TestOpaqueLoc, ModuleOp> {
+struct TestOpaqueLoc
+ : public PassWrapper<TestOpaqueLoc, OperationPass<ModuleOp>> {
/// A simple structure which is used for testing as an underlying location in
/// OpaqueLoc.
namespace {
struct TestVectorToLoopsPass
- : public FunctionPass<TestVectorToLoopsPass> {
+ : public PassWrapper<TestVectorToLoopsPass, FunctionPass> {
void runOnFunction() override {
OwningRewritePatternList patterns;
auto *context = &getContext();
#include "TestVectorTransformPatterns.h.inc"
struct TestVectorToVectorConversion
- : public FunctionPass<TestVectorToVectorConversion> {
+ : public PassWrapper<TestVectorToVectorConversion, FunctionPass> {
void runOnFunction() override {
OwningRewritePatternList patterns;
auto *context = &getContext();
};
struct TestVectorSlicesConversion
- : public FunctionPass<TestVectorSlicesConversion> {
+ : public PassWrapper<TestVectorSlicesConversion, FunctionPass> {
void runOnFunction() override {
OwningRewritePatternList patterns;
populateVectorSlicesLoweringPatterns(patterns, &getContext());
};
struct TestVectorContractionConversion
- : public FunctionPass<TestVectorContractionConversion> {
+ : public PassWrapper<TestVectorContractionConversion, FunctionPass> {
TestVectorContractionConversion() = default;
TestVectorContractionConversion(const TestVectorContractionConversion &pass) {
}