2012-02-06 14 views
11

Quiero leer (analizar) el código IR LLVM (que se guarda en un archivo de texto) y agregarle algo de mi propio código. Necesito algún ejemplo de cómo hacer esto, es decir, cómo se hace esto utilizando las bibliotecas proporcionadas por LLVM para este propósito. Básicamente, lo que quiero es leer en el código IR de un archivo de texto en la memoria (tal vez la biblioteca LLVM lo representa en forma AST, no lo sé), hacer modificaciones, como agregar más nodos en el AST y finalmente escribir respalde el AST en el archivo de texto IR.Analizando y modificando el código IR LLVM

Aunque necesito tanto leer como modificar el código IR, agradecería mucho si alguien pudiera proporcionarme o referirme a algún ejemplo que simplemente lo lea (lo analice).

Respuesta

24

En primer lugar, para corregir un malentendido obvio: LLVM es un marco para manipular código en formato IR. No hay AST a la vista (*): lee IR, lo transforma/manipula/analiza, y vuelve a escribir IR.

lectura IR es muy simple:

int main(int argc, char** argv) 
{ 
    if (argc < 2) { 
     errs() << "Expected an argument - IR file name\n"; 
     exit(1); 
    } 

    LLVMContext &Context = getGlobalContext(); 
    SMDiagnostic Err; 
    Module *Mod = ParseIRFile(argv[1], Err, Context); 

    if (!Mod) { 
     Err.print(argv[0], errs()); 
     return 1; 
    } 

    [...] 
    } 

Este código acepta un nombre de archivo. Esto debería ser un archivo LLVM IR (textual). A continuación, pasa a analizarlo en un Module, que representa un módulo de IR en el formato interno en memoria de LLVM. Esto puede ser manipulado con los diferentes pases que LLVM tiene o usted puede agregar por su cuenta. Eche un vistazo a algunos ejemplos en la base de código LLVM (como lib/Transforms/Hello/Hello.cpp) y lea esto - http://llvm.org/docs/WritingAnLLVMPass.html.

Escupir IR nuevamente en un archivo es aún más fácil. La clase Module simplemente escribe a sí mismo a una corriente:

some_stream << *Mod; 

Eso es todo.

Ahora, si tiene alguna preguntas específicas sobre específicos modificaciones que quiere hacer con el código de IR, que realmente debería pedir algo más centrado. Espero que esta respuesta te muestre cómo analizar el IR y escribirlo de nuevo.


(*) IR no tiene una representación AST dentro de LLVM, porque es un lenguaje simple de ensamblaje. Si subes un escalón hacia arriba, hacia C o C++, puedes usar Clang para analizar eso en ASTs, y luego hacer manipulaciones en el nivel de AST. Clang sabe cómo producir LLVM IR desde su AST. Sin embargo, debe comenzar con C/C++ aquí, y no LLVM IR. Si LLVM IR es lo único que te importa, olvídate de los AST.

+0

Gracias Eli. Tu respuesta fue muy útil. – MetallicPriest

+0

Heads up, creo que debería ser "parseIRFile" con una p minúscula. http://llvm.org/docs/doxygen/html/IRReader_2IRReader_8h_source.html – user2027722

+0

@ user2027722: sí, las API de LLVM cambian tan a menudo que es difícil mantener las muestras actualizadas. Tengo un repositorio de Github para eso: https://github.com/eliben/llvm-clang-samples que mantengo lo más sincronizado posible, y es más una fuente de verdad que SO al azar. –

1

La forma más fácil de hacerlo es mirar una de las herramientas existentes y robar el código de la misma. En este caso, es posible que desee ver la fuente de llc. Puede tomar un bitcode o un archivo .ll como entrada. Puede modificar el archivo de entrada de la forma que desee y luego escribir el archivo usando algo similar al código en llvm-dis si desea un archivo de texto.

2

Esto se hace generalmente implementando un pase/transformación LLVM. De esta forma, no tiene que analizar el IR en absoluto porque LLVM lo hará por usted y operará en una representación en memoria del IR de la OO-oriented.

This es el punto de entrada para escribir un pase LLVM. A continuación, puede consultar cualquiera de los pasos estándar ya implementados que vienen incluidos con LLVM (consulte lib/Transforms).

+0

Eso sería lo que haré finalmente. Pero en este momento, dado que estoy en etapa de aprendizaje, quiero poder ver el IR en los archivos de texto. – MetallicPriest

+3

No veo el problema. La mayoría de las herramientas LLVM pueden leer/escribir la representación textual del IR. En particular, para emitir la representación textual, agregue el interruptor -S a su línea de comando. (Además, recuerde siempre que la representación binaria y textual es absolutamente equivalente). – CAFxX

1

La herramienta Opt toma el código IR de llvm, ejecuta un pase sobre él y luego escupe IIvm IR transformado en el otro lado.

La piratería más fácil de iniciar es lib \ Transforms \ Hello \ Hello.cpp. Cortarlo, ejecutar optar con su archivo de origen como entrada, inspeccionar la salida.

Aparte de eso, los documentos para escribir pases son bastante buenos.

1

Como se mencionó anteriormente, la mejor manera de escribir un pase. Pero si simplemente desea repetir las instrucciones y hacer algo con el LLVM, proporcionó una clase InstVisitor. Es una clase que implementa el patrón de visitante para obtener instrucciones. Es muy sencillo para el usuario, por lo que si quiere evitar aprender a implementar un pase, puede recurrir a eso.

Cuestiones relacionadas