LLVM如何进行AOT编译

LLVM如何进行AOT编译,llvm,llvm-ir,Llvm,Llvm Ir,我正在尝试用LLVM创建一个玩具语言 目前,我可以用我的LLVM IR发出一个文件,但我不知道如何静态地将其编译成可执行文件。LLVM教程使用JIT编译,但我想进行AOT编译 如何执行此操作?如果已生成LLVM IR,则可以首先通过LLC编码生成IR到机器代码,然后将目标文件链接到可执行文件 如果您想通过命令行使用它,只需 clang yourIRFile.ll -o output 或 否则,您可以使用llc和lldapi。 (以下关键代码从其工具目录中的llc.cpp和lld.cpp中提取,

我正在尝试用LLVM创建一个玩具语言

目前,我可以用我的LLVM IR发出一个文件,但我不知道如何静态地将其编译成可执行文件。LLVM教程使用JIT编译,但我想进行AOT编译


如何执行此操作?

如果已生成LLVM IR,则可以首先通过LLC编码生成IR到机器代码,然后将目标文件链接到可执行文件

如果您想通过命令行使用它,只需

clang yourIRFile.ll -o output

否则,您可以使用
llc
lld
api。
(以下关键代码从其工具目录中的
llc.cpp
lld.cpp
中提取,所有代码均由本人验证)

首先,对于代码生成,使用目标机器通行证

legacy::PassManager pass;
auto CPU = "generic";
auto Features = "";
std::string Error;
auto Target = TargetRegistry::lookupTarget(module->getTargetTriple(), Error);
TheTargetMachine =
        Target->createTargetMachine(module->getTargetTriple(), CPU, Features, targetOptions, RM);
assert(TheTargetMachine && "Fail to create TheTargetMachine");

auto FileType = CGFT_ObjectFile;
SmallVector<char, 0> objStream;
std::unique_ptr<raw_svector_ostream> BOS = std::make_unique<raw_svector_ostream>(objStream);
auto OS = BOS.get();
if (TheTargetMachine->addPassesToEmitFile(pass, *OS, nullptr, FileType)) {
    errs() << "TheTargetMachine can't emit a file of this type";
    return;
}

// Here write the `objStream` content to a temp file you like.
// the objStream is the object file need by lld linker
legacy::PassManager pass;
自动CPU=“通用”;
汽车功能=”;
字符串错误;
自动目标=TargetRegistry::lookupTarget(模块->getTargetTriple(),错误);
目标机器=
目标->创建目标机器(模块->getTargetTriple(),CPU,功能,目标选项,RM);
断言(目标机器&“未能创建目标机器”);
自动文件类型=CGFT_对象文件;
小矢量objStream;
std::unique_ptr BOS=std::make_unique(objStream);
自动操作系统=BOS.get();
if(目标机器->添加密码发送文件(密码、*OS、空PTR、文件类型)){

errs()在你的
.ll
文件上使用
llc
。它会给你一个汇编文件。然后你可以使用像
as
这样的汇编程序来获得最终的可执行文件。使用
llc
你可以指定你想要的体系结构。
llc--version
给你一个支持的体系结构列表show我可以使用
lld::elf::link
-我应该包括哪些文件包括
。并确保您已安装
lld
或已编译它。
legacy::PassManager pass;
auto CPU = "generic";
auto Features = "";
std::string Error;
auto Target = TargetRegistry::lookupTarget(module->getTargetTriple(), Error);
TheTargetMachine =
        Target->createTargetMachine(module->getTargetTriple(), CPU, Features, targetOptions, RM);
assert(TheTargetMachine && "Fail to create TheTargetMachine");

auto FileType = CGFT_ObjectFile;
SmallVector<char, 0> objStream;
std::unique_ptr<raw_svector_ostream> BOS = std::make_unique<raw_svector_ostream>(objStream);
auto OS = BOS.get();
if (TheTargetMachine->addPassesToEmitFile(pass, *OS, nullptr, FileType)) {
    errs() << "TheTargetMachine can't emit a file of this type";
    return;
}

// Here write the `objStream` content to a temp file you like.
// the objStream is the object file need by lld linker
const char *emu_argv[] = {
        "ld.lld",
        objFileName,
        "-o",
        execFileName,
};
int argc = sizeof(emu_argv) / sizeof(emu_argv[0]);
const char **argv = (const char **) emu_argv;
std::vector<const char *> args(argv, argv + argc);
lld::elf::link(args, false, outs(), outs());