2014-12-28 4 views
4

LLVM C API를 사용하는 일부 코드로 작업하고 있습니다. 내장 함수 (예 : llvm.cos.f64 또는 llvm.sadd.with.overflow.i32)를 사용하려면 어떻게해야합니까? 나는 (올바른 유형의 서명으로) LLVMAddGlobal와 세계를 생성하여 수행하려고 할 때마다, 난 그냥 JIT의 연결 단계에서이 오류 메시지가 :LLVM C API를 사용하여 내장 함수 호출 생성

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

을 나는 LLVM C++ 인터페이스 사용하지 않는 따라서 LLVM insert intrinsic function Cos의 조언은 적용되지 않는 것 같습니다.

나는 Intrinsic::getDeclaration과 같은 것을 필요로하지만 나는 그것을 찾을 수없는 것 같습니다. 나는 명백한 것을 놓치고 있는가?

답변

1

저는 이제 다른 질문에서 참조한 API 인 llvm::Intrinsic::getDeclaration을 호출하는 C++ 코드의 짧은 부분을 작성하여 약간의 마법을 사용하여 올바른 내장 함수 목록을 얻었습니다. 나는 순수한 C API로 오히려 이것을 해왔지만 엄격한 언어 순도에 대한 필요보다 강하게 일하는 것이 필요합니다.


이 내장 함수의 이름 목록을 얻으려면,이 작업을 수행합니다

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

이 그래서 내가 원하는 ID를 찾을 수 bsearch을 사용할 수 있습니다 정렬 테이블을 생성합니다.

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

내가 다음 호출 할 수있는 실제 고유을 얻으려면, 내가 할이 ( 모듈 참조 및 인수 유형 참조 요구하는) : LLVMValueRef이 적합

// 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)); 

그 LLVM C API의 나머지 부분과 함께 사용합니다. 열쇠는 내가 llvm::unwrapllvm::wrap을 사용하고 있다는 것입니다.

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

는 그런 다음 LLVMBuildCallfn에 대한 호출을 생성 할 수 있습니다.