C++ 链接时错误折叠LLVM IR类型(C+;+;API)
直截了当地说——我试图将两个(或更多)llvm模块链接在一起,但我遇到了来自llvm的某个奇怪错误 我不想发布太多的代码,所以我将在这里使用一堆伪代码 我有3个模块,假设A、B和C。A是主要模块;我用它初始化C++ 链接时错误折叠LLVM IR类型(C+;+;API),c++,llvm,llvm-ir,llvm-c++-api,C++,Llvm,Llvm Ir,Llvm C++ Api,直截了当地说——我试图将两个(或更多)llvm模块链接在一起,但我遇到了来自llvm的某个奇怪错误 我不想发布太多的代码,所以我将在这里使用一堆伪代码 我有3个模块,假设A、B和C。A是主要模块;我用它初始化llvm::Linker。B和C为二级模块;我调用linker.linkInModule(B和C) 除其他外,所有3个模块都定义了以下两种类型: %String = type { i8*, i64 } %Character = type { i8*, i64 } 请注意,它们具有相同的成员
llvm::Linker
。B和C为二级模块;我调用linker.linkInModule(B和C)
除其他外,所有3个模块都定义了以下两种类型:
%String = type { i8*, i64 }
%Character = type { i8*, i64 }
请注意,它们具有相同的成员类型。此外,函数foo
定义如下(在模块B中):
这个函数是在模块A和C中声明的。现在,一切看起来都很好——这个函数是从模块A和C调用的,IR看起来很正常,如下所示:
%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)
问题来了:当所有3个模块链接在一起时,这些类型会发生一些事情:
%2
(%String
)和%3
(%Character
)define i1 @_ZN9Character7hasDataEv(%2*)
请注意%Character
或%3
如何变成%2
。此外,在callsite,可能是尝试取消合并类型,我得到以下结果:
%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通道中进行了一些探索之后,llvm::Linker打算与一个空的llvm::Module一起使用作为起始模块 此外,在我的用例中,我在链接在一起的不同模块之间重用相同的llvm::Type(内存中的实际内容)。他们说这不违法,但从未测试过,所以。。。¯\_(ツ)_/“”
因此,无论如何,这个问题是通过从一个空模块开始传递到链接器来解决的。您是否尝试禁用所有优化?如果使用不同的优化,是否会产生不同的效果?如果遇到奇怪的错误,我首先怀疑的是优化传递会弄乱我的代码。我禁用了所有优化传递。我确实做到了如果没有解决方案,我会把它编辑成问题。
%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2)