blob: 12f90be95ee02b20fe55fa34ba994ee299280ecf [file]
// Copyright 2023 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef IREE_CODEGEN_LLVMCPU_PASSES
#define IREE_CODEGEN_LLVMCPU_PASSES
include "mlir/Pass/PassBase.td"
//------------------------------------------------------------------------------
// LLVMCPU Passes (keep alphabetical)
//------------------------------------------------------------------------------
def ConvertToLLVMPass :
Pass<"iree-convert-to-llvm", "ModuleOp"> {
let summary =
"Perform final conversion from Linalg/HAL/Shape/Vector/Standard to LLVMIR dialect";
let options = [
Option<"reassociateFpReductions", "reassociateFpReductions", "bool",
/*default=*/"false",
"Specifies if FP add and mult reductions can be reordered">,
Option<"targetTriple", "target-triple", "std::string", /*default=*/"",
"Code generation target triple.">,
Option<"targetDataLayout", "target-data-layout", "std::string",
/*default=*/"",
"Code generation target data layout.">,
];
}
def ExpandF16OpToF32Pass :
Pass<"iree-llvmcpu-expand-f16-op-to-f32", ""> {
let summary =
"Preform f16 opertaions by expanding them to f32.";
let description = [{
Pass to handel F16 bit operations, but converting f16 operands to F32.
Currently this pass is handeling fmaxf conversion from f16 to f32,
and then returing a f16 output back after preforming the operation.
Can handle more operations if required in future.
}];
}
def LLVMCPUAssignConstantOrdinalsPass :
Pass<"iree-llvmcpu-assign-constant-ordinals", "IREE::HAL::ExecutableVariantOp"> {
let summary = "Assigns executable constant ordinals across all LLVMCPU variants.";
}
def LLVMCPUAssignImportOrdinalsPass :
Pass<"iree-llvmcpu-assign-import-ordinals", "IREE::HAL::ExecutableVariantOp"> {
let summary = "Assigns executable import ordinals across all LLVMCPU variants.";
}
def LLVMCPUCheckIRBeforeLLVMConversionPass :
InterfacePass<"iree-llvmcpu-check-ir-before-llvm-conversion", "mlir::FunctionOpInterface"> {
let summary = "Checks CPU backend specific IR constraints (like no allocas)";
let options = [
Option<"failOnOutOfBounds", "fail-on-out-of-bounds", "bool", "true",
"Fails if the upper bound of dynamic stack allocation cannot be"
"resolved or is more than the limit.">
];
}
def LLVMCPUEmitVectorizationRemarksPass :
InterfacePass<"iree-llvmcpu-emit-vectorization-remarks", "mlir::FunctionOpInterface"> {
let summary = "Emit vectorization remarks on Linalg ops";
}
def LLVMCPULinkExecutablesPass :
Pass<"iree-llvmcpu-link-executables", "mlir::ModuleOp"> {
let summary = "Links LLVMCPU HAL executables within the top-level program module.";
let options = [
Option<
"target", "target",
"std::string", "",
"Target backend name whose executables will be linked by this pass."
>,
];
}
def LLVMCPULowerExecutableTargetPass :
InterfacePass<"iree-llvmcpu-lower-executable-target", "mlir::FunctionOpInterface"> {
let summary =
"Lower executable target using an IREE::HAL::DispatchLoweringPassPipeline";
let description = [{
Pass to lower the module an hal.executable.variant operation to external
dialect. Currently this pass lowers to LLVM dialect, but could be
generalized to lower to any "final" dialect like SPIR-V/NVVM, etc.
}];
}
def LLVMCPUMmt4dVectorLoweringPass
: InterfacePass<"iree-llvmcpu-mmt4d-vector-lowering", "mlir::FunctionOpInterface"> {
let summary = "Apply vector lowering logic to vector ops";
let options = [
Option<"enableVectorContractCustomKernels", "vector-contract-custom-kernels", "bool",
/*default=*/"true",
"Flag to enable or disable vector contract custom kernels.">,
];
}
def LLVMCPUPeelPass :
InterfacePass<"iree-llvmcpu-peel", "mlir::FunctionOpInterface"> {
let summary = "Pass to perform peeling on non-distributed loops.";
}
def LLVMCPUSelectLoweringStrategyPass :
Pass<"iree-llvmcpu-select-lowering-strategy", "ModuleOp"> {
let summary =
"Select a IREE::HAL::DispatchLoweringPassPipeline for lowering the variant";
let description = [{
Pass to select a lowering strategy for a hal.executable.variant operation.
The variant is annotated with the selected strategies, which are
subsequently ingested by LLVMCPULowerExecutableTargetPass.
}];
}
def LLVMCPUSplitReductionPass : InterfacePass<"iree-llvmcpu-split-reduction", "mlir::FunctionOpInterface"> {
let summary = "Pass to splitReduce linalg operations.";
let options = [
Option<"enableFpReductionReordering", "enable-fp-reduction-reordering",
"bool", /*default=*/"false",
"Flag to enable reduction reordering on floating points.">,
];
}
def LLVMCPUSynchronizeSymbolVisibilityPass :
Pass<"iree-llvmcpu-synchronize-symbol-visibility", "ModuleOp"> {
let summary = "Synchronizes LLVM linkage with MLIR symbol visibility";
}
def LLVMCPUTilePass :
InterfacePass<"iree-llvmcpu-tile", "mlir::FunctionOpInterface"> {
let summary = "Pass to tile TilingInterface operations.";
let options = [
Option<"tilingLevel", "tiling-level", "int64_t", /*default=*/"-1",
"Use default tiling level used to retrieve the configuration from lowering_config">
];
}
def LLVMCPUTileAndFusePass :
InterfacePass<"iree-llvmcpu-tile-and-fuse", "mlir::FunctionOpInterface"> {
let summary = "Pass to tile and fuse TilingInterface operations.";
let options = [
Option<"tilingLevel", "tiling-level", "int64_t", /*default=*/"-1",
"Use default tiling level used to retrieve the configuration from lowering_config">
];
}
def LLVMCPUTileRootAndFuseProducerConsumerPass
: InterfacePass<"iree-llvmcpu-tile-root-and-fuse-producer-consumer",
"mlir::FunctionOpInterface"> {
let summary = "Pass to tile root op and fuse with producer and consumer "
"TilingInterface ops.";
let options =
[Option<"tilingLevel", "tiling-level", "int64_t", /*default=*/"-1",
"Use default tiling level used to retrieve the configuration "
"from lowering_config">,
Option<"onlyFuseProducerInputOperands",
"only-fuse-producer-input-operands", "bool",
/*default=*/"false",
"Specifies if we only want to fuse producer's input operands. "
"This is helpful to tile&fuse in case of reduction dimensions.">];
}
def LLVMCPUVerifyVectorSizeLegalityPass :
InterfacePass<"iree-llvmcpu-verify-vector-size-legality", "mlir::FunctionOpInterface"> {
let summary =
"Signals errors when there are large vectors in the IR. I.e., one of"
"the vector sizes is greater than"
"maxAllowedNumberOfNativeVectors * native_vector_size. For scalable"
"vectors, it assumes that the vscale value is always 1. It may be an"
"underestimate if the runtime larger than 1, but it should still catch"
"unreasonable vector sizes.";
let options = [
Option<"maxAllowedNumberOfNativeVectors", "max-allowed-number-of-native-vectors", "int64_t", /*default=*/"512",
"The ratio used in the computation of max vector size.">
];
}
// Note: This pass is currently only required when targeting Arm SME (which is
// the only target that currently has some concept of 2D scalability).
def LLVMCPU2DScalableTo1DScalablePass :
InterfacePass<"iree-llvmcpu-2d-scalable-to-1d-scalable", "mlir::FunctionOpInterface"> {
let summary = "Pass to replace unsupported scalable dimensions with loops.";
let options = [
Option<"assumeArmSME", "assume-arm-sme", "bool", /*default=*/"false",
"Assume the current target is ArmSME (used for testing)">
];
}
def LLVMCPUUnfuseFMAOpsPass :
InterfacePass<"iree-llvmcpu-unfuse-fma-pass", "mlir::FunctionOpInterface"> {
let summary = "Convert llvm.fma into unfused mulf and addf ops";
}
def LLVMCPUVirtualVectorLoweringPass :
InterfacePass<"iree-llvmcpu-virtual-vector-lowering", "mlir::FunctionOpInterface"> {
let summary = "Pass to lower high level vector operations like contract or multidim reduce ops to lower level vector ops.";
let options = [
Option<"splitVectorTransfersTo", "split-transfers", "std::string",
/*default=*/"",
[{Split vector transfers between slow (masked) and fast "
"(unmasked) variants. Possible options are:\n"
"\tnone [default]: keep unsplit vector.transfer and pay the price\n"
"\tlinalg-copy: use linalg.fill + linalg.generic for the slow path\n"
"\tvector-transfers: use extra small unmasked vector.transfers for"
" the slow path\n}]>,
Option<"enableArmI8mm", "enable-arm-i8mm", "bool",
/*default=*/ "false",
"Enables arm i8mm lowering patterns">,
];
}
def LLVMCPUVectorTransferLoweringPass :
InterfacePass<"iree-llvmcpu-vector-transfer-lowering", "mlir::FunctionOpInterface"> {
let summary = "Pass to lower transfer ops to simpler ops like `vector.load`, `vector.store`, `vector.broadcast`, and a set of scf ops.";
let options = [
Option<"enableScalableLowerings", "enable-scalable-lowerings", "bool",
/*default=*/"false",
"Enables scalable vector specific transfer lowerings">,
];
}
def LLVMCPUVectorTransposeLoweringPass :
InterfacePass<"iree-llvmcpu-vector-transpose-lowering", "mlir::FunctionOpInterface"> {
let summary = "Pass to lower vector.transpose ops.";
let options = [
Option<"lowerVectorTransposeToAVX2", "lower-vector-transpose-to-avx2", "bool",
/*default=*/"false",
"Add specific transpose to avx2 lowering patterns.">,
];
}
def LLVMCPUVectorShapeCastLoweringPass :
InterfacePass<"iree-llvmcpu-vector-shape-cast-lowering", "mlir::FunctionOpInterface"> {
let summary = "Pass to lower vector.shape_cast ops.";
}
def VectorContractCustomKernelsPass :
InterfacePass<"iree-llvmcpu-vector-contract-custom-kernels", "mlir::FunctionOpInterface"> {
let summary = "Enable custom kernels (inline assembly or intrinsics) for some vector.contract ops";
}
def VerifyLinalgTransformLegalityPass :
InterfacePass<"iree-llvmcpu-verify-linalg-transform-legality", "mlir::FunctionOpInterface"> {
let summary = "Verify that only supported IR constructs are passed to the compiler.";
}
#endif // IREE_CODEGEN_LLVMCPU_PASSES