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

时间:2016-06-12 21:26:54

标签: 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 }

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

define i1 @_ZN9Character7hasDataEv(%Character*) { }

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

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

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

  1. 他们失去了名字,成为%2%String)和%3%Character)。
  2. 他们似乎合并在一起。
  3. 奇怪的是,虽然这个转换发生在模块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.有没有这样的错误。

    感谢...?

1 个答案:

答案 0 :(得分:1)

好的,事实证明,在llvm IRC频道中进行了一些讨论后,llvm :: Linker意味着与空llvm :: Module一起用作启动模块。

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

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