【问题标题】:LLVM IR types being collapsed wrongly when linking (C++ API)链接时错误折叠 LLVM IR 类型(C++ API)
【发布时间】:2016-06-12 21:26:54
【问题描述】:

直截了当——我正在尝试将两个(或更多)llvm 模块链接在一起,我正面临来自 LLVM 的某个奇怪错误。

不想贴太多代码,这里就用一堆伪代码。

我有 3 个模块,比如说 A、B 和 C。A 是主要模块;我用它初始化llvm::Linker。 B、C为二级模块;我打电话给linker.linkInModule(B and C)

除其他外,所有 3 个模块都定义了这两种类型:

%String = type { i8*, i64 }
%Character = type { i8*, i64 }

请注意,它们具有相同的成员类型。此外,函数foo 是这样定义的(在模块B中):

define i1 @_ZN9Character7hasDataEv(%Character*) { }

这个函数在模块 A 和 C 中声明。现在,一切看起来都很好——这个函数是从模块 A 和 C 中调用的,IR 看起来很正常,如下所示:

%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)

问题来了:当所有 3 个模块链接在一起时,这些类型会发生一些事情:

  1. 他们失去了自己的名字,变成了%2 (%String) 和%3 (%Character)。
  2. 它们似乎合并在一起了。

奇怪的是,虽然这种转换发生在模块 A 和 C 中,但错误只出现在 C 中——注意 A 是所谓的“主”模块。

现在链接文件的函数定义是

define i1 @_ZN9Character7hasDataEv(%2*)

注意%Character%3 是如何变成%2 的。此外,在调用站点,大概是试图取消合并类型,我得到了这个:

%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2)

奇怪的是,虽然函数从i1 (%2*) 转换为%3 (%2*),但传递的参数(参数1)仍然是%2 类型。怎么回事?

请注意,在模块 A 中,无论发生什么都正确完成,并且没有错误。这发生在许多函数中,但仅在模块 C 中。

我尝试通过将这些复制粘贴到.ll 文件并调用llvm-link 后跟llvm-dis 来复制它,但是1. 类型没有合并,2. 没有这样的错误。

谢谢...?

【问题讨论】:

  • 您是否尝试禁用所有优化?如果您使用不同的优化,会有什么不同吗?如果我遇到奇怪的错误,我首先怀疑的是优化过程会弄乱我的代码。
  • 我禁用了所有优化通道。我确实找到了解决方案,我会将其编辑到问题中。

标签: c++ llvm llvm-ir llvm-c++-api


【解决方案1】:

好吧,事实证明,在 llvm IRC 频道中四处寻找之后,llvm::Linker 本来是要与一个空的 llvm::Module 一起使用作为起始模块。

此外,在我的用例中,我在链接在一起的不同模块中重复使用相同的 llvm::Type(内存中的实际内容)。他们说这并不违法,但从未经过测试,所以...¯\_(ツ)_/¯

所以无论如何,问题是通过从一个空模块开始传递给链接器来解决的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多