gpt4 book ai didi

c - 如何使用 LLVM-C 对浮点恒等函数进行 JIT 编译

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:37 25 4
gpt4 key购买 nike

到目前为止,我已经编写了以下代码:

#include <stdlib.h>
#include <stdio.h>
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
#include <llvm-c/Transforms/Scalar.h>


int main (int argc, char const *argv[])
{
char *error = NULL;
LLVMLinkInMCJIT();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();

LLVMModuleRef mod = LLVMModuleCreateWithName("minimal_module");
LLVMTypeRef identity_args[] = { LLVMDoubleType(), NULL };
LLVMValueRef identity = LLVMAddFunction(mod, "identity", LLVMFunctionType(LLVMDoubleType(), identity_args, 1, 0));
LLVMSetFunctionCallConv(identity, LLVMCCallConv);
LLVMValueRef n = LLVMGetParam(identity, 0);

LLVMBasicBlockRef entry = LLVMAppendBasicBlock(identity, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
LLVMBuildRet(builder, n);

LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);

LLVMExecutionEngineRef engine;
error = NULL;
if(LLVMCreateJITCompilerForModule(&engine, mod, 2, &error) != 0) {
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
abort();
}

LLVMDumpModule(mod);

LLVMGenericValueRef exec_args[] = {LLVMCreateGenericValueOfFloat(LLVMDoubleType(), 1.25)};
LLVMGenericValueRef exec_res = LLVMRunFunction(engine, identity, 1, exec_args);
fprintf(stderr, "\n");
fprintf(stderr, "; Running identity(%f) with JIT...\n", 1.25);
fprintf(stderr, "; Result: %f\n", LLVMGenericValueToFloat(LLVMDoubleType(), exec_res));

LLVMRemoveModule(engine, mod, &mod, &error);
LLVMDisposeModule(mod);
LLVMDisposeExecutionEngine(engine);
LLVMDisposeBuilder(builder);
return 0;
}

使用 32 位整数的相应实现有效,即 identity(42) 将返回 42。然而,上面的浮点版本返回 0.0。上面的程序生成以下输出:

; ModuleID = 'minimal_module'
source_filename = "minimal_module"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

define double @identity(double) {
entry:
ret double %0
}

; Running identity(1.250000) with JIT...
; Result: 0.000000

我在 AMD 计算机上使用 Debian Jessie 下的 LLVM-3.9。我的问题是:我做错了什么?

最佳答案

我找到了解决问题的方法。除了使用 LLVMRunFunction 之外,还可以使用 LLVMGetFunctionAddress 来获取函数的地址并使用 C(或使用 FFI 库)直接调用它。

#include <stdlib.h>
#include <stdio.h>
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
#include <llvm-c/Transforms/Scalar.h>


int main (int argc, char const *argv[])
{
char *error = NULL;
LLVMLinkInMCJIT();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();

LLVMModuleRef mod = LLVMModuleCreateWithName("minimal_module");
LLVMTypeRef identity_args[] = { LLVMInt32Type() };
LLVMValueRef identity = LLVMAddFunction(mod, "identity", LLVMFunctionType(LLVMInt32Type(), identity_args, 1, 0));
LLVMSetFunctionCallConv(identity, LLVMCCallConv);
LLVMValueRef n = LLVMGetParam(identity, 0);

LLVMBasicBlockRef entry = LLVMAppendBasicBlock(identity, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
LLVMBuildRet(builder, n);

LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);

LLVMExecutionEngineRef engine;
error = NULL;
if(LLVMCreateJITCompilerForModule(&engine, mod, 2, &error) != 0) {
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
abort();
}
int (*fun)(int) = (int (*)(int))LLVMGetFunctionAddress(engine, "identity");

LLVMDumpModule(mod);

fprintf(stderr, "\n");
fprintf(stderr, "; Running identity(42) with JIT...\n");
fprintf(stderr, "; Result: %d\n", (*fun)(42));

LLVMRemoveModule(engine, mod, &mod, &error);
LLVMDisposeModule(mod);
LLVMDisposeExecutionEngine(engine);
LLVMDisposeBuilder(builder);
return 0;
}

关于c - 如何使用 LLVM-C 对浮点恒等函数进行 JIT 编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47721017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com