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

zhi*_*ang 5 c++ llvm llvm-ir llvm-c++-api

直截了当 - 我正在尝试将两个(或更多)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 }
Run Code Online (Sandbox Code Playgroud)

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

define i1 @_ZN9Character7hasDataEv(%Character*) { }
Run Code Online (Sandbox Code Playgroud)

这个函数在模块A和C中声明.现在,一切看起来都很好 - 从模块A和C调用此函数,并且IR看起来很正常,如下所示:

%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)
Run Code Online (Sandbox Code Playgroud)

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

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

奇怪的是,虽然这种转换发生在模块A和C中,但这种错误只发生在C中 - 注意A是所谓的"主"模块.

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

define i1 @_ZN9Character7hasDataEv(%2*)
Run Code Online (Sandbox Code Playgroud)

注意如何%Character,或者%3,变成了%2.此外,在呼叫网站,可能是尝试取消合并类型,我得到了这个:

%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2)
Run Code Online (Sandbox Code Playgroud)

奇怪的是,虽然函数是从中传来i1 (%2*)%3 (%2*),但是传递的参数(arg.1)仍然是类型%2.这是怎么回事?

请注意,在模块A中,正在进行的任何操作都正确完成,并且没有错误.这发生在许多功能上,但仅限于模块C.

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

谢谢...?

zhi*_*ang 1

好吧,事实证明,在 llvm IRC 频道中进行一番探索之后,llvm::Linker 应该与空的 llvm::Module 一起使用作为启动模块。

\n\n

另外,在我的用例中,我在链接在一起的不同模块中重复使用相同的 llvm::Type (内存中的实际内容)。他们说这不是非法的,但从未测试过,所以... \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf

\n\n

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

\n