【问题标题】:what is the right abstraction for compilation unit in LLVM?LLVM 中编译单元的正确抽象是什么?
【发布时间】:2012-03-23 16:47:39
【问题描述】:

在 LLVM 中,LLVMContext 是存储单元,llvm::Module 是构建新符号(函数和类型)的地方。

我的问题是;用于编译单元的正确 llvm 抽象是什么?是Module?还是这实际上意味着更大的范围,即:共享库目标

在我看来,编译单元必须满足全有或全无的结果;它要么编译所有内容而没有错误,要么存在错误并且需要在 CU 中的任何符号可用之前对其进行修复和重新构建。在我看来,这是编译单元应该代表什么的定义

如果模块是 CU 的正确抽象,我如何将其他(正确编译的)Module 对象中的符号呈现给即将构建的新模块,以便它能够找到那些?我需要添加声明还是有其他加速方法?

指向clang 中的相关行会很有帮助

【问题讨论】:

  • 您描述的是链接器问题,而不是编译器问题。 clang 本身与此无关。您需要查看 LLVM 中的链接位。
  • 并非所有符号解析都可以延迟到链接阶段,特别是在类型的情况下。在任何情况下,我都关心 llvm - 我只提到 clang,因为它是规范的客户端示例
  • 理想情况下,您永远不会将编译单元作为任何编译器的一部分。因此,我认为它们没有正确的抽象。
  • @DeadMG,你能详细说明你的断言吗?你的意思是'CU不应该成为任何编译器的一部分'?
  • 我在另一个问题中添加了更多上下文:stackoverflow.com/q/9934790/170521

标签: c++ compilation llvm llvm-clang incremental-compiler


【解决方案1】:

模块是编译单元的正确抽象。您可以将模块链接在一起,从那里进行整个程序分析。

【讨论】:

    【解决方案2】:

    这是一个正在进行的尝试回答我自己的问题:

    llvm::Linker 类能够获取多个模块并返回一个包含现有模块中所有符号的复合模块。完成链接并创建复合模块后,我仍然不清楚有关输入模块所有权的规则是什么。

    在任何情况下,该类都应该允许您采用增量路径来扩展模块。假设您正在尝试实现 REPL,这意味着您将新符号添加到全局命名空间:

    REPL 的大纲如下:

    • 在 REPL 中编写一些函数
    • 将函数编译为单个模块,称之为“基础”
    • 在 REPL 中编写更多函数
    • 在新模块中编译新函数
    • 如果新功能模块编译成功,将“base”和新模块链接在一个新模块中,命名为“base.2”
    • 冲洗并重复

      如果您按名称替换符号或函数,您希望旧符号看到符号的覆盖版本。所以当你定义一个新函数时,你需要确保你的getOrInsertFunction在现有的“基础”模块以及新的模块中被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多