¿Por qué LLVM tiene un IR de tipo ensamblador en lugar de un IR de árbol? O: ¿por qué los proyectos se enfocan en LLVM IR en lugar de AST de Clang?

14

¿Por qué la representación intermedia de LLVM es como un ensamblaje en lugar de como un árbol?

Alternativamente, ¿por qué las implementaciones de lenguaje se enfocan en LLVM IR en lugar de AST de Clang?

No estoy tratando de hacer dos preguntas diferentes a la vez si parece que es así. Para mí, simplemente parece que los programadores tanto de clientes como de bibliotecas llegaron al consenso de que la API de LLVM, nada más y nada menos, es obviamente un buen diseño de software y mi pregunta es "¿por qué?".

La razón por la que pregunto es que parece que LLVM podría proporcionar más funcionalidad a las interfaces si su IR era similar a AST porque las herramientas basadas en AST de Clang podrían usarse para cualquier interfaz. Alternativamente, los idiomas que apuntan a LLVM IR podrían obtener más funcionalidad si se enfocaran en AST de Clang.

Clang tiene clases y funciones para crear y trabajar con AST y es el proyecto frontend only que está fuertemente vinculado al proyecto LLVM. ¿Por qué la funcionalidad AST de Clang es externa a LLVM?

Desde lo alto de mi cabeza, sé que Rust (rustc), D (ldc) y Haskell (GHC) pueden usar LLVM como backend pero no usan Clang AST (que yo sepa) , Podría estar equivocado). No conozco todos los detalles internos de estos compiladores, pero al menos Rust y D ciertamente parecen estar compilados para AST de Clang. Tal vez Haskell también podría, pero estoy mucho menos seguro de eso.

¿Esto se debe a razones históricas (LLVM originalmente era una "máquina virtual de bajo nivel" y el clang viene más adelante)? ¿Esto se debe a que otras interfaces quieren tener el mayor control posible sobre lo que alimentan a LLVM? ¿Hay razones fundamentales por las que el AST de Clang no sea apropiado para lenguajes "no similares a C"?

No pretendo que esta pregunta sea un ejercicio de lectura mental. Solo quiero que sea útil para aquellos de nosotros que tenemos curiosidad acerca del diseño del compilador, pero que aún no lo dominamos. Dado que los proyectos LLVM y clang se desarrollan en público, espero que alguien familiarizado con el desarrollo de estos proyectos pueda responder o que la respuesta sea lo suficientemente obvia para algunos nerds de compilación que se sientan lo suficientemente seguros para responder.

Para anticiparse a algunas respuestas obvias pero insatisfactorias:

Sí, tener un IR similar a un ensamblaje le da más control a quienquiera que diseñe el IR (quizás X lang tenga un mejor código de base y formato AST que el clang) pero si esa es la única respuesta, entonces la pregunta es "¿por qué LLVM > solo tiene un IR de ensamblador en lugar de un IR de alto nivel como un árbol y un IR de ensamblaje de bajo nivel? ".

Sí, no es tan difícil analizar un lenguaje de programación en un AST (al menos en comparación con los otros pasos de compilación). Aun así, ¿por qué usar ASTs separados? Si no hace nada más, usar el mismo AST le permite usar herramientas que operan en AST (incluso cosas simples como las impresoras AST).

Sí, estoy muy de acuerdo en que ser más modular es algo bueno, pero si esa es la única razón, ¿por qué las implementaciones de otros lenguajes tienden a apuntar con LLVM IR en lugar de AST de Clang?

Estas preferencias pueden ser erróneas o pasar por alto detalles, así que siéntase libre de dar estas respuestas si tiene más detalles o mis suposiciones están equivocadas.

Para cualquier persona que quiera responder una pregunta con una respuesta más definitiva: ¿cuáles son las ventajas y desventajas de una IR de tipo ensamblaje frente a una IR de tipo árbol?

    
pregunta Praxeolitic 16.08.2017 - 12:09

1 respuesta

12

Aquí hay una serie de preguntas interrelacionadas, intentaré separarlas lo mejor que pueda.

¿Por qué otros lenguajes se basan en LLVM IR y no usan AST?

Esto es simplemente porque clang es un extremo delantero de C / C ++ y el AST que produce está estrechamente acoplado a C / C ++. Otro lenguaje podría usarlo, pero necesitaría una semántica casi idéntica a algún subconjunto de C / C ++, que es muy limitante. Como señala, el análisis de un AST es bastante sencillo, por lo que la limitación de sus elecciones semánticas probablemente no valdrá la pena.

Sin embargo, si está escribiendo herramientas para C / C ++, p. ej. analizadores estáticos, luego reutilizar el AST tiene mucho sentido, ya que es mucho más fácil trabajar con el AST que con el texto sin formato si está trabajando con C / C ++.

¿Por qué LLVM IR es el formulario?

LLVM IR se eligió como una forma apropiada para escribir optimizaciones del compilador. Como tal, su principal característica es que está en el formulario SSA . Es un nivel de IR bastante bajo, por lo que es aplicable a una amplia gama de idiomas, por ejemplo. no escribe la memoria ya que esto varía mucho según los idiomas.

Ahora bien, sucede que escribir optimizaciones del compilador es una tarea bastante especializada y, a menudo, es ortogonal al diseño de características del idioma. Sin embargo, tener un lenguaje compilado ejecutándose rápido es un requisito bastante general. Además, la conversión de LLVM IR a ASM es bastante mecánica y, en general, tampoco es interesante para los diseñadores de idiomas.

Por lo tanto, reducir un idioma a LLVM IR le da a un diseñador de idiomas muchas "cosas gratis" que son muy útiles en la práctica, lo que las hace concentrarse en el idioma en sí.

¿Sería útil un IR diferente (OK, no se pregunta, pero está implícito)?

¡Absolutamente! Los AST son bastante buenos para ciertas transformaciones en la estructura del programa, pero son muy difíciles de usar si se desea transformar el flujo del programa. Un formulario de SSA es generalmente mejor. Sin embargo, LLVM IR es de muy bajo nivel, por lo que gran parte de la estructura de alto nivel se pierde (a propósito, por lo que es de aplicación más general). Tener un IR entre el AST y el IR de bajo nivel puede ser beneficioso aquí. Tanto Rust como Swift adoptan este enfoque y tienen un IR de alto nivel entre los dos.

    
respondido por el Alex 16.08.2017 - 15:30

Lea otras preguntas en las etiquetas