blob: 91e65bac4fb8970f5a0110bb93ce792174d57c35 [file] [log] [blame]
// Copyright 2019 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_COMPILER_DIALECT_FLOW_TRANSFORMS_PASSES_H_
#define IREE_COMPILER_DIALECT_FLOW_TRANSFORMS_PASSES_H_
#include "iree/compiler/Dialect/Flow/IR/FlowOps.h"
#include "llvm/ADT/StringMap.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Support/LLVM.h"
namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace Flow {
//===----------------------------------------------------------------------===//
// Pipelines
//===----------------------------------------------------------------------===//
// Adds a set of passes to the given pass manager that run the required flow
// transforms in the canonical order.
//
// Most translation code should prefer to use this instead of manually adding
// the passes themselves to ensure that expected pass ordering is observed.
//
// The expected usage is:
// Input legalization by one of:
// - Directly passing supported flow plus core ops
// buildFlowTransformPassPipeline
// <run conversion from flow to sequencer/hal/vm/etc>
void buildFlowTransformPassPipeline(OpPassManager &passManager);
void registerFlowTransformPassPipeline();
//===----------------------------------------------------------------------===//
// Input canonicalization and legalization
//===----------------------------------------------------------------------===//
/// Creates a pass to convert linalg convolution ops with 1x1 kernels into
/// linalg.matmul
std::unique_ptr<OperationPass<mlir::FuncOp>>
createConvertConv2D1x1ToMatmulPass();
/// Creates a pass to convert linalg convolution ops into linalg.matmul ops
/// using im2col tranformation.
std::unique_ptr<OperationPass<mlir::FuncOp>> createConvertConv2DToImg2ColPass();
/// Pass to convert a linalg.pad_tensor operation into a linalg.fill +
/// subtensor_insert. This allows lowering the operation into a single kernel.
std::unique_ptr<Pass> createPadTensorToSubTensorInsertPass();
/// Pass to convert a linalg.matmul into linalg.mmt4d given M0, N0 and K0 are
/// compile time constants.
std::unique_ptr<OperationPass<FuncOp>>
createConvertLinalgMatmulOpToLinalgMMT4dPass(int M0 = 4, int N0 = 4,
int K0 = 4);
/// Creates a pass to fuse Linalg operations on tensors.
std::unique_ptr<Pass> createFusionOfTensorOpsPass();
/// Create a pass to interchange generic ops to force the reduction loop to be
/// the most inner loops.
std::unique_ptr<OperationPass<mlir::FuncOp>> createInterchangeGenericOpsPass();
// Convert operations to equivalent flow ops before dispatch region creation.
std::unique_ptr<OperationPass<mlir::FuncOp>>
createConvertToFlowBeforeDispatchFormation();
// Convert remaining operations that were left outside of dispatch regions to
// equivalent flow ops.
std::unique_ptr<OperationPass<mlir::FuncOp>>
createConvertToFlowAfterDispatchFormation();
// Promote I1 tensor constants to I8 tensors to match later operations.
std::unique_ptr<OperationPass<mlir::FuncOp>> createPromoteI1ToI8Pass();
// Converts standard ops which match to flow.tensor.load (typically causing a
// read-back).
// Note that there are typically very specific phase ordering issues with
// performing such a conversion, so even though it is of fine granularity,
// this is maintained separately.
std::unique_ptr<OperationPass<mlir::FuncOp>> createPromoteTensorLoadsPass();
// Expands dynamic !shapex.ranked_shape dimensions in variables.
std::unique_ptr<OperationPass<mlir::ModuleOp>>
createExpandGlobalDynamicDimsPass();
/// Verified if the input to the Flow transformation passes has operations from
/// dialects that are expected to be legalized before this pass.
std::unique_ptr<OperationPass<mlir::FuncOp>> createVerifyInputLegalityPass();
//===----------------------------------------------------------------------===//
// Dispatches (flow.dispatch.workgroups)
//===----------------------------------------------------------------------===//
/// Pass to perform dispatch of Linalg on tensor ops by tiling and distribution.
/// A dispatch region is created for each tiled loop nest.
std::unique_ptr<OperationPass<mlir::FuncOp>>
createDispatchLinalgOnTensorsPass();
// Outlines dispatch regions into executables.
std::unique_ptr<OperationPass<mlir::ModuleOp>>
createOutlineDispatchRegionsPass();
// Injects tracing markers for dispatch operation tensor inputs and outputs.
std::unique_ptr<OperationPass<mlir::FuncOp>> createInjectDispatchTracingPass();
// Exports all functions and dispatch executables as `() -> ()` benchmark funcs.
std::unique_ptr<OperationPass<mlir::ModuleOp>> createExportBenchmarkFuncsPass();
//===----------------------------------------------------------------------===//
// Linalg transforms
//===----------------------------------------------------------------------===//
/// A pass to pad linalg ops to the next integer multiple of `paddingSize`.
std::unique_ptr<OperationPass<mlir::FuncOp>>
createPadLinalgOpsToIntegerMultiplePass(int paddingSize = 4);
//===----------------------------------------------------------------------===//
// Optimizations
//===----------------------------------------------------------------------===//
// Outlines large tensor constants into util.globals at the module level.
//
// TODO(#5493): implement the support for inlining constants into the command
// buffer and raise this value to one that is measured to be good.
static constexpr size_t kMinLargeConstantSize = 1;
std::unique_ptr<OperationPass<mlir::ModuleOp>> createOutlineLargeConstantsPass(
size_t minLargeConstantSize = kMinLargeConstantSize);
// Deduplicates equivalent executables.
std::unique_ptr<OperationPass<mlir::ModuleOp>>
createDeduplicateExecutablesPass();
//===----------------------------------------------------------------------===//
// Stream Formation and Folding
//===----------------------------------------------------------------------===//
// Identifies dispatches that can be grouped into streams within functions.
std::unique_ptr<OperationPass<mlir::FuncOp>> createFormStreamsPass();
// Reorders blocks to hoist ops that cannot be put into streams.
std::unique_ptr<OperationPass<mlir::FuncOp>> createHoistUnstreamableOpsPass();
// TODO(benvanik): cross-function stream flows.
// Inserts clones of constant values where they may be required.
std::unique_ptr<OperationPass<mlir::FuncOp>> createInsertConstantClonesPass();
//===----------------------------------------------------------------------===//
// Module Analysis and Finalization
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Simplification and Development Tools
//===----------------------------------------------------------------------===//
// Strips constant util.globals and replaces them with splats.
// This destructively removes data (often model weights and other parameters)
// and is intended for use as a development tool.
// TODO(scotttodd): pass pipeline with this and other development passes to
// generate test cases / models suitable for check-in
std::unique_ptr<OperationPass<mlir::ModuleOp>>
createStripAndSplatConstantVariablesPass();
//===----------------------------------------------------------------------===//
// Register all Passes
//===----------------------------------------------------------------------===//
void registerFlowPasses();
} // namespace Flow
} // namespace IREE
} // namespace iree_compiler
} // namespace mlir
#endif // IREE_COMPILER_DIALECT_FLOW_TRANSFORMS_PASSES_H_