使用 LLVM C API 生成对内部函数的调用
Posted
技术标签:
【中文标题】使用 LLVM C API 生成对内部函数的调用【英文标题】:Generate call to intrinsic using LLVM C API 【发布时间】:2014-12-28 23:01:53 【问题描述】:我正在编写一些使用 LLVM C API 的代码。如何使用内部函数,例如 llvm.cos.f64
或 llvm.sadd.with.overflow.i32
?每当我尝试通过使用LLVMAddGlobal
(具有正确的类型签名)生成全局来执行此操作时,我只会在 JIT 链接阶段收到此错误消息:
我没有使用 LLVM C++ 接口,所以LLVM insert intrinsic function Cos 中的建议似乎不适用。
我想我需要Intrinsic::getDeclaration
之类的东西,但我似乎找不到它。我错过了什么明显的东西吗?
【问题讨论】:
【参考方案1】:无需离开 C API。将内部名称传递给LLVMAddFunction
:
LLVMTypeRef param_types[] = LLVMDoubleType();
LLVMTypeRef fn_type = LLVMFunctionType(LLVMDoubleType(), param_types, 1, false);
LLVMValueRef fn = LLVMAddFunction(module, "llvm.cos.f64", fn_type);
然后您可以使用LLVMBuildCall
生成对fn
的调用。
【讨论】:
这是我遇到同样问题时发现的堆栈溢出问题 :)【参考方案2】:我现在已经通过编写一小段 C++ 代码来解决这个问题,该代码调用我在另一个问题llvm::Intrinsic::getDeclaration
中引用的 API,并且我使用了一点魔法来获取合法内在函数的列表。我宁愿使用纯 C API 来完成此操作,但我对使事情正常运行的需求比我对严格语言纯度的需求更强烈。
要获得内在函数的名称列表,我这样做:
static const char *const intrinsicNames[] =
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_NAME_TABLE
;
这会生成一个排序表,因此我可以使用bsearch
来查找我想要的 ID。
static int search(const void *p1, const void *p2)
const char *s1 = (const char *) p1;
const char *s2 = *(const char **) p2;
return strcmp(s1, s2);
int GetLLVMIntrinsicIDFromString(const char* str, llvm::Intrinsic::ID& id)
void *ptr = bsearch(str, (const void *) intrinsicNames,
sizeof(intrinsicNames)/sizeof(const char *),
sizeof(const char *), search);
if (ptr == NULL)
return 0;
id = (llvm::Intrinsic::ID)((((const char**) ptr) - intrinsicNames) + 1);
return 1;
为了获得我可以调用的实际内在函数,我这样做(需要一个模块引用和一个参数类型引用):
// Omitting exactly how I obtain these values but the types are mostly LLVM C API types.
// The only one that was awkward was the ID which was cast from an offset into that table above.
LLVMModuleRef mod = ...;
llvm::Intrinsic::ID = ...;
LLVMTypeRef ty = ...;
std::vector<llvm::Type *> arg_types;
arg_types.push_back(llvm::unwrap(ty));
LLVMValueRef rt = llvm::wrap(llvm::Intrinsic::getDeclaration(llvm::unwrap(mod), id, arg_types));
LLVMValueRef
适合与 LLVM C API 的其余部分一起使用。关键是我正在使用llvm::unwrap
和llvm::wrap
。
【讨论】:
以上是关于使用 LLVM C API 生成对内部函数的调用的主要内容,如果未能解决你的问题,请参考以下文章