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 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 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 *)> 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