1 //===- OptUtils.cpp - MLIR Execution Engine optimization pass utilities ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the utility functions to trigger LLVM optimizations from
10 // MLIR Execution Engine.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "mlir/ExecutionEngine/OptUtils.h"
15
16 #include "llvm/Analysis/TargetTransformInfo.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Passes/OptimizationLevel.h"
19 #include "llvm/Passes/PassBuilder.h"
20 #include "llvm/Support/Error.h"
21 #include "llvm/Support/FormatVariadic.h"
22 #include "llvm/Target/TargetMachine.h"
23
24 using namespace llvm;
25
mapToLevel(unsigned optLevel,unsigned sizeLevel)26 static Optional<OptimizationLevel> mapToLevel(unsigned optLevel,
27 unsigned sizeLevel) {
28 switch (optLevel) {
29 case 0:
30 return OptimizationLevel::O0;
31
32 case 1:
33 return OptimizationLevel::O1;
34
35 case 2:
36 switch (sizeLevel) {
37 case 0:
38 return OptimizationLevel::O2;
39
40 case 1:
41 return OptimizationLevel::Os;
42
43 case 2:
44 return OptimizationLevel::Oz;
45 }
46 break;
47 case 3:
48 return OptimizationLevel::O3;
49 }
50 return None;
51 }
52 // Create and return a lambda that uses LLVM pass manager builder to set up
53 // optimizations based on the given level.
54 std::function<Error(Module *)>
makeOptimizingTransformer(unsigned optLevel,unsigned sizeLevel,TargetMachine * targetMachine)55 mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
56 TargetMachine *targetMachine) {
57 return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
58 Optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
59 if (!ol) {
60 return make_error<StringError>(
61 formatv("invalid optimization/size level {0}/{1}", optLevel,
62 sizeLevel)
63 .str(),
64 inconvertibleErrorCode());
65 }
66 LoopAnalysisManager lam;
67 FunctionAnalysisManager fam;
68 CGSCCAnalysisManager cgam;
69 ModuleAnalysisManager mam;
70
71 PassBuilder pb(targetMachine);
72
73 pb.registerModuleAnalyses(mam);
74 pb.registerCGSCCAnalyses(cgam);
75 pb.registerFunctionAnalyses(fam);
76 pb.registerLoopAnalyses(lam);
77 pb.crossRegisterProxies(lam, fam, cgam, mam);
78
79 ModulePassManager mpm;
80 if (*ol == OptimizationLevel::O0)
81 mpm.addPass(pb.buildO0DefaultPipeline(*ol));
82 else
83 mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol));
84
85 mpm.run(*m, mam);
86 return Error::success();
87 };
88 }
89