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#include <optional>
24
25using namespace llvm;
26
27static std::optional<OptimizationLevel> mapToLevel(unsigned optLevel,
28 unsigned sizeLevel) {
29 switch (optLevel) {
30 case 0:
31 return OptimizationLevel::O0;
32
33 case 1:
34 return OptimizationLevel::O1;
35
36 case 2:
37 switch (sizeLevel) {
38 case 0:
39 return OptimizationLevel::O2;
40
41 case 1:
42 return OptimizationLevel::Os;
43
44 case 2:
45 return OptimizationLevel::Oz;
46 }
47 break;
48 case 3:
49 return OptimizationLevel::O3;
50 }
51 return std::nullopt;
52}
53// Create and return a lambda that uses LLVM pass manager builder to set up
54// optimizations based on the given level.
55std::function<Error(Module *)>
56mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
57 TargetMachine *targetMachine) {
58 return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
59 std::optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
60 if (!ol) {
61 return make_error<StringError>(
62 Args: formatv(Fmt: "invalid optimization/size level {0}/{1}", Vals: optLevel,
63 Vals: sizeLevel)
64 .str(),
65 Args: inconvertibleErrorCode());
66 }
67 LoopAnalysisManager lam;
68 FunctionAnalysisManager fam;
69 CGSCCAnalysisManager cgam;
70 ModuleAnalysisManager mam;
71
72 PipelineTuningOptions tuningOptions;
73 tuningOptions.LoopUnrolling = true;
74 tuningOptions.LoopInterleaving = true;
75 tuningOptions.LoopVectorization = true;
76 tuningOptions.SLPVectorization = true;
77
78 PassBuilder pb(targetMachine, tuningOptions);
79
80 pb.registerModuleAnalyses(MAM&: mam);
81 pb.registerCGSCCAnalyses(CGAM&: cgam);
82 pb.registerFunctionAnalyses(FAM&: fam);
83 pb.registerLoopAnalyses(LAM&: lam);
84 pb.crossRegisterProxies(LAM&: lam, FAM&: fam, CGAM&: cgam, MAM&: mam);
85
86 ModulePassManager mpm;
87 mpm.addPass(Pass: pb.buildPerModuleDefaultPipeline(Level: *ol));
88 mpm.run(IR&: *m, AM&: mam);
89 return Error::success();
90 };
91}
92

source code of mlir/lib/ExecutionEngine/OptUtils.cpp