直接通过 LLVM 生成机器代码 API
generate machine code directly via LLVM API
使用以下代码,我可以从模块生成 LLVM 位码文件:
llvm::Module * module;
// fill module with code
module = ...;
std::error_code ec;
llvm::raw_fd_ostream out("anonymous.bc", ec, llvm::sys::fs::F_None);
llvm::WriteBitcodeToFile(module, out);
然后我可以使用那个位码文件生成一个可执行的机器码文件,例如:
clang -o anonymous anonymous.bc
或者:
llc anonymous.bc
gcc -o anonymous anonymous.s
我现在的问题是:我可以直接在 C++ 中使用 LLVM API 生成机器代码,而无需先编写位代码文件吗?
我正在寻找 代码示例 或至少 LLVM API 中的一些起点,例如类 使用哪个,将我推向正确的方向甚至可能就足够了。
看看 llc tool source,特别是 compileModule()
函数。简而言之,它创建 Target
,通过 TargetOptions
为其设置一些选项,然后将其用于 addPassesToEmitFile()
,最后要求 PassManager
执行所有计划任务。
我也在找代码,@arrowd 的建议奏效了。
为了给下一个人省去麻烦,我想出了这个办法。
给定一个模块,它会在标准输出上为您的本机目标生成汇编代码:
void printASM(Module *M) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
auto TargetTriple = sys::getDefaultTargetTriple();
M->setTargetTriple(TargetTriple);
std::string Error;
const Target *target = TargetRegistry::lookupTarget(TargetTriple, Error);
auto cpu = sys::getHostCPUName();
SubtargetFeatures Features;
StringMap<bool> HostFeatures;
if (sys::getHostCPUFeatures(HostFeatures))
for (auto &F : HostFeatures)
Features.AddFeature(F.first(), F.second);
auto features = Features.getString();
TargetOptions Options;
std::unique_ptr<TargetMachine> TM{
target->createTargetMachine(
TargetTriple, cpu, features, Options,
Reloc::PIC_, None, CodeGenOpt::None)
};
legacy::PassManager PM;
M->setDataLayout(TM->createDataLayout());
TM->addPassesToEmitFile(PM, (raw_pwrite_stream &) outs(), (raw_pwrite_stream *) (&outs()),
TargetMachine::CodeGenFileType::CGFT_AssemblyFile, true, nullptr);
PM.run(*M);
}
如果有人知道编写此代码的更短方法,请随时纠正我!
使用以下代码,我可以从模块生成 LLVM 位码文件:
llvm::Module * module;
// fill module with code
module = ...;
std::error_code ec;
llvm::raw_fd_ostream out("anonymous.bc", ec, llvm::sys::fs::F_None);
llvm::WriteBitcodeToFile(module, out);
然后我可以使用那个位码文件生成一个可执行的机器码文件,例如:
clang -o anonymous anonymous.bc
或者:
llc anonymous.bc
gcc -o anonymous anonymous.s
我现在的问题是:我可以直接在 C++ 中使用 LLVM API 生成机器代码,而无需先编写位代码文件吗?
我正在寻找 代码示例 或至少 LLVM API 中的一些起点,例如类 使用哪个,将我推向正确的方向甚至可能就足够了。
看看 llc tool source,特别是 compileModule()
函数。简而言之,它创建 Target
,通过 TargetOptions
为其设置一些选项,然后将其用于 addPassesToEmitFile()
,最后要求 PassManager
执行所有计划任务。
我也在找代码,@arrowd 的建议奏效了。
为了给下一个人省去麻烦,我想出了这个办法。
给定一个模块,它会在标准输出上为您的本机目标生成汇编代码:
void printASM(Module *M) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
auto TargetTriple = sys::getDefaultTargetTriple();
M->setTargetTriple(TargetTriple);
std::string Error;
const Target *target = TargetRegistry::lookupTarget(TargetTriple, Error);
auto cpu = sys::getHostCPUName();
SubtargetFeatures Features;
StringMap<bool> HostFeatures;
if (sys::getHostCPUFeatures(HostFeatures))
for (auto &F : HostFeatures)
Features.AddFeature(F.first(), F.second);
auto features = Features.getString();
TargetOptions Options;
std::unique_ptr<TargetMachine> TM{
target->createTargetMachine(
TargetTriple, cpu, features, Options,
Reloc::PIC_, None, CodeGenOpt::None)
};
legacy::PassManager PM;
M->setDataLayout(TM->createDataLayout());
TM->addPassesToEmitFile(PM, (raw_pwrite_stream &) outs(), (raw_pwrite_stream *) (&outs()),
TargetMachine::CodeGenFileType::CGFT_AssemblyFile, true, nullptr);
PM.run(*M);
}
如果有人知道编写此代码的更短方法,请随时纠正我!