使用LLVM C API生成对内在函数的调用 [英] Generate call to intrinsic using LLVM C API

查看:401
本文介绍了使用LLVM C API生成对内在函数的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一些使用LLVM C API的代码.如何使用内在函数,例如llvm.cos.f64llvm.sadd.with.overflow.i32?每当我尝试通过使用LLVMAddGlobal(具有正确的类型签名)生成一个全局变量来做到这一点时,我只会在JIT链接阶段得到以下错误消息:

I'm working on some code that uses the LLVM C API. How do I use intrinsics, such as llvm.cos.f64 or llvm.sadd.with.overflow.i32? Whenever I try to do it by generating a global with LLVMAddGlobal (with the correct type signature), I just get this error message during the JIT linking stage:


LLVM ERROR: Could not resolve external global address: llvm.cos.f64

我没有使用LLVM C ++接口,因此我想我需要像Intrinsic::getDeclaration这样的东西,但是我似乎找不到.我缺少明显的东西吗?

I presume I need something like Intrinsic::getDeclaration, but I can't seem to find it. Am I missing something obvious?

推荐答案

我现在通过编写一小段C ++代码来解决此问题,该代码调用了我在另一个问题llvm::Intrinsic::getDeclaration中引用的API,我使用了获取法律内在要素清单的小魔术.我宁愿使用纯C API来完成此操作,但我使事情正常进行的需求比对严格的语言纯净度的需求要强.

I've now resolved this by writing a short piece of C++ code that calls the API I referenced in the other question, llvm::Intrinsic::getDeclaration, and I use a little magic to get the list of legal intrinsics. I'd have rather done this with a pure C API, but my need for making things work is stronger than my need for strict language purity.

要获取内部函数名称的列表,请执行以下操作:

To get the list of names of intrinsics, I do this:

static const char *const intrinsicNames[] = {
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_NAME_TABLE
};

这将生成一个排序表,因此我可以使用bsearch查找所需的ID.

This produces a sorted table, so I can use bsearch to find the ID that I want.

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;
}


要获取随后可以调用的实际内在函数,请执行此操作(需要一个模块引用和一个参数类型引用):


To get the actual intrinsic that I can then call, I do this (which requires a module reference and an argument type reference):

// 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::unwrapllvm::wrap.

That LLVMValueRef is suitable for use with the rest of the LLVM C API. The key is that I'm using llvm::unwrap and llvm::wrap.

这篇关于使用LLVM C API生成对内在函数的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆