2009-09-13 19 views
10

Estoy escribiendo un generador de código LLVM para la madera aserrada lenguaje, el compilador emite la corriente C-código. Mi problema es que necesito llamar a las funciones C de los archivos LLVM generados, por ejemplo, el compilador tiene un recolector de basura en tiempo real y necesito llamar a las funciones para notificar cuando se asignan nuevos objetos en el montón. No tengo idea de cómo vincular estas funciones con mis archivos LLVM generados.LLVM - vinculación problema

La generación de código se hace por generar .ll-archivos y luego compilar manualmente estos.

estoy tratando de llamar a una función externa de LLVM pero no tengo suerte. En los ejemplos, he encontrado que solo se llaman funciones C estándar, como "puts" y "printf", pero quiero llamar a una función> casera. Estoy atascado.

+0

¿Quiere decir que está tratando de escribir código directamente en LLVM IR y no puede hacer una llamada, o que está compilando código usando LLVM y teniendo problemas? –

Respuesta

5

compilar sus archivos de ensamblaje llvm normalmente con llvm-como:

llvm-as *.ll 

compilar los archivos de código binario a .s archivos en lenguaje ensamblador:

llc *.bc 

GCC ellos con la biblioteca de ejecución:

gcc *.s runtime.c -o executable 

Sustituto en archivos make reales, bibliotecas compartidas, etc, si es necesario. Entiendes la idea.

12

Supongo que está escribiendo una transformación LLVM y desea agregar llamadas a funciones externas en el código transformado. Si este no es el caso, edite su pregunta e incluya más información.

Antes de poder llamar a una función externa de código LLVM, es necesario insertar una declaración por ello. Por ejemplo:

virtual bool runOnModule(Module &m) { 
    Constant *log_func = m.getOrInsertFunction("log_func", 
               Type::VoidTy, 
               PointerType::getUnqual(Type::Int8Ty), 
               Type::Int32Ty, 
               Type::Int32Ty, 
               NULL); 
    ... 
} 

El código anterior declara una función que devuelve log_func nula y tiene tres argumentos: un puntero de bytes (cuerda), y dos enteros de 32 bits. getOrInsertFunction es un método de Module.

Para llamar realmente la función, tiene que insertar un CallInst. Hay varios métodos estáticos Create para esto.

+0

Esto es exactamente lo que estaba tratando de hacer con llvm, ¡gracias! – Dan

3

estoy interpretando su pregunta como "¿Cómo implementar una biblioteca de tiempo de ejecución en C o C++ para mi lenguaje que se compila a LLVM?"

Un enfoque es, como lo detalla Jonathan Tang, transformar la salida de su compilador de LLVM IR a bitcode para ensamblar, y vanil gcc enlazar el ensamblado con el origen del tiempo de ejecución (o archivos de objetos).

Un enfoque alternativo, posiblemente más flexible es usar llvm-gcc para compilar el tiempo de ejecución en sí mismo en código de bits LLVM, y luego usar llvm-ld para vincular el código de bits de su compilador con el código de bits de su tiempo de ejecución. Este código de bit puede ser re-optimizado con opt, convertido de nuevo a IR con llvm-dis, interpretado directamente con lli (esto, afaik, solo funcionará si LLVM fue construido contra libffi), o compilado para ensamblar con llc (y luego a un nativo binario con vainilla gcc).