Function optimization pass

This question has been submitted to stackoverflow () but someone suggested me that it should be submitted to llvm-dev mailing list instead. I’m sorry for the duplication.

I am trying to use PassBulider and FunctionPassManager ``to optimize a function in a module, what I have done is:

mod = …load module from LLVM IR bitcode file go_back.bc…

auto lift_func = mod->getFunction(“go_back”);
if (not lift_func) {
llvm::errs() << “Error: cannot get function\n”;
return 0;
}

auto pass_builder = llvm::PassBuilder{};
auto fa_manager = llvm::FunctionAnalysisManager{};

pass_builder.registerFunctionAnalyses(fa_manager);
auto fp_manager = pass_builder.buildFunctionSimplificationPipeline(llvm::PassBuilder::OptimizationLevel::O2);

fp_manager.run(*lift_func, fa_manager);

…print mod…

but the program crashes always at fp_manager.run. Strange enough, LLVM’s opt tool (which uses legacy optimization API) works without any problem, i.e if I run

opt -O2 go_back.bc -o go_back_o2.bc

then I get a new module where the (single) function go_back is optimized.

Many thanks for any response.

NB. The disassembled LLVM bitcode is at if anyone wants to take a look.

Can you tell us more about the crash? I.e., do you have a stack dump? Does it hit an assertion (if your LLVM is built in Debug mode/has assertions enabled)?

Generally, PassBuilder and passes likely assume a full stack of analysis managers. You should thus create and populate all of them, not just FunctionAM, and cross-register their proxies.

Cheers,
Philip

Hi Philip,

Thanks for the response. Under llvm-5.0.2 and llvm-6.0.1 in Debug mode, the crash hit at the same assertion:

/usr/local/include/llvm/IR/PassManager.h:689: typename PassT::Result& llvm::AnalysisManager<IRUnitT, ExtraArgTs>::getResult(IRUnitT&, ExtraArgTs …) [with PassT = llvm::InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::Function>; IRUnitT = llvm::Function; ExtraArgTs = {}; typename PassT::Result = llvm::InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::Function>::Result]: Assertion `AnalysisPasses.count(PassT::ID()) && “This analysis pass was not registered prior to being queried”’ failed.

I’m new to llvm optimization and I still don’t know which analysis managers should be created and populated in this case. Many thanks for any help.

I’ve managed somehow to pass the fp_manager.run using:

auto loop_manager = llvm::LoopAnalysisManager{};
auto cgscc_manager = llvm::CGSCCAnalysisManager{};
auto mod_manager = llvm::ModuleAnalysisManager{};

pass_builder.registerModuleAnalyses(mod_manager);
pass_builder.registerCGSCCAnalyses(cgscc_manager);
pass_builder.registerFunctionAnalyses(fa_manager);
pass_builder.registerLoopAnalyses(loop_manager);
pass_builder.crossRegisterProxies(loop_manager, fa_manager, cgscc_manager, mod_manager);

auto fp_manager = pass_builder.buildFunctionSimplificationPipeline(llvm::PassBuilder::OptimizationLevel::O2, llvm::PassBuilder::ThinLTOPhase::None, true);

fp_manager.run(*lift_func, fa_manager);

…print module…

but the program still crashes when the object fa_manager (of class FunctionAnalysisManager) is destroyed!!!

The managers need to be created in a specific order. I recommend checking out how the opt tool sets up its pipeline. Specifically the implementation of llvm::runPassPipeline.

Cheers,
Philip