gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:47:04 25 4
gpt4 key购买 nike

开门见山——我正在尝试将两个(或更多)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-link 然后调用 llvm-dis 来重现它,但是 1. 类型没有合并,并且 2. 没有这样的错误。

谢谢...?

最佳答案

好吧,事实证明,在 llvm IRC channel 中进行了一些探索之后,llvm::Linker 打算与一个空的 llvm::Module 作为起始模块一起使用。

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

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

关于c++ - 链接时 LLVM IR 类型被错误折叠(C++ API),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37779242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com