2012-03-09 14 views
7

Estoy tratando de comenzar con LLVM para agregar compilación justo a tiempo para mi código, pero me resulta muy difícil encontrar referencias sobre cómo hacer las cosas que quiero en LLVM, a pesar de tener revisado a través del tutorial Kaleidoscope, el manual de referencia del idioma, el manual del programador y la documentación doxygen. ¿Hay más referencias a la API C++ de LLVM que estas?Acceso a elementos en matrices LLVM

Ahora para la pregunta concreta. He asignado un objeto de matriz con dos elementos (que supongo corresponde a double[2] en C++):

const llvm::Type* double_t = llvm::Type::getDoubleTy(llvm::getGlobalContext()); 
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2) 

Más adelante en el código, crear una función, donde esta matriz es uno de los argumentos. Entonces, en mi función extraigo el primer elemento de la matriz y devolverlo al usuario:

llvm::Function::arg_iterator AI = jit_function_->arg_begin(); 
llvm::Value *x = AI; 
llvm::Value *x0 = Builder.CreateExtractValue(x,0); 
Builder.CreateRet(x0); 

Los jits código bien, pero cuando intento ejecutarlo, no funciona. Por ejemplo:

typedef double (*GenType)(double[2]); 
GenType FP = GenType(intptr_t(TheExecutionEngine->getPointerToFunction(jit_function_))); 
double y[2] = {10,20}; 
double r = FP(y); 
printf("r = %g\n", r); 

El valor de retorno no tiene sentido y no puedo ver lo que estoy haciendo mal. Si paso los valores en la matriz (10 y 20) como argumentos escalares a la función, funciona bien.

Respuesta

8

Creo que puedo responder mi propia pregunta. Para la primera parte de la pregunta, una buena referencia a LLVM (además de las mencionadas anteriormente) es escribir lo que desea en C simple y compilarlo con Clang y ver la salida de LLVM: clang -S -emit-llvm test.c -o -.

Para la pregunta concreta, mi problema era que suponía que estaba pasando una serie de dos dobles a la función jitted, mientras que de hecho estaba pasando un puntero a una matriz con dos valores. Así que la solución es cambiar:

const llvm::Type* array_t = llvm::ArrayType::get(double_t,2); 

a

const llvm::Type* array_t = llvm::PointerType::getUnqual(llvm::ArrayType::get(double_t,2)); 

Y para añadir un desreferenciar adicional cambiando

llvm::Value *x0 = Builder.CreateExtractValue(x,0); 

a

llvm::Value *x0 = Builder.CreateExtractValue(Builder.CreateLoad(x),0); 
0

Si está utilizando LLVM 3.0 o 3.1, CreateExtractValue toma un ArrayRef con los índices.

+0

Sí, lo sé (se se usa en el código anterior). Pero realmente no está respondiendo la pregunta. – Joel

Cuestiones relacionadas