链接时LLVM IR类型错误折叠(C++ API)

5
直截了当地说,我正在尝试将两个(或更多)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*),但传递的参数(arg. 1)仍然是类型为%2。发生了什么?

请注意,在模块A中,无论发生什么情况,都会正确执行,没有错误。这种情况发生在许多函数中,但只发生在模块C中。

我尝试通过复制这些.ll文件并调用llvm-linkllvm-dis来重现它,但是1.类型没有合并,2.没有这样的错误。

谢谢...?


你尝试过禁用所有优化吗?如果使用不同的优化,会有什么不同吗?当我遇到奇怪的错误时,我首先怀疑的是优化处理对我的代码造成的影响。 - Fee
我禁用了所有的优化处理。我找到了一个解决方案,我会将其编辑到问题中。 - zhiayang
1个回答

1
好的,事实证明,在llvm IRC频道中探索后,llvm::Linker应该使用一个空的llvm::Module作为起始模块。

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

因此,问题通过使用空模块作为传递给链接器的起始点来解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接