使用现代LLVM运行默认优化管道

时间:2018-12-12 08:27:45

标签: c++ clang llvm llvm-c++-api

我正在使用LLVM 7,我有一个llvm::Module,我想使用标准优化管道进行优化。不幸的是,没有一个我可以调用的llvm::runDefaultOptimizations函数。在LLVM中似乎有无数种优化模块的方法。我在该主题上进行的搜索发现了许多旧的/折旧的API,以及一些无法在我的系统上运行的示例。

我希望在-O3上运行所有标准优化,并尽可能减少麻烦。我不想手动列出所有过程,甚至不想编写for循环。我以为llvm::PassBuilder::buildModuleOptimizationPipeline可能是解决方案,但是当我尝试使用我认为确实很奇怪的函数时遇到链接器错误。

2 个答案:

答案 0 :(得分:2)

我最终使用了#sidebar.active工具(found here)的源,并剥离了我不需要的所有内容。我结束了:

#sidebar.active {
    margin-left: -250px;
}

这大致相当于将@media (max-width: 768px) { #sidebar.active { margin-left: 0; } } 传递给opt。它正在使用一些#include <llvm/IR/Verifier.h> #include <llvm/Transforms/IPO.h> #include <llvm/IR/LegacyPassManager.h> #include <llvm/Target/TargetMachine.h> #include <llvm/Analysis/TargetLibraryInfo.h> #include <llvm/Analysis/TargetTransformInfo.h> #include <llvm/Transforms/IPO/PassManagerBuilder.h> namespace { void addOptPasses( llvm::legacy::PassManagerBase &passes, llvm::legacy::FunctionPassManager &fnPasses, llvm::TargetMachine *machine ) { llvm::PassManagerBuilder builder; builder.OptLevel = 3; builder.SizeLevel = 0; builder.Inliner = llvm::createFunctionInliningPass(3, 0, false); builder.LoopVectorize = true; builder.SLPVectorize = true; machine->adjustPassManager(builder); builder.populateFunctionPassManager(fnPasses); builder.populateModulePassManager(passes); } void addLinkPasses(llvm::legacy::PassManagerBase &passes) { llvm::PassManagerBuilder builder; builder.VerifyInput = true; builder.Inliner = llvm::createFunctionInliningPass(3, 0, false); builder.populateLTOPassManager(passes); } } void optimizeModule(llvm::TargetMachine *machine, llvm::Module *module) { module->setTargetTriple(machine->getTargetTriple().str()); module->setDataLayout(machine->createDataLayout()); llvm::legacy::PassManager passes; passes.add(new llvm::TargetLibraryInfoWrapperPass(machine->getTargetTriple())); passes.add(llvm::createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); llvm::legacy::FunctionPassManager fnPasses(module); fnPasses.add(llvm::createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); addOptPasses(passes, fnPasses, machine); addLinkPasses(passes); fnPasses.doInitialization(); for (llvm::Function &func : *module) { fnPasses.run(func); } fnPasses.doFinalization(); passes.add(llvm::createVerifierPass()); passes.run(*module); } 东西,但我并不介意。

答案 1 :(得分:1)

要查看LLVM的标准通行证,可以尝试 检查Pass接口的子类。据我所知,在LLVM API本身中没有运行Clang特定过程的过程。为此,您必须看看c声。

要弄清楚要添加的通行证,请查看

llvm-as < /dev/null | opt -O3 -disable-output -debug-pass=Arguments  

请参见Where to find the optimization sequence for clang -OX?

仍然有一些麻烦,找到您使用的API等等。同样适用于Clang -O3。

如果可能的话,您可以做的是将LLVM IR生成到磁盘上,然后使用O3标志分别用clang编译未经优化的LLVM IR。

这是您可以使用旧版通行证管理器运行某些通行证的方式。假设您有一个LLVM上下文。

 module = llvm::make_unique<llvm::Module>("module",context); //Context is your LLVM context.
 functionPassMngr = llvm::make_unique<llvm::legacy::FunctionPassManager>(module.get());
 functionPassMngr->add(llvm::createPromoteMemoryToRegisterPass()); //SSA conversion
 functionPassMngr->add(llvm::createCFGSimplificationPass()); //Dead code elimination
 functionPassMngr->add(llvm::createSROAPass());
 functionPassMngr->add(llvm::createLoopSimplifyCFGPass());
 functionPassMngr->add(llvm::createConstantPropagationPass());
 functionPassMngr->add(llvm::createNewGVNPass());//Global value numbering
 functionPassMngr->add(llvm::createReassociatePass());
 functionPassMngr->add(llvm::createPartiallyInlineLibCallsPass()); //Inline standard calls
 functionPassMngr->add(llvm::createDeadCodeEliminationPass());
 functionPassMngr->add(llvm::createCFGSimplificationPass()); //Cleanup
 functionPassMngr->add(llvm::createInstructionCombiningPass());
 functionPassMngr->add(llvm::createFlattenCFGPass()); //Flatten the control flow graph.

然后可以由

运行
functionPassMngr->run(getLLVMFunc());

如果getLLVMFunc返回当前正在生成的llvm :: Function *。请注意,我在这里使用旧版通行管理器,原因是clang在内部使用旧版通行管理器。

相关问题