Skip to content

Commit

Permalink
Adapt the module optimization to use different version of LLVM PassMa…
Browse files Browse the repository at this point in the history
…nager API so that the code can work with multiple versions of LLVM.
  • Loading branch information
niyue committed Sep 27, 2023
1 parent 99d5c57 commit 6c514dc
Showing 1 changed file with 73 additions and 37 deletions.
110 changes: 73 additions & 37 deletions cpp/src/gandiva/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -302,49 +302,85 @@ Status Engine::RemoveUnusedFunctions() {
return Status::OK();
}

// several passes requiring LLVM 14+ that are not available in the legacy pass manager
#if LLVM_VERSION_MAJOR >= 14
static void OptimizeModuleWithNewPassManager(llvm::Module& module,
llvm::TargetIRAnalysis target_analysis) {
// Setup an optimiser pipeline
llvm::PassBuilder pass_builder;
llvm::LoopAnalysisManager loop_am;
llvm::FunctionAnalysisManager function_am;
llvm::CGSCCAnalysisManager cgscc_am;
llvm::ModuleAnalysisManager module_am;

function_am.registerPass([&] { return target_analysis; });

// Register required analysis managers
pass_builder.registerModuleAnalyses(module_am);
pass_builder.registerCGSCCAnalyses(cgscc_am);
pass_builder.registerFunctionAnalyses(function_am);
pass_builder.registerLoopAnalyses(loop_am);
pass_builder.crossRegisterProxies(loop_am, function_am, cgscc_am, module_am);

pass_builder.registerPipelineStartEPCallback([&](llvm::ModulePassManager& module_pm,
llvm::OptimizationLevel Level) {
module_pm.addPass(llvm::ModuleInlinerPass());

llvm::FunctionPassManager function_pm;
function_pm.addPass(llvm::InstCombinePass());
function_pm.addPass(llvm::PromotePass());
function_pm.addPass(llvm::GVNPass());
function_pm.addPass(llvm::NewGVNPass());
function_pm.addPass(llvm::SimplifyCFGPass());
function_pm.addPass(llvm::LoopVectorizePass());
function_pm.addPass(llvm::SLPVectorizerPass());
module_pm.addPass(llvm::createModuleToFunctionPassAdaptor(std::move(function_pm)));

module_pm.addPass(llvm::GlobalOptPass());
});

pass_builder.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3)
.run(module, module_am);
}
#else
static void OptimizeModuleWithLegacyPassManager(llvm::Module& module,
llvm::TargetIRAnalysis target_analysis) {
std::unique_ptr<llvm::legacy::PassManager> pass_manager(
new llvm::legacy::PassManager());

pass_manager->add(llvm::createTargetTransformInfoWrapperPass(target_analysis));
pass_manager->add(llvm::createFunctionInliningPass());
pass_manager->add(llvm::createInstructionCombiningPass());
pass_manager->add(llvm::createPromoteMemoryToRegisterPass());
pass_manager->add(llvm::createGVNPass());
pass_manager->add(llvm::createNewGVNPass());
pass_manager->add(llvm::createCFGSimplificationPass());
pass_manager->add(llvm::createLoopVectorizePass());
pass_manager->add(llvm::createSLPVectorizerPass());
pass_manager->add(llvm::createGlobalOptimizerPass());

// run the optimiser
llvm::PassManagerBuilder pass_builder;
pass_builder.OptLevel = 3;
pass_builder.populateModulePassManager(*pass_manager);
pass_manager->run(module);
}
#endif

// Optimise and compile the module.
Status Engine::FinalizeModule() {
if (!cached_) {
ARROW_RETURN_NOT_OK(RemoveUnusedFunctions());

if (optimize_) {
// Setup an optimiser pipeline
llvm::PassBuilder pass_builder;
llvm::LoopAnalysisManager loop_am;
llvm::FunctionAnalysisManager function_am;
llvm::CGSCCAnalysisManager cgscc_am;
llvm::ModuleAnalysisManager module_am;

function_am.registerPass(
[&] { return execution_engine_->getTargetMachine()->getTargetIRAnalysis(); });

// Register required analysis managers
pass_builder.registerModuleAnalyses(module_am);
pass_builder.registerCGSCCAnalyses(cgscc_am);
pass_builder.registerFunctionAnalyses(function_am);
pass_builder.registerLoopAnalyses(loop_am);
pass_builder.crossRegisterProxies(loop_am, function_am, cgscc_am, module_am);

pass_builder.registerPipelineStartEPCallback(
[&](llvm::ModulePassManager& module_pm, llvm::OptimizationLevel Level) {
module_pm.addPass(llvm::ModuleInlinerPass());

llvm::FunctionPassManager function_pm;
function_pm.addPass(llvm::InstCombinePass());
function_pm.addPass(llvm::PromotePass());
function_pm.addPass(llvm::GVNPass());
function_pm.addPass(llvm::NewGVNPass());
function_pm.addPass(llvm::SimplifyCFGPass());
function_pm.addPass(llvm::LoopVectorizePass());
function_pm.addPass(llvm::SLPVectorizerPass());
module_pm.addPass(
llvm::createModuleToFunctionPassAdaptor(std::move(function_pm)));

module_pm.addPass(llvm::GlobalOptPass());
});

pass_builder.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3)
.run(*module_, module_am);
auto target_analysis = execution_engine_->getTargetMachine()->getTargetIRAnalysis();

// misc passes to allow for inlining, vectorization, ..
#if LLVM_VERSION_MAJOR >= 14
OptimizeModuleWithNewPassManager(*module_, target_analysis);
#else
OptimizeModuleWithLegacyPassManager(*module_, target_analysis);
#endif
}

ARROW_RETURN_IF(llvm::verifyModule(*module_, &llvm::errs()),
Expand Down

0 comments on commit 6c514dc

Please sign in to comment.