我是LLVM的新手。我正在使用clang c ++ API将多个存根文件(在c中)编译为IR,然后使用IR构建器(在链接它们之后)将它们粘在一起,最终通过JIT运行。
所有这一切都很有效,除非我在我的优化中添加了一个functionInlining传递,此时在IR构建器中进行的这些函数调用之一将在运行传递管理器时触发以下异常:
Assertion failed: (New->getType() == getType() && "replaceAllUses of value with new value of different type!"), function replaceAllUsesWith, file /Users/mike/Development/llvm/llvm/lib/IR/Value.cpp, line 356.
这就是我如何拨打电话指令(非常简单):
Function *kernelFunc = mModule->getFunction( (kernel->Name() + StringRef("_") + StringRef(funcName)).str());
if (kernelFunc){
CallInst* newInst = builder.CreateCall(kernelFunc, args);
}
稍后该模块已经过优化:
legacy::PassManager passMan;
PassManagerBuilder Builder;
Builder.OptLevel = 3;
//Builder.Inliner = llvm::createFunctionInliningPass(); //commenting this back in trigger the exception
Builder.populateModulePassManager(passMan);
passMan.run( *mModule ); //exception occurs before this call returns
任何想法要找什么?
答案 0 :(得分:0)
尝试在模块上运行llvm :: verifyModule以查看它是否正确。你可能有一个错误,并且事先变得幸运,但它在内衬中绊倒了一些东西。
通常,断言会检查模块可能出错的部分内容,但验证检查的次数更多。
这可能是LLVM中的一个错误,但很可能它是一个糟糕的模块,很容易发生。
答案 1 :(得分:-1)
所以我最终设置了我的开发环境,以便我可以在调试器中检查断言调用。事实证明,被替换的基本块具有与被替换的基本块不同的上下文集。返回并确保IRBuilder使用相同的上下文,因为IR解析器解决了这个问题。