[Mlir-commits] [mlir] b0f7f6f - [mlir] Remove uses of LLVM's legacy pass manager

Arthur Eubanks llvmlistbot at llvm.org
Mon Apr 11 16:19:24 PDT 2022


Author: Arthur Eubanks
Date: 2022-04-11T16:18:45-07:00
New Revision: b0f7f6f78d050cc89b31c87fb48744989145af60

URL: https://github.com/llvm/llvm-project/commit/b0f7f6f78d050cc89b31c87fb48744989145af60
DIFF: https://github.com/llvm/llvm-project/commit/b0f7f6f78d050cc89b31c87fb48744989145af60.diff

LOG: [mlir] Remove uses of LLVM's legacy pass manager

Use the new pass manager.

This also removes the ability to run arbitrary sets of passes. Not sure if this functionality is used, but it doesn't seem to be tested.

No need to initialize passes outside of constructing the PassBuilder with the new pass manager.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D123425

Added: 
    

Modified: 
    mlir/include/mlir/ExecutionEngine/OptUtils.h
    mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
    mlir/lib/ExecutionEngine/CMakeLists.txt
    mlir/lib/ExecutionEngine/JitRunner.cpp
    mlir/lib/ExecutionEngine/OptUtils.cpp
    mlir/tools/mlir-cpu-runner/mlir-cpu-runner.cpp
    mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp
    mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/ExecutionEngine/OptUtils.h b/mlir/include/mlir/ExecutionEngine/OptUtils.h
index b5c4e2d3b3005..4cee8c6d60ff1 100644
--- a/mlir/include/mlir/ExecutionEngine/OptUtils.h
+++ b/mlir/include/mlir/ExecutionEngine/OptUtils.h
@@ -14,8 +14,6 @@
 #ifndef MLIR_EXECUTIONENGINE_OPTUTILS_H
 #define MLIR_EXECUTIONENGINE_OPTUTILS_H
 
-#include "llvm/Pass.h"
-
 #include <functional>
 #include <string>
 
@@ -27,10 +25,6 @@ class TargetMachine;
 
 namespace mlir {
 
-/// Initialize LLVM passes that can be used when running MLIR code using
-/// ExecutionEngine.
-void initializeLLVMPasses();
-
 /// Create a module transformer function for MLIR ExecutionEngine that runs
 /// LLVM IR passes corresponding to the given speed and size optimization
 /// levels (e.g. -O2 or -Os). If not null, `targetMachine` is used to
@@ -40,18 +34,6 @@ std::function<llvm::Error(llvm::Module *)>
 makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
                           llvm::TargetMachine *targetMachine);
 
-/// Create a module transformer function for MLIR ExecutionEngine that runs
-/// LLVM IR passes explicitly specified, plus an optional optimization level,
-/// Any optimization passes, if present, will be inserted before the pass at
-/// position optPassesInsertPos. If not null, `targetMachine` is used to
-/// initialize passes that provide target-specific information to the LLVM
-/// optimizer. `targetMachine` must outlive the returned std::function.
-std::function<llvm::Error(llvm::Module *)>
-makeLLVMPassesTransformer(llvm::ArrayRef<const llvm::PassInfo *> llvmPasses,
-                          llvm::Optional<unsigned> mbOptLevel,
-                          llvm::TargetMachine *targetMachine,
-                          unsigned optPassesInsertPos = 0);
-
 } // namespace mlir
 
 #endif // MLIR_EXECUTIONENGINE_OPTUTILS_H

diff  --git a/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
index 4c55530870df7..2190566b22b13 100644
--- a/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/CAPI/ExecutionEngine/ExecutionEngine.cpp
@@ -48,8 +48,8 @@ mlirExecutionEngineCreate(MlirModule op, int optLevel, int numPaths,
   // Create a transformer to run all LLVM optimization passes at the
   // specified optimization level.
   auto llvmOptLevel = static_cast<llvm::CodeGenOpt::Level>(optLevel);
-  auto transformer = mlir::makeLLVMPassesTransformer(
-      /*passes=*/{}, llvmOptLevel, /*targetMachine=*/tmOrError->get());
+  auto transformer = mlir::makeOptimizingTransformer(
+      llvmOptLevel, /*sizeLevel=*/0, /*targetMachine=*/tmOrError->get());
   ExecutionEngineOptions jitOptions;
   jitOptions.transformer = transformer;
   jitOptions.jitCodeGenOptLevel = llvmOptLevel;

diff  --git a/mlir/lib/ExecutionEngine/CMakeLists.txt b/mlir/lib/ExecutionEngine/CMakeLists.txt
index 8776d6f7e5d8f..e1f30470a9fd6 100644
--- a/mlir/lib/ExecutionEngine/CMakeLists.txt
+++ b/mlir/lib/ExecutionEngine/CMakeLists.txt
@@ -52,6 +52,7 @@ add_mlir_library(MLIRExecutionEngine
   TransformUtils
   nativecodegen
   IPO
+  Passes
   ${LLVM_JIT_LISTENER_LIB}
 
   LINK_LIBS PUBLIC

diff  --git a/mlir/lib/ExecutionEngine/JitRunner.cpp b/mlir/lib/ExecutionEngine/JitRunner.cpp
index f61710f390acd..5e738002728dd 100644
--- a/mlir/lib/ExecutionEngine/JitRunner.cpp
+++ b/mlir/lib/ExecutionEngine/JitRunner.cpp
@@ -57,10 +57,6 @@ struct Options {
 
   llvm::cl::OptionCategory optFlags{"opt-like flags"};
 
-  // CLI list of pass information
-  llvm::cl::list<const llvm::PassInfo *, bool, llvm::PassNameParser> llvmPasses{
-      llvm::cl::desc("LLVM optimizing passes to run"), llvm::cl::cat(optFlags)};
-
   // CLI variables for -On options.
   llvm::cl::opt<bool> optO0{"O0",
                             llvm::cl::desc("Run opt passes and codegen at O0"),
@@ -322,27 +318,6 @@ int mlir::JitRunnerMain(int argc, char **argv, const DialectRegistry &registry,
   Optional<unsigned> optLevel = getCommandLineOptLevel(options);
   SmallVector<std::reference_wrapper<llvm::cl::opt<bool>>, 4> optFlags{
       options.optO0, options.optO1, options.optO2, options.optO3};
-  unsigned optCLIPosition = 0;
-  // Determine if there is an optimization flag present, and its CLI position
-  // (optCLIPosition).
-  for (unsigned j = 0; j < 4; ++j) {
-    auto &flag = optFlags[j].get();
-    if (flag) {
-      optCLIPosition = flag.getPosition();
-      break;
-    }
-  }
-  // Generate vector of pass information, plus the index at which we should
-  // insert any optimization passes in that vector (optPosition).
-  SmallVector<const llvm::PassInfo *, 4> passes;
-  unsigned optPosition = 0;
-  for (unsigned i = 0, e = options.llvmPasses.size(); i < e; ++i) {
-    passes.push_back(options.llvmPasses[i]);
-    if (optCLIPosition < options.llvmPasses.getPosition(i)) {
-      optPosition = i;
-      optCLIPosition = UINT_MAX; // To ensure we never insert again
-    }
-  }
 
   MLIRContext context(registry);
 
@@ -367,11 +342,11 @@ int mlir::JitRunnerMain(int argc, char **argv, const DialectRegistry &registry,
     return EXIT_FAILURE;
   }
 
-  auto transformer = mlir::makeLLVMPassesTransformer(
-      passes, optLevel, /*targetMachine=*/tmOrError->get(), optPosition);
-
   CompileAndExecuteConfig compileAndExecuteConfig;
-  compileAndExecuteConfig.transformer = transformer;
+  if (optLevel) {
+    compileAndExecuteConfig.transformer = mlir::makeOptimizingTransformer(
+        *optLevel, /*sizeLevel=*/0, /*targetMachine=*/tmOrError->get());
+  }
   compileAndExecuteConfig.llvmModuleBuilder = config.llvmModuleBuilder;
   compileAndExecuteConfig.runtimeSymbolMap = config.runtimesymbolMap;
 

diff  --git a/mlir/lib/ExecutionEngine/OptUtils.cpp b/mlir/lib/ExecutionEngine/OptUtils.cpp
index 53ad7fd66a9af..33b52aadf9c48 100644
--- a/mlir/lib/ExecutionEngine/OptUtils.cpp
+++ b/mlir/lib/ExecutionEngine/OptUtils.cpp
@@ -13,135 +13,76 @@
 
 #include "mlir/ExecutionEngine/OptUtils.h"
 
-#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LegacyPassNameParser.h"
 #include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Coroutines.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include <climits>
-#include <mutex>
 
-// Run the module and function passes managed by the module manager.
-static void runPasses(llvm::legacy::PassManager &modulePM,
-                      llvm::legacy::FunctionPassManager &funcPM,
-                      llvm::Module &m) {
-  funcPM.doInitialization();
-  for (auto &func : m) {
-    funcPM.run(func);
-  }
-  funcPM.doFinalization();
-  modulePM.run(m);
-}
+using namespace llvm;
 
-// Initialize basic LLVM transformation passes under lock.
-void mlir::initializeLLVMPasses() {
-  static std::mutex mutex;
-  std::lock_guard<std::mutex> lock(mutex);
+static Optional<OptimizationLevel> mapToLevel(unsigned optLevel,
+                                              unsigned sizeLevel) {
+  switch (optLevel) {
+  case 0:
+    return OptimizationLevel::O0;
 
-  auto &registry = *llvm::PassRegistry::getPassRegistry();
-  llvm::initializeCore(registry);
-  llvm::initializeTransformUtils(registry);
-  llvm::initializeScalarOpts(registry);
-  llvm::initializeIPO(registry);
-  llvm::initializeInstCombine(registry);
-  llvm::initializeAggressiveInstCombine(registry);
-  llvm::initializeAnalysis(registry);
-  llvm::initializeVectorization(registry);
-  llvm::initializeCoroutines(registry);
-}
+  case 1:
+    return OptimizationLevel::O1;
 
-// Populate pass managers according to the optimization and size levels.
-// This behaves similarly to LLVM opt.
-static void populatePassManagers(llvm::legacy::PassManager &modulePM,
-                                 llvm::legacy::FunctionPassManager &funcPM,
-                                 unsigned optLevel, unsigned sizeLevel,
-                                 llvm::TargetMachine *targetMachine) {
-  llvm::PassManagerBuilder builder;
-  builder.OptLevel = optLevel;
-  builder.SizeLevel = sizeLevel;
-  builder.Inliner = llvm::createFunctionInliningPass(
-      optLevel, sizeLevel, /*DisableInlineHotCallSite=*/false);
-  builder.LoopVectorize = optLevel > 1 && sizeLevel < 2;
-  builder.SLPVectorize = optLevel > 1 && sizeLevel < 2;
-  builder.DisableUnrollLoops = (optLevel == 0);
+  case 2:
+    switch (sizeLevel) {
+    case 0:
+      return OptimizationLevel::O2;
 
-  // Add all coroutine passes to the builder.
-  addCoroutinePassesToExtensionPoints(builder);
+    case 1:
+      return OptimizationLevel::Os;
 
-  if (targetMachine) {
-    // Add pass to initialize TTI for this specific target. Otherwise, TTI will
-    // be initialized to NoTTIImpl by default.
-    modulePM.add(createTargetTransformInfoWrapperPass(
-        targetMachine->getTargetIRAnalysis()));
-    funcPM.add(createTargetTransformInfoWrapperPass(
-        targetMachine->getTargetIRAnalysis()));
-  }
+    case 2:
+      return OptimizationLevel::Oz;
+    }
 
-  builder.populateModulePassManager(modulePM);
-  builder.populateFunctionPassManager(funcPM);
+  case 3:
+    return OptimizationLevel::O3;
+  }
+  return None;
 }
-
 // Create and return a lambda that uses LLVM pass manager builder to set up
 // optimizations based on the given level.
-std::function<llvm::Error(llvm::Module *)>
+std::function<Error(Module *)>
 mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
-                                llvm::TargetMachine *targetMachine) {
-  return [optLevel, sizeLevel, targetMachine](llvm::Module *m) -> llvm::Error {
-    llvm::legacy::PassManager modulePM;
-    llvm::legacy::FunctionPassManager funcPM(m);
-    populatePassManagers(modulePM, funcPM, optLevel, sizeLevel, targetMachine);
-    runPasses(modulePM, funcPM, *m);
-
-    return llvm::Error::success();
-  };
-}
-
-// Create and return a lambda that is given a set of passes to run, plus an
-// optional optimization level to pre-populate the pass manager.
-std::function<llvm::Error(llvm::Module *)> mlir::makeLLVMPassesTransformer(
-    llvm::ArrayRef<const llvm::PassInfo *> llvmPasses,
-    llvm::Optional<unsigned> mbOptLevel, llvm::TargetMachine *targetMachine,
-    unsigned optPassesInsertPos) {
-  return [llvmPasses, mbOptLevel, optPassesInsertPos,
-          targetMachine](llvm::Module *m) -> llvm::Error {
-    llvm::legacy::PassManager modulePM;
-    llvm::legacy::FunctionPassManager funcPM(m);
-
-    bool insertOptPasses = mbOptLevel.hasValue();
-    for (unsigned i = 0, e = llvmPasses.size(); i < e; ++i) {
-      const auto *passInfo = llvmPasses[i];
-      if (!passInfo->getNormalCtor())
-        continue;
-
-      if (insertOptPasses && optPassesInsertPos == i) {
-        populatePassManagers(modulePM, funcPM, mbOptLevel.getValue(), 0,
-                             targetMachine);
-        insertOptPasses = false;
-      }
-
-      auto *pass = passInfo->createPass();
-      if (!pass)
-        return llvm::make_error<llvm::StringError>(
-            "could not create pass " + passInfo->getPassName(),
-            llvm::inconvertibleErrorCode());
-      modulePM.add(pass);
+                                TargetMachine *targetMachine) {
+  return [optLevel, sizeLevel, targetMachine](Module *m) -> Error {
+    Optional<OptimizationLevel> ol = mapToLevel(optLevel, sizeLevel);
+    if (!ol) {
+      return make_error<StringError>(
+          formatv("invalid optimization/size level {0}/{1}", optLevel,
+                  sizeLevel)
+              .str(),
+          inconvertibleErrorCode());
     }
-
-    if (insertOptPasses)
-      populatePassManagers(modulePM, funcPM, mbOptLevel.getValue(), 0,
-                           targetMachine);
-
-    runPasses(modulePM, funcPM, *m);
-    return llvm::Error::success();
+    LoopAnalysisManager lam;
+    FunctionAnalysisManager fam;
+    CGSCCAnalysisManager cgam;
+    ModuleAnalysisManager mam;
+
+    PassBuilder pb(targetMachine);
+
+    pb.registerModuleAnalyses(mam);
+    pb.registerCGSCCAnalyses(cgam);
+    pb.registerFunctionAnalyses(fam);
+    pb.registerLoopAnalyses(lam);
+    pb.crossRegisterProxies(lam, fam, cgam, mam);
+
+    ModulePassManager mpm;
+    if (*ol == OptimizationLevel::O0)
+      mpm.addPass(pb.buildO0DefaultPipeline(*ol));
+    else
+      mpm.addPass(pb.buildPerModuleDefaultPipeline(*ol));
+
+    mpm.run(*m, mam);
+    return Error::success();
   };
 }

diff  --git a/mlir/tools/mlir-cpu-runner/mlir-cpu-runner.cpp b/mlir/tools/mlir-cpu-runner/mlir-cpu-runner.cpp
index b1009a1fae458..1b1d5d03d2be5 100644
--- a/mlir/tools/mlir-cpu-runner/mlir-cpu-runner.cpp
+++ b/mlir/tools/mlir-cpu-runner/mlir-cpu-runner.cpp
@@ -26,7 +26,6 @@ int main(int argc, char **argv) {
   llvm::InitializeNativeTarget();
   llvm::InitializeNativeTargetAsmPrinter();
   llvm::InitializeNativeTargetAsmParser();
-  mlir::initializeLLVMPasses();
 
   mlir::DialectRegistry registry;
   mlir::registerAllToLLVMIRTranslations(registry);

diff  --git a/mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp b/mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp
index ee2c4be2574b8..fb51af9002e12 100644
--- a/mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp
+++ b/mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp
@@ -90,7 +90,6 @@ int main(int argc, char **argv) {
 
   llvm::InitializeNativeTarget();
   llvm::InitializeNativeTargetAsmPrinter();
-  mlir::initializeLLVMPasses();
 
   mlir::JitRunnerConfig jitRunnerConfig;
   jitRunnerConfig.mlirTransformer = runMLIRPasses;

diff  --git a/mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp b/mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp
index 972292954663b..6d0edda7feb9b 100644
--- a/mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp
+++ b/mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp
@@ -67,7 +67,6 @@ int main(int argc, char **argv) {
   llvm::InitLLVM y(argc, argv);
   llvm::InitializeNativeTarget();
   llvm::InitializeNativeTargetAsmPrinter();
-  mlir::initializeLLVMPasses();
 
   mlir::JitRunnerConfig jitRunnerConfig;
   jitRunnerConfig.mlirTransformer = runMLIRPasses;


        


More information about the Mlir-commits mailing list