sirve que para c++ llvm machine-code

c++ - que - Cómo generar código máquina con llvm



clang para que sirve (4)

Actualmente estoy trabajando en un proyecto de compilador usando llvm. He seguido varios tutoriales hasta el punto donde tengo un analizador para crear un árbol de sintaxis y luego el árbol se convierte en un Módulo llvm usando el IRBuilder proporcionado.

Mi objetivo es crear un ejecutable, y estoy confundido sobre qué hacer a continuación. Todos los tutoriales que he encontrado solo crean el módulo llvm e imprimen el ensamblaje utilizando Module.dump (). Además, la única documentación que puedo encontrar es para los desarrolladores de llvm, y no para los usuarios finales del proyecto.

Si quiero generar un código de máquina, ¿cuáles son los próximos pasos? El proyecto llvm-mc parece que puede hacer lo que quiero, pero no puedo encontrar ningún tipo de documentación sobre él.

Tal vez estoy esperando que llvm haga algo que no hace. Mi expectativa es que puedo construir un Módulo, entonces habría una API a la que puedo llamar con el Módulo y se generará un objetivo triple y se generará un archivo de objeto. He encontrado documentación y ejemplos sobre cómo producir un JIT, y no estoy interesado en eso. Estoy buscando cómo producir binarios compilados.

Estoy trabajando en OS X, si eso tiene algún impacto.


Como se puede leer en la guía de llc , de hecho, se pretende que solo genere el ensamblaje, y luego "La salida del lenguaje ensamblador se puede pasar a través de un ensamblador y un vinculador nativos para generar un ejecutable nativo", por ejemplo, el ensamblador gnu ( as ) y enlazador ( ld ).

Entonces, la respuesta principal aquí es usar herramientas nativas para ensamblar y vincular .

Sin embargo, hay soporte experimental para generar el objeto nativo directamente desde un archivo IR, a través de llc :

-filetype - Choose a file type (not all types are supported by all targets): =asm - Emit an assembly (''.s'') file =obj - Emit a native object (''.o'') file [experimental]

O puede usar llvm-mc para ensamblarlo desde el archivo .s :

-filetype - Choose an output file type: =asm - Emit an assembly (''.s'') file =null - Don''t emit anything (for timing purposes) =obj - Emit a native object (''.o'') file

Aunque no sé sobre enlazadores.

Además, recomiendo revisar el archivo tools/bugpoint/ToolRunner.h , que expone una envoltura que combina llc y la cadena de herramientas C nativa de la plataforma para generar código de máquina. Desde su comentario de cabecera:

Este archivo expone una abstracción alrededor de un compilador de C de plataforma, que se utiliza para compilar C y código de ensamblaje.


Echa un vistazo a estas funciones en llvm-c/TargetMachine.h :

/** Emits an asm or object file for the given module to the filename. This wraps several c++ only classes (among them a file stream). Returns any error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */ LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage); /** Compile the LLVM IR stored in /p M and store the result in /p OutMemBuf. */ LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);


Para ejecutar el programa BrainF ejemplo, BrainF y ejecute:

echo ,. > test.bf ./BrainF test.bf -o test.bc llc -filetype=obj test.bc gcc test.o -o a.out ./a.out

luego escriba una sola letra y presione Enter. Debería repetir esa carta de vuelta a usted. (Eso es lo que hace.)

Lo anterior fue probado con LLVM versión 3.5.0.


Utilice llc -filetype=obj para emitir un archivo de objeto llc -filetype=obj desde su IR. Puede consultar el código de llc para ver las llamadas a la API de LLVM que realiza para emitir dicho código. Al menos para Mac OS X y Linux, los objetos emitidos de esta manera deberían ser bastante buenos (es decir, esta no es una opción de "calidad alfa" por ahora).

Sin embargo, LLVM no contiene un enlazador (¡aún!). Por lo tanto, para vincular realmente este archivo objeto a una biblioteca ejecutable o compartida, deberá usar el enlazador del sistema. Tenga en cuenta que incluso si tiene un ejecutable que consiste en un solo archivo de objeto, este último tiene que estar vinculado de todos modos. Los desarrolladores de la comunidad LLVM están trabajando en un enlazador real para LLVM, llamado lld . Puede visitar su página o buscar en los archivos de la lista de correo para seguir su progreso.