【问题标题】:LLVM how to do AOT compilationLLVM如何做AOT编译
【发布时间】:2020-07-25 18:24:07
【问题描述】:

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

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

我该怎么做?

【问题讨论】:

  • 在您的 .ll 文件上使用 llc。它会给你汇编文件。然后,您可以使用像 as 这样的汇编程序来获取最终的可执行文件。使用llc,您可以指定您想要的架构。 llc --version 为您提供支持的架构列表

标签: llvm llvm-ir


【解决方案1】:

如果你已经生成了 LLVM IR,你可以先通过 LLC 将 IR 生成机器码,然后将目标文件链接到可执行文件。

如果你想通过命令行使用它,事情就简单了

clang yourIRFile.ll -o output

llc yourIRFile.ll --filetype=obj
lld generatedObjFileName.o -o output

否则,您可以使用 llclld api。
(以下关键代码摘自其tools目录llc.cpplld.cpp,所有代码均由本人验证)

首先,对于代码生成,使用target machine pass by

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

然后使用 lld 链接器

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());

objFileName 是您在 codegen 生成的文件。 最后,execFileName 是最终的可执行文件。

【讨论】:

  • 我如何使用lld::elf::link -- 我包含什么文件
  • 包括&lt;lld/Common/Driver.h&gt;。并确保您已安装lld 或编译它。
猜你喜欢
  • 1970-01-01
  • 2019-03-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 2020-01-19
  • 1970-01-01
相关资源
最近更新 更多