2009-04-09 8 views
10

He estado jugando con LLVM con la esperanza de aprender a usarlo.Preguntas para compilar a LLVM

Sin embargo, mi mente está empantanada por el nivel de complejidad de la interfaz.

Tomemos por ejemplo la función de Fibonacci

int fib(int x) { 
    if(x<=2) 
     return 1; 
    return fib(x-1) + fib(x-2); 
    } 

Para conseguir esto para dar salida LLVM IR, se necesita 61 líneas de código !!!

También incluyen BrainFuck que es conocido por tener el compilador más pequeño (200 bytes). Desafortunadamente, con LLVM, es más de 600 líneas (18 kb).

¿Es esta la norma para los back-end de compiladores? Hasta ahora, parece que sería mucho más fácil hacer un ensamblaje o backend de C.

Respuesta

17

El problema está en C++ y no en LLVM.

Utilice un lenguaje diseñado para la metaprogramación, como OCaml, y su compilador será mucho más pequeño. Por ejemplo, this OCaml Journal article describes an 87-line LLVM-based Brainfuck compiler, this mailing list post describes complete programming language implementation including parser que puede compilar la función Fibonacci (entre otros programas) y todo el compilador tiene menos de 100 líneas de código OCaml usando LLVM y HLVM is a high-level virtual machine with multicore-capable garbage collection in under 2,000 lines of OCaml code using LLVM.

+0

Gracias por la sugerencia Jon. Desafortunadamente, la programación en OCaml todavía me resulta difícil de aprender, ya que soy principalmente un programador de procedimientos. – Unknown

+1

Incluso si incluye el tiempo necesario para aprender OCaml, será aún más rápido escribir un compilador de calidad de producción en OCaml en lugar de usar C++. No puedo recomendar OCaml con suficiente fuerza para este propósito. –

+2

Eche un vistazo a mi [PL zoo] (http://andrej.com/plzoo/) si no le cree a Jon. –

1

¿No LLVM entonces optimiza el IR dependiendo de la arquitectura específica implementada en el back-end? El código IR no se traduce directamente 1: 1 en el binario final. Por lo que yo entiendo, así es como funciona. Sin embargo, solo he comenzado a jugar con el back-end (lo estoy transfiriendo a un procesador personalizado).

+0

No estoy hablando del tamaño final. Estoy hablando del código necesario para HACER el IR. – Unknown

1

LLVM requiere un código repetitivo, pero una vez que lo entiendes, es bastante simple. Intente buscar una interfaz simple de GCC, y se dará cuenta de lo limpio que es LLVM. Definitivamente recomendaría LLVM sobre C o ASM. ASM no es portátil en absoluto, y la generación de código fuente suele ser algo malo, porque hace que la compilación sea lenta.

+0

¿Qué hay de compilar para LLVM IR? ¿Sabes si es lo suficientemente estable? – Unknown

+1

LLVM IR funciona, pero tiene muchos de los mismos problemas que la compilación de C. Si usa C++ para el compilador, usar las bibliotecas es mucho más fácil. – Zifre

1

Las representaciones intermedias pueden ser un poco prolijas, en comparación con el ensamblador no virtual. Aprendí que estaba mirando .NET IL, aunque nunca fui más allá de mirar. No estoy muy familiarizado con LLVM, pero creo que es el mismo problema.

Tiene sentido cuando lo piensas bien. Una gran diferencia es que los IR tienen que lidiar con muchos metadatos. En el ensamblador hay muy poco: el procesador define implícitamente mucho, y las convenciones para cosas como las llamadas a funciones se dejan al programador/compilador para definirlas. Eso es conveniente, pero crea una gran portabilidad y problemas de interoperabilidad.

Las representaciones intermedias como .NET y LLVM se preocupan por asegurarse de que los componentes compilados por separado puedan funcionar juntos, incluso los componentes escritos en diferentes idiomas y compilados por diferentes interfaces de compilación. Eso significa que los metadatos son necesarios para describir lo que está sucediendo a un nivel más alto que, por ejemplo, empujes arbitrarios, saltos y cargas que podrían ser manejo de parámetros, pero podrían ser casi cualquier cosa. La recompensa es bastante grande, pero hay un precio que pagar.

También hay otros problemas. La representación intermedia no está realmente destinada a ser escrita por humanos, sino que debe ser legible. Además, está destinado a ser lo suficientemente general como para sobrevivir a una serie de versiones sin un rediseño completamente incompatible desde cero.

Básicamente, en este contexto, explícito es casi siempre mejor que implícito, por lo que la verbosidad es difícil de evitar.

Cuestiones relacionadas