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"
234bb31f73SAlex Zinenko
247ccd026cSArthur Eubanks using namespace llvm;
257ccd026cSArthur Eubanks
mapToLevel(unsigned optLevel,unsigned sizeLevel)267ccd026cSArthur Eubanks static Optional<OptimizationLevel> mapToLevel(unsigned optLevel,
277ccd026cSArthur Eubanks unsigned sizeLevel) {
287ccd026cSArthur Eubanks switch (optLevel) {
297ccd026cSArthur Eubanks case 0:
307ccd026cSArthur Eubanks return OptimizationLevel::O0;
317ccd026cSArthur Eubanks
327ccd026cSArthur Eubanks case 1:
337ccd026cSArthur Eubanks return OptimizationLevel::O1;
347ccd026cSArthur Eubanks
357ccd026cSArthur Eubanks case 2:
367ccd026cSArthur Eubanks switch (sizeLevel) {
377ccd026cSArthur Eubanks case 0:
387ccd026cSArthur Eubanks return OptimizationLevel::O2;
397ccd026cSArthur Eubanks
407ccd026cSArthur Eubanks case 1:
417ccd026cSArthur Eubanks return OptimizationLevel::Os;
427ccd026cSArthur Eubanks
437ccd026cSArthur Eubanks case 2:
447ccd026cSArthur Eubanks return OptimizationLevel::Oz;
454bb31f73SAlex Zinenko }
46*42f5b050SDaniil Dudkin break;
477ccd026cSArthur Eubanks case 3:
487ccd026cSArthur Eubanks return OptimizationLevel::O3;
494bb31f73SAlex Zinenko }
507ccd026cSArthur Eubanks return None;
5168587dfcSDiego Caballero }
52d9cc3c31SAlex Zinenko // Create and return a lambda that uses LLVM pass manager builder to set up
53d9cc3c31SAlex Zinenko // optimizations based on the given level.
547ccd026cSArthur Eubanks std::function<Error(Module *)>
makeOptimizingTransformer(unsigned optLevel,unsigned sizeLevel,TargetMachine * targetMachine)5568587dfcSDiego Caballero mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
567ccd026cSArthur Eubanks TargetMachine *targetMachine) {
577ccd026cSArthur Eubanks return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
587ccd026cSArthur Eubanks Optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
597ccd026cSArthur Eubanks if (!ol) {
607ccd026cSArthur Eubanks return make_error<StringError>(
617ccd026cSArthur Eubanks formatv("invalid optimization/size level {0}/{1}", optLevel,
627ccd026cSArthur Eubanks sizeLevel)
637ccd026cSArthur Eubanks .str(),
647ccd026cSArthur Eubanks inconvertibleErrorCode());
654bb31f73SAlex Zinenko }
667ccd026cSArthur Eubanks LoopAnalysisManager lam;
677ccd026cSArthur Eubanks FunctionAnalysisManager fam;
687ccd026cSArthur Eubanks CGSCCAnalysisManager cgam;
697ccd026cSArthur Eubanks ModuleAnalysisManager mam;
704bb31f73SAlex Zinenko
717ccd026cSArthur Eubanks PassBuilder pb(targetMachine);
724bb31f73SAlex Zinenko
737ccd026cSArthur Eubanks pb.registerModuleAnalyses(mam);
747ccd026cSArthur Eubanks pb.registerCGSCCAnalyses(cgam);
757ccd026cSArthur Eubanks pb.registerFunctionAnalyses(fam);
767ccd026cSArthur Eubanks pb.registerLoopAnalyses(lam);
777ccd026cSArthur Eubanks pb.crossRegisterProxies(lam, fam, cgam, mam);
784bb31f73SAlex Zinenko
797ccd026cSArthur Eubanks ModulePassManager mpm;
807ccd026cSArthur Eubanks if (*ol == OptimizationLevel::O0)
817ccd026cSArthur Eubanks mpm.addPass(pb.buildO0DefaultPipeline(*ol));
827ccd026cSArthur Eubanks else
837ccd026cSArthur Eubanks mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol));
84d9cc3c31SAlex Zinenko
857ccd026cSArthur Eubanks mpm.run(*m, mam);
867ccd026cSArthur Eubanks return Error::success();
874bb31f73SAlex Zinenko };
884bb31f73SAlex Zinenko }
89