Как использовать LLVM-C для JIT-компиляции функции идентификации с плавающей точкой

wedesoft спросил: 14 ноября 2017 в 05:52 в: c

Пока что я написал следующий код:

#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

Я использую LLVM-3.9 под Debian Jessie на компьютере AMD. У меня вопрос: что я делаю не так?


0 ответов