14bb31f73SAlex Zinenko //===- OptUtils.cpp - MLIR Execution Engine optimization pass utilities ---===//
24bb31f73SAlex Zinenko //
330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64bb31f73SAlex Zinenko //
756222a06SMehdi Amini //===----------------------------------------------------------------------===//
84bb31f73SAlex Zinenko //
94bb31f73SAlex Zinenko // This file implements the utility functions to trigger LLVM optimizations from
104bb31f73SAlex Zinenko // MLIR Execution Engine.
114bb31f73SAlex Zinenko //
124bb31f73SAlex Zinenko //===----------------------------------------------------------------------===//
134bb31f73SAlex Zinenko
144bb31f73SAlex Zinenko #include "mlir/ExecutionEngine/OptUtils.h"
154bb31f73SAlex Zinenko
1668587dfcSDiego Caballero #include "llvm/Analysis/TargetTransformInfo.h"
174bb31f73SAlex Zinenko #include "llvm/IR/Module.h"
187ccd026cSArthur Eubanks #include "llvm/Passes/OptimizationLevel.h"
197ccd026cSArthur Eubanks #include "llvm/Passes/PassBuilder.h"
204bb31f73SAlex Zinenko #include "llvm/Support/Error.h"
217ccd026cSArthur Eubanks #include "llvm/Support/FormatVariadic.h"
2268587dfcSDiego Caballero #include "llvm/Target/TargetMachine.h"
23*5273219eSKazu Hirata #include <optional>
244bb31f73SAlex Zinenko
257ccd026cSArthur Eubanks using namespace llvm;
267ccd026cSArthur Eubanks
mapToLevel(unsigned optLevel,unsigned sizeLevel)27*5273219eSKazu Hirata static std::optional<OptimizationLevel> mapToLevel(unsigned optLevel,
287ccd026cSArthur Eubanks unsigned sizeLevel) {
297ccd026cSArthur Eubanks switch (optLevel) {
307ccd026cSArthur Eubanks case 0:
317ccd026cSArthur Eubanks return OptimizationLevel::O0;
327ccd026cSArthur Eubanks
337ccd026cSArthur Eubanks case 1:
347ccd026cSArthur Eubanks return OptimizationLevel::O1;
357ccd026cSArthur Eubanks
367ccd026cSArthur Eubanks case 2:
377ccd026cSArthur Eubanks switch (sizeLevel) {
387ccd026cSArthur Eubanks case 0:
397ccd026cSArthur Eubanks return OptimizationLevel::O2;
407ccd026cSArthur Eubanks
417ccd026cSArthur Eubanks case 1:
427ccd026cSArthur Eubanks return OptimizationLevel::Os;
437ccd026cSArthur Eubanks
447ccd026cSArthur Eubanks case 2:
457ccd026cSArthur Eubanks return OptimizationLevel::Oz;
464bb31f73SAlex Zinenko }
4742f5b050SDaniil Dudkin break;
487ccd026cSArthur Eubanks case 3:
497ccd026cSArthur Eubanks return OptimizationLevel::O3;
504bb31f73SAlex Zinenko }
511a36588eSKazu Hirata return std::nullopt;
5268587dfcSDiego Caballero }
53d9cc3c31SAlex Zinenko // Create and return a lambda that uses LLVM pass manager builder to set up
54d9cc3c31SAlex Zinenko // optimizations based on the given level.
557ccd026cSArthur Eubanks std::function<Error(Module *)>
makeOptimizingTransformer(unsigned optLevel,unsigned sizeLevel,TargetMachine * targetMachine)5668587dfcSDiego Caballero mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
577ccd026cSArthur Eubanks TargetMachine *targetMachine) {
587ccd026cSArthur Eubanks return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
59*5273219eSKazu Hirata std::optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
607ccd026cSArthur Eubanks if (!ol) {
617ccd026cSArthur Eubanks return make_error<StringError>(
627ccd026cSArthur Eubanks formatv("invalid optimization/size level {0}/{1}", optLevel,
637ccd026cSArthur Eubanks sizeLevel)
647ccd026cSArthur Eubanks .str(),
657ccd026cSArthur Eubanks inconvertibleErrorCode());
664bb31f73SAlex Zinenko }
677ccd026cSArthur Eubanks LoopAnalysisManager lam;
687ccd026cSArthur Eubanks FunctionAnalysisManager fam;
697ccd026cSArthur Eubanks CGSCCAnalysisManager cgam;
707ccd026cSArthur Eubanks ModuleAnalysisManager mam;
714bb31f73SAlex Zinenko
72f11e0741SDenys Shabalin PipelineTuningOptions tuningOptions;
73f11e0741SDenys Shabalin tuningOptions.LoopUnrolling = true;
74f11e0741SDenys Shabalin tuningOptions.LoopInterleaving = true;
75f11e0741SDenys Shabalin tuningOptions.LoopVectorization = true;
76f11e0741SDenys Shabalin tuningOptions.SLPVectorization = true;
77f11e0741SDenys Shabalin
78f11e0741SDenys Shabalin PassBuilder pb(targetMachine, tuningOptions);
794bb31f73SAlex Zinenko
807ccd026cSArthur Eubanks pb.registerModuleAnalyses(mam);
817ccd026cSArthur Eubanks pb.registerCGSCCAnalyses(cgam);
827ccd026cSArthur Eubanks pb.registerFunctionAnalyses(fam);
837ccd026cSArthur Eubanks pb.registerLoopAnalyses(lam);
847ccd026cSArthur Eubanks pb.crossRegisterProxies(lam, fam, cgam, mam);
854bb31f73SAlex Zinenko
867ccd026cSArthur Eubanks ModulePassManager mpm;
877ccd026cSArthur Eubanks mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol));
887ccd026cSArthur Eubanks mpm.run(*m, mam);
897ccd026cSArthur Eubanks return Error::success();
904bb31f73SAlex Zinenko };
914bb31f73SAlex Zinenko }
92