xref: /llvm-project/mlir/lib/ExecutionEngine/OptUtils.cpp (revision a8f6b5763e89cfeec94d3fcf0f6b70f96b293f7d)
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