blob: 2ec5db7dff1ff4e7edde68945486ef68377b91b0 [file] [log] [blame]
// Copyright 2020 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
#include "iree/compiler/Codegen/Passes.h"
#include "iree/compiler/Codegen/PassDetail.h"
#include "iree/compiler/Dialect/LinalgExt/Transforms/Passes.h"
#include "iree/compiler/Dialect/Shape/Transforms/Passes.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/Passes.h"
namespace mlir {
namespace iree_compiler {
static llvm::cl::opt<bool> clUseTensorPadTileAndVectorize(
"iree-codegen-linalg-to-llvm-use-tensor-to-vectors",
llvm::cl::desc("If enabled will use tensor -> vector transformation pass"),
llvm::cl::init(false));
static Value cpuAllocationFunction(OpBuilder &builder, Location loc,
ArrayRef<int64_t> staticShape,
Type elementType,
ArrayRef<Value> dynamicSizes) {
MemRefType allocType = MemRefType::get(staticShape, elementType);
return builder.create<memref::AllocaOp>(loc, allocType, dynamicSizes);
}
void addCPUVectorizationPassPipeline(OpPassManager &passManager,
bool lowerToVectors) {
passManager.addPass(createCanonicalizerPass());
// TODO(ataei): This causes segmentation fault on Android. Fix it and
// re-enable.
// passManager.addNestedPass<FuncOp>(createPadLinalgWorkgroupTilesPass());
if (clUseTensorPadTileAndVectorize) {
// Tile and vectorize linalg ops on tensors.
passManager.addNestedPass<FuncOp>(createLLVMCPUTilePadAndVectorizePass());
passManager.addNestedPass<FuncOp>(createCSEPass());
passManager.addNestedPass<FuncOp>(createCanonicalizerPass());
}
// Use stack allocation on CPU side.
addLinalgBufferizePasses(passManager, cpuAllocationFunction);
passManager.addNestedPass<FuncOp>(createCSEPass());
passManager.addNestedPass<FuncOp>(createCanonicalizerPass());
if (!clUseTensorPadTileAndVectorize) {
// Tile and vectorize linalg ops on buffers.
passManager.addNestedPass<FuncOp>(
createLLVMCPUVectorizationPass(lowerToVectors));
passManager.addNestedPass<FuncOp>(createCSEPass());
passManager.addNestedPass<FuncOp>(createCanonicalizerPass());
}
passManager.addNestedPass<FuncOp>(createForOpCanonicalizationPass());
passManager.addNestedPass<FuncOp>(createLLVMCPUPlanConvLoopOrderPass());
}
void addCPUDefaultPassPipeline(OpPassManager &passManager) {
passManager.addPass(createCanonicalizerPass());
// Use stack allocation on CPU side.
addLinalgBufferizePasses(passManager, cpuAllocationFunction);
passManager.addNestedPass<FuncOp>(createLLVMCPUPlanConvLoopOrderPass());
}
static void addLowerToLLVMPasses(
OpPassManager &passManager,
const LLVMCPUCodegenPassPipelineOptions &options) {
// LinalgExt -> SCF
passManager.addNestedPass<FuncOp>(linalg_ext::createLinalgExtToLoopsPass());
// Linalg -> SCF
passManager.addNestedPass<FuncOp>(createConvertLinalgToLoopsPass());
passManager.addNestedPass<FuncOp>(createCanonicalizerPass());
passManager.addNestedPass<FuncOp>(createCSEPass());
// SCF -> STD
passManager.addNestedPass<FuncOp>(createLowerToCFGPass());
passManager.addNestedPass<FuncOp>(createCanonicalizerPass());
passManager.addNestedPass<FuncOp>(createCSEPass());
// Handled tensor-type constants.
passManager.addPass(createTensorConstantBufferizePass());
passManager.addPass(createFoldTensorExtractOpPass());
// (HAL, IREE, Linalg, STD) -> LLVM
passManager.addPass(createConvertToLLVMPass(
options.targetTriple, options.targetDataLayout, options.unfuseFMAOps));
passManager.addPass(createCanonicalizerPass());
passManager.addPass(createCSEPass());
}
void buildLLVMCPUCodegenPassPipeline(
OpPassManager &passManager,
const LLVMCPUCodegenPassPipelineOptions &options) {
OpPassManager &nestedModulePM = passManager.nest<ModuleOp>();
addLowerToLLVMPasses(nestedModulePM, options);
}
} // namespace iree_compiler
} // namespace mlir