使用现代LLVM运行默认优化管道 [英] Run default optimization pipeline using modern LLVM
问题描述
我正在使用LLVM 7,我有一个llvm::Module
,我想使用标准优化管道进行优化.不幸的是,我没有可以调用的llvm::runDefaultOptimizations
函数.似乎有无数种方法可以优化LLVM中的模块.我在此主题上进行的搜索发现了许多旧的/折旧的API,以及一些无法在我的系统上运行的示例.
I'm using LLVM 7 and I have an llvm::Module
that I'd like to optimize using the standard optimization pipeline. Unfortunately, there isn't a llvm::runDefaultOptimizations
function that I can call. There seems to be a bajillion ways to optimize a module in LLVM. My searches on this topic have found many old/depreciated APIs and some examples that don't work on my system.
我希望在-O3
上运行所有标准优化,并尽可能减少麻烦.我不想手动列出所有过程,甚至不想编写for循环.我以为llvm::PassBuilder::buildModuleOptimizationPipeline
可能是解决方案,但是当我尝试使用该功能时却收到了链接器错误,我认为这很奇怪.
I want to run all of the standard optimizations at -O3
with the least amount of hassle possible. I don't want to manually list all of the passes or even write a for loop. I thought llvm::PassBuilder::buildModuleOptimizationPipeline
might be the solution but I get a linker error when I try to use that function which I think is really strange.
推荐答案
I ended up taking the source of the opt
tool (found here) and stripping everything I didn't need. I ended up with this:
#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);
}
这大致等效于将-O3
传递给opt
.它正在使用某些legacy
内容,但我并不介意.
This is roughly equivalent to passing -O3
to opt
. It's using some legacy
stuff but I don't really mind.
这篇关于使用现代LLVM运行默认优化管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!