| //===- OptUtils.cpp - MLIR Execution Engine optimization pass utilities ---===// |
| // |
| // Part of the LLVM Project, 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the utility functions to trigger LLVM optimizations from |
| // MLIR Execution Engine. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "mlir/ExecutionEngine/OptUtils.h" |
| |
| #include "llvm/Analysis/TargetTransformInfo.h" |
| #include "llvm/IR/Module.h" |
| #include "llvm/Passes/OptimizationLevel.h" |
| #include "llvm/Passes/PassBuilder.h" |
| #include "llvm/Support/Error.h" |
| #include "llvm/Support/FormatVariadic.h" |
| #include "llvm/Target/TargetMachine.h" |
| #include <optional> |
| |
| using namespace llvm; |
| |
| static std::optional<OptimizationLevel> mapToLevel(unsigned optLevel, |
| unsigned sizeLevel) { |
| switch (optLevel) { |
| case 0: |
| return OptimizationLevel::O0; |
| |
| case 1: |
| return OptimizationLevel::O1; |
| |
| case 2: |
| switch (sizeLevel) { |
| case 0: |
| return OptimizationLevel::O2; |
| |
| case 1: |
| return OptimizationLevel::Os; |
| |
| case 2: |
| return OptimizationLevel::Oz; |
| } |
| break; |
| case 3: |
| return OptimizationLevel::O3; |
| } |
| return std::nullopt; |
| } |
| // Create and return a lambda that uses LLVM pass manager builder to set up |
| // optimizations based on the given level. |
| std::function<Error(Module *)> |
| mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel, |
| TargetMachine *targetMachine) { |
| return [optLevel, sizeLevel, targetMachine](Module *m) -> Error { |
| std::optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel); |
| if (!ol) { |
| return make_error<StringError>( |
| formatv("invalid optimization/size level {0}/{1}", optLevel, |
| sizeLevel) |
| .str(), |
| inconvertibleErrorCode()); |
| } |
| LoopAnalysisManager lam; |
| FunctionAnalysisManager fam; |
| CGSCCAnalysisManager cgam; |
| ModuleAnalysisManager mam; |
| |
| PipelineTuningOptions tuningOptions; |
| tuningOptions.LoopUnrolling = true; |
| tuningOptions.LoopInterleaving = true; |
| tuningOptions.LoopVectorization = true; |
| tuningOptions.SLPVectorization = true; |
| |
| PassBuilder pb(targetMachine, tuningOptions); |
| |
| pb.registerModuleAnalyses(mam); |
| pb.registerCGSCCAnalyses(cgam); |
| pb.registerFunctionAnalyses(fam); |
| pb.registerLoopAnalyses(lam); |
| pb.crossRegisterProxies(lam, fam, cgam, mam); |
| |
| ModulePassManager mpm; |
| mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol)); |
| mpm.run(*m, mam); |
| return Error::success(); |
| }; |
| } |