2011-09-05 12 views
6

Aviso: noté que this question está muy relacionado con este, por lo que si está interesado en mi pregunta, definitivamente debería leer esa otra y sus respuestas también.¿Qué tipos de optimización LLVM hace y qué tipo de optimizaciones tienen que implementar sus interfaces?

Puedo pensar en algunas optimizaciones que un frontend de lenguaje OOP podría hacer, como crear variables temporales para mantener los valores de las llamadas al método const llamadas en secuencia, sin llamadas intermedias no conformes al objeto en cuestión, cortar llamadas a funciones , pero no puedo pensar en muchos más. Me gustaría pedirle a las personas que creen una lista más larga de ejemplos.

Pregunto esto porque quiero crear un pequeño lenguaje como proyecto para mascotas y no estoy seguro de cómo estudiar este tema muy bien. Tal vez este es un caso para la wiki de la comunidad? Una lista completa de optimizaciones que hace el backend LLVM y que las interfaces deberían hacer por sí mismas, ¿qué opinas?

Ah, y sé que diferentes interfaces pueden tener necesidades muy diferentes, pero mi atención se centra en los lenguajes de procedimiento/OOP.

Respuesta

6

Esto probablemente varía mucho según el idioma ... clang (C/C++) es capaz de salirse con la suya haciendo muy poco en términos de optimizaciones en la interfaz. La única optimización que puedo pensar que se hace para el rendimiento del código generado es que clang realiza cierta desvirtualización de los métodos de C++ en la interfaz. clang hace algunas otras optimizaciones como plegado constante y eliminación de código muerto, pero eso se hace principalmente para acelerar el tiempo de compilación, no para el rendimiento del código generado.

EDIT: En realidad, pensar en ello un poco más, acabo de recordar una más ruido metálico optimización importante hace para C++: tañido sabe algunos trucos para eludir constructores de copia en C++ (google para NRVO).

En algunos casos, puede ser útil un pase de optimización de IR específico del idioma. Hay un pase SimplifyLibCalls que sabe cómo optimizar las llamadas en la biblioteca estándar C. Para la nueva característica de lenguaje ARC de Objective-C, clang pone algunos pasos específicos de ARC en la tubería; esos optimizan llamadas a varias funciones de tiempo de ejecución de Objective-C.

En general, implementar optimizaciones en el frontend solo es útil en general cuando el código tiene propiedades que no se pueden codificar en el IR (por ejemplo, los objetos C++ tienen un puntero vtable constante). Y en la práctica, lo más probable es que desee implementar primero la generación de código tonto y ver si hay casos importantes que no están optimizados. Los optimizadores pueden hacer algunas transformaciones sorprendentemente complejas.

Véase también http://llvm.org/docs/tutorial/LangImpl7.html; El uso de alloca de manera apropiada es una de las cosas que ayuda sustancialmente a los optimizadores, aunque en realidad no es una optimización en sí misma.

+0

No me imaginaba que el clang no hiciera muchas optimizaciones. Pensé que haría al menos 5 o algo así (una vez más, no entiendo este tema, por lo que todo lo que digo es solo adivinar arbitrariamente, lol). Si está muy seguro de su respuesta, y como esta pregunta no se hizo popular en absoluto, puedo marcarla como aceptada. Solo esperando tu confirmación; muchas gracias;) –

+0

Realmente no hace tanto ... piénselo de esta manera: si una optimización se puede expresar como una transformación IR a IR que no cambia la semántica, ¿por qué duplicar el código para hacerlo? en ASTs? (En realidad, clang ha creado algunos optimizadores de AST bastante potentes, pero los usamos para análisis estáticos, no para generación de código.) – servn

+0

Sí, imaginé que LLVM probablemente exprime todo lo que puede salir de la IR, pero no tengo una visión clara de lo que entra en el IR y lo que se pierde (NRVO es un ejemplo). Supongo que no hay muchos ejemplos sutiles aquí. NRVO, la especialización de implementación depende del hardware disponible, las ramificaciones preferidas, todas son bastante obvias y no las extrañaría al escribir mi compilador. Pero gracias por aclarar, ¡ahora me siento más seguro! :RE –

2

Existen muchas optimizaciones que solo necesitan tanta información como la que se conserva en SSA form, que LLVM utiliza. SSA ofrece muchas posibilidades de analizar en términos de flujo de control, flujo de datos.

Por otro lado, el lenguaje LLVM es RISC, por lo que se pierde mucha información de alto nivel.

Así respuesta es: front-end es capaz de hacer optimizaciones que requieren información que se pierde después de traducir a SSA.Los ejemplos que vienen a la mente:

  • prefieren optimizaciones de ramificación, algunos ejemplos
    • lang. extensiones como declarar ramas preferidas (en el núcleo de Linux algunas ramas están marcados como casi siempre ejecutados)
    • implementación de lanzar y atrapar excepciones
    • aplicación co-rutinas y la información de dependencia
  • optimizaciones que crecen exponencialmente (como bucle -unswitch grow code-size), puede ser necesario aplicarlo a lugares específicos de acuerdo con la información de alto nivel. - podría ser del código fuente (front-end).
  • características del lenguaje (podría ser una reflexión o algo más) que se traduce en estructuras de interconexión de "muchos punteros" (como punteros a indicadores ...), que pueden ser difíciles de adivinar en el nivel bajo, como en el nivel bajo, todos podrían parecerse al acceso a la matriz, mientras que podría tener algunas restricciones en el nivel alto que podrían ayudar en las optimizaciones.
  • funciones complejas pueden implementarse de manera diferente dependiendo del hardware disponible. Veamos algunos ejemplos: multiplicación de matrices, transformación FFT (compresión & algoritmos de descompresión), aritmética de números grandes, etc ... dependiendo del hardware subyacente, podría implementarse de manera diferente para lograr el máximo rendimiento. Después de traducir cosas en LLVM podría ser muy, muy, muy costoso (en términos de complejidad de cómputo) cambiar la implementación con un hardware más apropiado. Es decir, por qué la decisión debe tomarse por front-end cuando se compila en un nivel inferior.

Esas son sólo algunas ideas, una esperanza, que muestran el tipo de optimizaciones que podrían estar involucradas.

Cuestiones relacionadas