En el diseño de compiladores , la forma de asignación única estática (a menudo abreviada como forma SSA o simplemente SSA ) es un tipo de representación intermedia (IR) donde cada variable se asigna exactamente una vez. SSA se utiliza en la mayoría de los compiladores optimizadores de alta calidad para lenguajes imperativos, incluidos LLVM , la Colección de Compiladores GNU y muchos compiladores comerciales.
Existen algoritmos eficientes para convertir programas a formato SSA. Para ello, las variables existentes en el IR original se dividen en versiones; las nuevas variables suelen indicarse con el nombre original seguido de un subíndice, de modo que cada definición tenga su propia versión. También puede ser necesario introducir instrucciones adicionales que asignen valores a las nuevas versiones de las variables en el punto de unión de dos rutas de flujo de control. La conversión de formato SSA a código máquina también es eficiente.
SSA facilita numerosos análisis necesarios para la optimización, como la determinación de cadenas de uso-definición , ya que al examinar el uso de una variable, solo existe un lugar donde dicha variable puede haber recibido un valor. La mayoría de las optimizaciones pueden adaptarse para mantener la forma SSA, de modo que se pueden realizar una optimización tras otra sin análisis adicionales. Las optimizaciones basadas en SSA suelen ser más eficientes y potentes que sus equivalentes anteriores sin SSA.
En los compiladores de lenguajes funcionales , como los de Scheme y ML , se suele utilizar el estilo de paso de continuaciones (CPS). SSA es formalmente equivalente a un subconjunto bien comportado de CPS que excluye el flujo de control no local, por lo que las optimizaciones y transformaciones formuladas en términos de uno generalmente se aplican al otro. El uso de CPS como representación intermedia es más natural para funciones de orden superior y análisis interprocedimental. CPS también codifica fácilmente call/cc , mientras que SSA no. [ 1 ]
Historia
SSA fue desarrollado en la década de 1980 por varios investigadores en IBM . Kenneth Zadeck, un miembro clave del equipo, se trasladó a la Universidad de Brown mientras continuaba el desarrollo. [ 2 ] [ 3 ] Un artículo de 1986 introdujo puntos de nacimiento, asignaciones de identidad y renombramiento de variables de modo que las variables tuvieran una única asignación estática. [ 4 ] Un artículo posterior de 1987 de Jeanne Ferrante y Ronald Cytron [ 5 ] demostró que el renombramiento realizado en el artículo anterior elimina todas las dependencias falsas para escalares. [ 3 ] En 1988, Barry Rosen, Mark N. Wegman y Kenneth Zadeck reemplazaron las asignaciones de identidad con funciones Φ, introdujeron el nombre "forma estática de asignación única" y demostraron una optimización SSA ahora común. [ 6 ] El nombre función Φ fue elegido por Rosen para que fuera una versión más publicable de "función falsa". [ 3 ] Alpern, Wegman y Zadeck presentaron otra optimización, pero usando el nombre "asignación única estática". [ 7 ] Finalmente, en 1989, Rosen, Wegman, Zadeck, Cytron y Ferrante encontraron un medio eficiente de convertir programas a la forma SSA. [ 8 ]
Beneficios
La principal utilidad de SSA radica en cómo simplifica y mejora simultáneamente los resultados de diversas optimizaciones del compilador , al simplificar las propiedades de las variables. Por ejemplo, considere este fragmento de código:
y := 1 y := 2 x := y
Los humanos pueden ver que la primera asignación no es necesaria y que el valor de yser utilizado en la tercera línea proviene de la segunda asignación de y. Un programa tendría que realizar un análisis de definición de alcance para determinar esto. Pero si el programa está en forma SSA, ambos son inmediatos:
y 1 := 1 y 2 := 2 x 1 := y 2
Los algoritmos de optimización del compilador que se habilitan o mejoran notablemente mediante el uso de SSA incluyen:
- Plegado constante : conversión de cálculos de tiempo de ejecución a tiempo de compilación, por ejemplo, tratar la instrucción
a=3*4+5;como si fueraa=17; - Propagación del rango de valores [ 9 ] : precalcula los rangos potenciales que podría tener un cálculo, lo que permite la creación de predicciones de ramificación por adelantado.
- Propagación de constantes condicionales dispersas : comprobación de rango de algunos valores, lo que permite a las pruebas predecir la rama más probable.
- Eliminación de código muerto : elimine el código que no tendrá ningún efecto en los resultados.
- Numeración de valores globales : reemplaza los cálculos duplicados que producen el mismo resultado.
- Eliminación de redundancia parcial : eliminación de cálculos duplicados realizados previamente en algunas ramas del programa.
- Reducción de la complejidad : sustituir operaciones costosas por otras menos costosas pero equivalentes; por ejemplo, sustituir la multiplicación o división de enteros por potencias de 2 por el desplazamiento a la izquierda (para la multiplicación) o el desplazamiento a la derecha (para la división), que podrían ser menos costosos.
- Asignación de registros : optimizar cómo se puede utilizar el número limitado de registros de la máquina para realizar cálculos.
Conversión a SSA
Convertir código ordinario a formato SSA consiste principalmente en reemplazar el destino de cada asignación con una nueva variable y reemplazar cada uso de una variable con la "versión" de la variable que llega a ese punto. Por ejemplo, considere el siguiente diagrama de flujo de control :

Cambiar el nombre en el lado izquierdo de "xx - 3" y cambiar los siguientes usos de x a ese nuevo nombre dejaría el programa inalterado. Esto se puede aprovechar en SSA creando dos nuevas variables: x 1 y x 2 , cada una de las cuales se asigna solo una vez. Del mismo modo, dar subíndices distintivos a todas las demás variables produce:

Queda claro a qué definición se refiere cada uso, excepto en un caso: ambos usos de y en el bloque inferior podrían referirse a y 1 o a y 2 , dependiendo de la ruta que haya tomado el flujo de control.
Para resolver esto, se inserta una instrucción especial en el último bloque, llamada función Φ (Phi) . Esta instrucción generará una nueva definición de y llamada y 3 al "elegir" y 1 o y 2 , dependiendo del flujo de control anterior.

Ahora, el último bloque puede simplemente usar y 3 , y el valor correcto se obtendrá de cualquier manera. No se necesita una función Φ para x : solo una versión de x , a saber, x 2, llega a este lugar, por lo que no hay problema (en otras palabras, Φ( x 2 , x 2 )= x 2 ).
Dado un grafo de flujo de control arbitrario, puede resultar difícil determinar dónde insertar las funciones Φ y para qué variables. Esta cuestión general tiene una solución eficiente que se puede calcular utilizando un concepto denominado fronteras de dominancia (véase más adelante).
Las funciones Φ no se implementan como operaciones de máquina en la mayoría de las máquinas. Un compilador puede implementar una función Φ insertando operaciones de "movimiento" al final de cada bloque predecesor. En el ejemplo anterior, el compilador podría insertar un movimiento de y 1 a y 3 al final del bloque central izquierdo y un movimiento de y 2 a y 3 al final del bloque central derecho. Es posible que estas operaciones de movimiento no aparezcan en el código final según el procedimiento de asignación de registros del compilador . Sin embargo, este enfoque puede no funcionar cuando las operaciones simultáneas generan de forma especulativa entradas para una función Φ, como puede ocurrir en máquinas de emisión ancha . Normalmente, una máquina de emisión ancha dispone de una instrucción de selección que el compilador utiliza en estas situaciones para implementar la función Φ.
Cálculo del SSA mínimo mediante fronteras de dominancia
En un grafo de flujo de control, se dice que un nodo A domina estrictamente a otro nodo B si es imposible llegar a B sin pasar primero por A. En otras palabras, si se llega al nodo B, se puede asumir que A se ha ejecutado. Se dice que A domina a B (o que B es dominado por A) si A domina estrictamente a B o si A = B.
Un nodo que transfiere el control a un nodo A se denomina predecesor inmediato de A.
La frontera de dominancia del nodo A es el conjunto de nodos B donde A no domina estrictamente a B, pero sí domina a algún predecesor inmediato de B. Estos son los puntos donde múltiples rutas de control se fusionan en una sola ruta.
Por ejemplo, en el siguiente código:
[1] x = aleatorio() si x < 0,5 [2] resultado = "caras" demás [3] resultado = "colas" fin [4] imprimir(resultado)
El nodo 1 domina estrictamente a los nodos 2, 3 y 4, y los predecesores inmediatos del nodo 4 son los nodos 2 y 3.
Las fronteras de dominancia definen los puntos en los que se necesitan las funciones Φ. En el ejemplo anterior, cuando el control se transfiere al nodo 4, la definición resultutilizada depende de si el control se transfirió desde el nodo 2 o el 3. Las funciones Φ no son necesarias para las variables definidas en un dominador, ya que solo existe una definición posible.
Existe un algoritmo eficiente para encontrar las fronteras de dominancia de cada nodo. Este algoritmo fue descrito originalmente en "Efficiently Computing Static Single Assignment Form and the Control Graph" por Ron Cytron, Jeanne Ferrante, et al. en 1991. [ 10 ]
Keith D. Cooper, Timothy J. Harvey y Ken Kennedy de la Universidad Rice describen un algoritmo en su artículo titulado Un algoritmo de dominancia simple y rápido : [ 11 ]
para cada nodo b frontera_de_dominancia(b) := {} para cada nodo b si el número de predecesores inmediatos de b ≥ 2 para cada p en los predecesores inmediatos de b corredor := p mientras corredor ≠ idom(b) frontera_de_dominancia(corredor) := frontera_de_dominancia(corredor) ∪ { b } corredor := idom(corredor)En el código anterior, idom(b)es el dominador inmediato de b, el nodo único que domina estrictamente a b pero no domina estrictamente a ningún otro nodo que domine estrictamente a b.
Variaciones que reducen el número de funciones Φ
La implementación "Mínima" de SSA inserta el número mínimo de funciones Φ necesarias para garantizar que a cada nombre se le asigne un valor exactamente una vez y que cada referencia (uso) de un nombre en el programa original pueda seguir refiriéndose a un nombre único. (Este último requisito es necesario para garantizar que el compilador pueda escribir un nombre para cada operando en cada operación).
Sin embargo, algunas de estas funciones Φ podrían ser innecesarias . Por esta razón, el SSA mínimo no necesariamente produce la menor cantidad de funciones Φ necesarias para un procedimiento específico. Para algunos tipos de análisis, estas funciones Φ son superfluas y pueden ralentizar el proceso.
SSA podado
La forma SSA simplificada se basa en una observación simple: las funciones Φ solo son necesarias para las variables que permanecen activas después de su aplicación. (Aquí, "activa" significa que el valor se utiliza a lo largo de una ruta que comienza en la función Φ en cuestión). Si una variable no está activa, el resultado de la función Φ no se puede utilizar y la asignación realizada por dicha función queda anulada.
La construcción de la forma SSA podada utiliza información de variables activas en la fase de inserción de la función Φ para decidir si se necesita una función Φ determinada. Si el nombre de la variable original no está activo en el punto de inserción de la función Φ, esta no se inserta.
Otra posibilidad es tratar la poda como un problema de eliminación de código muerto . En ese caso, una función Φ solo se considera activa si algún uso en el programa de entrada se reescribe a ella, o si se utiliza como argumento en otra función Φ. Al entrar en la forma SSA, cada uso se reescribe a la definición más cercana que lo domina. Una función Φ se considerará activa siempre que sea la definición más cercana que domine al menos un uso, o al menos un argumento de una función Φ activa.
SSA semipodada
La forma SSA semi-podada [ 12 ] es un intento de reducir el número de funciones Φ sin incurrir en el costo relativamente alto de calcular información sobre variables activas. Se basa en la siguiente observación: si una variable nunca está activa al entrar en un bloque básico, nunca necesita una función Φ. Durante la construcción de SSA, se omiten las funciones Φ para cualquier variable "local de bloque".
Calcular el conjunto de variables locales de bloque es un procedimiento más sencillo y rápido que el análisis completo de variables en tiempo real, lo que hace que la forma SSA semi-podada sea más eficiente de calcular que la forma SSA podada. Por otro lado, la forma SSA semi-podada contendrá más funciones Φ.
argumentos de bloque
Los argumentos de bloque son una alternativa a las funciones Φ que es idéntica en representación, pero en la práctica puede ser más conveniente durante la optimización. Los bloques tienen nombre y toman una lista de argumentos de bloque, anotados como parámetros de función. Al llamar a un bloque, los argumentos de bloque se vinculan a valores específicos. MLton , Swift SIL y MLIR usan argumentos de bloque. [ 13 ] Los argumentos de bloque hacen más evidente la conexión con el estilo de paso de continuaciones (CPS): los bloques básicos son funciones, las variables de función son argumentos de bloque (funciones Φ).
Conversión del formulario de la SSA
La forma SSA no se suele utilizar para la ejecución directa (aunque es posible interpretarla [ 14 ] ), y se usa frecuentemente "sobre" otra IR con la que mantiene una correspondencia directa. Esto se puede lograr "construyendo" SSA como un conjunto de funciones que mapean partes de la IR existente (bloques básicos, instrucciones, operandos, etc. ) y su contraparte SSA. Cuando la forma SSA ya no es necesaria, estas funciones de mapeo pueden descartarse, dejando solo la IR ahora optimizada.
Realizar optimizaciones en la forma SSA generalmente conduce a redes SSA entrelazadas, lo que significa que hay instrucciones Φ cuyos operandos no tienen todos el mismo operando raíz. En tales casos, se utilizan algoritmos de eliminación de color para salir de SSA. Los algoritmos ingenuos introducen una copia a lo largo de cada ruta predecesora, lo que provoca que se coloque en Φ un símbolo raíz de origen diferente al del destino de Φ. Existen múltiples algoritmos para salir de SSA con menos copias; la mayoría utiliza grafos de interferencia o alguna aproximación de estos para realizar la coalescencia de copias. [ 15 ]
Extensiones
Las extensiones al formulario de la SSA se pueden dividir en dos categorías.
Las extensiones del esquema de cambio de nombre modifican el criterio de cambio de nombre. Recordemos que el formato SSA cambia el nombre de cada variable cuando se le asigna un valor. Los esquemas alternativos incluyen el formato estático de uso único (que cambia el nombre de cada variable en cada instrucción cuando se utiliza) y el formato estático de información única (que cambia el nombre de cada variable cuando se le asigna un valor y en la frontera de postdominancia).
Las extensiones específicas para características conservan la propiedad de asignación única para las variables, pero incorporan una nueva semántica para modelar características adicionales. Algunas extensiones específicas para características modelan características de lenguajes de programación de alto nivel, como arreglos, objetos y punteros con alias. Otras extensiones específicas para características modelan características arquitectónicas de bajo nivel, como la especulación y la predicación.
Compiladores que utilizan el formulario SSA
Código abierto
- Mono utiliza SSA en su compilador JIT llamado Mini.
- WebKit utiliza SSA en sus compiladores JIT. [ 16 ] [ 17 ]
- Swift define su propia forma SSA por encima de LLVM IR, llamada SIL (Swift Intermediate Language). [ 18 ] [ 19 ]
- El compilador de Erlang fue reescrito en OTP 22.0 para "utilizar internamente una representación intermedia basada en Asignación Única Estática (SSA)", con planes para optimizaciones adicionales basadas en SSA en futuras versiones. [ 20 ]
- La infraestructura del compilador LLVM utiliza la notación SSA para todos los valores de registro escalares (excepto la memoria) en su representación de código principal. La notación SSA solo se elimina una vez que se produce la asignación de registros, al final del proceso de compilación (a menudo en tiempo de enlace).
- La colección de compiladores GNU (GCC) utiliza ampliamente SSA desde la versión 4 (lanzada en abril de 2005). Los frontends generan código " GENERIC " que luego se convierte en código " GIMPLE " mediante el "gimplifier". Posteriormente, se aplican optimizaciones de alto nivel a la forma SSA de "GIMPLE". El código intermedio optimizado resultante se traduce a RTL , sobre el cual se aplican optimizaciones de bajo nivel. Finalmente, los backends específicos de la arquitectura convierten RTL en lenguaje ensamblador .
- Go (1.7: solo para arquitectura x86-64 ; 1.8: para todas las arquitecturas compatibles). [ 21 ] [ 22 ]
- La máquina virtual Java adaptativa de código abierto de IBM , Jikes RVM , utiliza SSA de matrices extendidas, una extensión de SSA que permite el análisis de escalares, matrices y campos de objetos en un marco unificado. El análisis de SSA de matrices extendidas solo se habilita en el nivel máximo de optimización, que se aplica a las partes del código que se ejecutan con mayor frecuencia.
- El motor JavaScript SpiderMonkey de Mozilla Firefox utiliza IR basado en SSA. [ 23 ]
- El motor JavaScript Chromium V8 implementa SSA en su infraestructura de compilación Crankshaft, tal como se anunció en diciembre de 2010.
- PyPy utiliza una representación SSA lineal para las trazas en su compilador JIT.
- El entorno de ejecución de Android [ 24 ] y la máquina virtual Dalvik utilizan SSA. [ 25 ]
- El compilador ML estándar MLton utiliza SSA en uno de sus lenguajes intermedios.
- LuaJIT hace un uso intensivo de optimizaciones basadas en SSA. [ 26 ]
- El compilador PHP y Hack HHVM utiliza SSA en su IR. [ 27 ]
- El compilador de OCaml utiliza SSA en su CMM IR (que significa C--). [ 28 ]
- libFirm, una biblioteca para usar como el backend y el middleend de un compilador , usa la forma SSA para todos los valores de registro escalares hasta la generación de código mediante el uso de un asignador de registros compatible con SSA. [ 29 ]
- Varios controladores Mesa a través de NIR, una representación SSA para lenguajes de sombreado. [ 30 ]
Comercial
- La máquina virtual Java HotSpot de Oracle utiliza un lenguaje intermedio basado en SSA en su compilador JIT. [ 31 ]
- El backend del compilador de Microsoft Visual C++ disponible en Microsoft Visual Studio 2015 Update 3 utiliza SSA [ 32 ]
- SPIR-V , el estándar de lenguaje de sombreado para la API gráfica Vulkan y lenguaje de kernel para la API de cómputo OpenCL , es una representación SSA. [ 33 ]
- DXIL , el lenguaje de sombreado para el compilador de sombreadores de Microsoft DirectX, utiliza la representación SSA debido a que es una bifurcación de LLVM. [ 34 ]
- La familia de compiladores XL de IBM, que incluye C, C++ y Fortran . [ 35 ]
- NVIDIA CUDA [ 36 ]
Investigación y abandono
- El compilador ETH Oberon-2 fue uno de los primeros proyectos públicos en incorporar "GSA", una variante de SSA.
- El compilador Open64 utiliza el formato SSA en su optimizador escalar global, aunque el código se convierte a formato SSA antes y se vuelve a convertir a formato SSA después. Open64 utiliza extensiones del formato SSA para representar la memoria en formato SSA, así como los valores escalares.
- En 2002, los investigadores modificaron JikesRVM de IBM (llamado Jalapeño en aquel entonces) para ejecutar tanto código de bytes Java estándar como archivos de clase de código de bytes SSA ( SafeTSA ) con tipado seguro, y demostraron importantes ventajas de rendimiento al usar el código de bytes SSA.
- jackcc es un compilador de código abierto para el conjunto de instrucciones académicas Jackal 3.0. Utiliza un código simple de 3 operandos con SSA para su representación intermedia. Como variante interesante, reemplaza las funciones Φ con una instrucción denominada SAME, que indica al asignador de registros que coloque los dos rangos activos en el mismo registro físico.
- El compilador de conciertos de Illinois de alrededor de 1994 [ 37 ] utilizaba una variante de SSA llamada SSU (Static Single Use) que renombra cada variable cuando se le asigna un valor y en cada contexto condicional en el que se utiliza esa variable; esencialmente la forma estática de información única mencionada anteriormente. La forma SSU está documentada en la tesis doctoral de John Plevyak .
- El compilador COINS utiliza optimizaciones de formato SSA como se explica aquí .
- El compilador R-Stream de Reservoir Labs admite formatos no SSA (lista cuádruple), SSA y SSI (Información Única Estática [ 38 ] ). [ 39 ]
- Aunque no es un compilador, el descompilador Boomerang utiliza la notación SSA en su representación interna. SSA se utiliza para simplificar la propagación de expresiones, la identificación de parámetros y valores de retorno, el análisis de preservación y mucho más.
- DotGNU Portable.NET utilizaba SSA en su compilador JIT.
Véase también
- Estilo de paso de continuaciones : forma equivalente utilizada principalmente en lenguajes de programación funcional.
- Forma normal
Referencias
Notas
- ↑ Kelsey, Richard A. (1995). "Una correspondencia entre el estilo de paso de continuación y la forma de asignación única estática" (PDF) . Artículos del taller ACM SIGPLAN de 1995 sobre representaciones intermedias . págs. 13–22 . doi : 10.1145/202529.202532 . ISBN 0897917545. S2CID 6207179 .
- ↑ Rastello y Tichadou 2022 , sec. 1.4.
- 1 2 3 Zadeck, Kenneth (abril de 2009). El desarrollo del formulario de asignación única estática (PDF) . Seminario sobre el formulario de asignación única estática . Autrans, Francia.
- ↑ Cytron, Ron; Lowry, Andy; Zadeck, F. Kenneth (1986). "Movimiento de código de estructuras de control en lenguajes de alto nivel". Actas del 13.º simposio ACM SIGACT-SIGPLAN sobre Principios de lenguajes de programación - POPL '86 . págs. 70–85 . doi : 10.1145/512644.512651 . S2CID 9099471 .
- ↑ Cytron, Ronald Kaplan; Ferrante, Jeanne. ¿Qué hay en un nombre? O el valor de renombrar para la detección de paralelismo y la asignación de almacenamiento . Conferencia Internacional sobre Procesamiento Paralelo, ICPP'87, 1987. págs. 19-27 .
- ↑ Barry Rosen; Mark N. Wegman; F. Kenneth Zadeck (1988). «Números de valor global y cálculos redundantes» (PDF) . Actas del 15.º simposio ACM SIGPLAN-SIGACT sobre principios de lenguajes de programación - POPL '88 . págs. 12-27 . doi : 10.1145/73560.73562 . ISBN 0-89791-252-7.
- ↑ Alpern, B.; Wegman, MN; Zadeck, FK (1988). "Detección de igualdad de variables en programas". Actas del 15.º simposio ACM SIGPLAN-SIGACT sobre principios de lenguajes de programación - POPL '88 . págs. 1–11 . doi : 10.1145/73560.73561 . ISBN 0897912527. S2CID 18384941 .
- ↑ Cytron, Ron; Ferrante, Jeanne; Rosen, Barry K.; Wegman, Mark N. y Zadeck, F. Kenneth (1991). "Cálculo eficiente de la forma de asignación única estática y el grafo de dependencia de control" (PDF) . ACM Transactions on Programming Languages and Systems . 13 (4): 451– 490. CiteSeerX 10.1.1.100.6361 . doi : 10.1145/115372.115320 . S2CID 13243943 .
- ↑ propagación del rango de valores
- ↑ Cytron, Ron; Ferrante, Jeanne; Rosen, Barry K.; Wegman, Mark N.; Zadeck, F. Kenneth (1 de octubre de 1991). "Cálculo eficiente de la forma de asignación única estática y el grafo de dependencia de control" . ACM Transactions on Programming Languages and Systems . 13 (4): 451– 490. doi : 10.1145/115372.115320 . S2CID 13243943 .
- ↑ Cooper, Keith D.; Harvey, Timothy J.; Kennedy, Ken (2001). Un algoritmo de dominancia simple y rápido (PDF) (Informe técnico). Universidad Rice, Informe técnico CS 06-33870. Archivado del original (PDF) el 26 de marzo de 2022.
- ↑ Briggs, Preston; Cooper, Keith D.; Harvey, Timothy J.; Simpson, L. Taylor (1998). Mejoras prácticas para la construcción y destrucción de formularios estáticos de asignación única (PDF) (Informe técnico). Archivado del original (PDF) el 7 de junio de 2010.
- ↑ "Argumentos de bloque frente a nodos PHI - Fundamentos de MLIR" . mlir.llvm.org . Consultado el 4 de marzo de 2022 .
- ↑ von Ronne, Jeffery; Ning Wang; Michael Franz (2004). "Interpretación de programas en formato de asignación única estática" . Actas del taller de 2004 sobre intérpretes, máquinas virtuales y emuladores - IVME '04 . pág. 23. doi : 10.1145/1059579.1059585 . ISBN 1581139098. S2CID 451410 .
- ^ Boissinot, Benoît; Darté, Alain; Rastello, Fabrice; Dinechin, Benoît Dupont de; Guillón, Christophe (2008). "Revisando la traducción fuera de SSA para determinar la corrección, la calidad del código y la eficiencia" . HAL-Inria Cs.DS : 14.
- ↑ "Presentación del JIT FTL de WebKit" . 13 de mayo de 2014.
- ↑ "Presentación del compilador JIT B3" . 15 de febrero de 2016.
- ↑ "Swift Intermediate Language (GitHub)" . GitHub . 30 de octubre de 2021.
- ↑ "Swift's High-Level IR: A Case Study of Complementing LLVM IR with Language-Specific Optimization, LLVM Developers Meetup 10/2015" . YouTube . 9 de noviembre de 2015. Archivado del original el 21 de diciembre de 2021.
- ↑ "Notas de la versión OTP 22.0" .
- ↑ "Notas de la versión 1.7 de Go - El lenguaje de programación Go" . golang.org . Consultado el 17 de agosto de 2016 .
- ↑ "Notas de la versión 1.8 de Go - El lenguaje de programación Go" . golang.org . Consultado el 17 de febrero de 2017 .
- ↑ "Descripción general de IonMonkey" .,
- ↑ La evolución del ART - Google I/O 2016. Google . 25 de mayo de 2016. El evento ocurre a los 3m47s.
- ^ Ramanan, Neeraja (12 de diciembre de 2011). "JIT a través de los tiempos" (PDF) .
- ↑ "Optimizaciones de código de bytes" . El proyecto LuaJIT.
- ↑ "Representación intermedia de Hip Hop (HHIR)" . GitHub . 30 de octubre de 2021.
- ↑ Chambart, Pierre; Laviron, Vincent; Pinto, Dario (2024-03-18). "Detrás de escena del compilador optimizador de OCaml" . OCaml Pro .
- ↑ "Empresa - Optimización y generación de código máquina" .
- ^ Ekstrand, Jason (16 de diciembre de 2014). "Reintroduciendo NIR, un nuevo IR para mesa" .
- ↑ "Arquitectura del motor de rendimiento Java HotSpot" . Oracle Corporation.
- ↑ "Presentamos un nuevo y avanzado optimizador de código para Visual C++" . 4 de mayo de 2016.
- ↑ "Especificación SPIR-V" (PDF) .
- ↑ "Lenguaje intermedio de DirectX" . Microsoft.
- ↑ Sarkar, V. (mayo de 1997). "Selección automática de transformaciones de alto orden en los compiladores IBM XL FORTRAN" (PDF) . IBM Journal of Research and Development . 41 (3). IBM: 233–264 . doi : 10.1147/rd.413.0233 .
- ↑ Chakrabarti, Gautam; Grover, Vinod; Aarts, Bastiaan; Kong, Xiangyun; Kudlur, Manjunath; Lin, Yuan; Marathe, Jaydeep; Murphy, Mike; Wang, Jian-Zhong (2012). "CUDA: Compilación y optimización para una plataforma GPU" . Procedia Computer Science . 9 : 1910–1919 . doi : 10.1016/j.procs.2012.04.209 .
- ↑ "Illinois Concert Project" . Archivado del original el 13 de marzo de 2014.
- ↑ Ananian, C. Scott; Rinard, Martin (1999). Formulario de información única estática (PDF) (Informe técnico). CiteSeerX 10.1.1.1.9976 .
- ↑ Enciclopedia de Computación Paralela .
Referencias generales
- Rastello, Fabrice; Tichadou, Florent Bouchez, eds. (2022). Diseño de compilador basado en SSA (PDF) . Cham. doi : 10.1007/978-3-030-80515-9 . ISBN 978-3-030-80515-9. S2CID 63274602 .
{{cite book}}: CS1 mantenimiento: falta el editor de ubicación ( enlace ) - Appel, Andrew W. (1999). Modern Compiler Implementation in ML . Cambridge University Press. ISBN 978-0-521-58274-2.También disponible en Java ( ISBN) 0-521-82060-X, 2002) y C ( ISBN 0-521-60765-5versiones de 1998.
- Cooper, Keith D. y Torczon, Linda (2003). Ingeniería de un compilador . Morgan Kaufmann. ISBN 978-1-55860-698-2.
- Muchnick, Steven S. (1997). Diseño e implementación avanzados de compiladores . Morgan Kaufmann. ISBN 978-1-55860-320-2.
- Kelsey, Richard A. (marzo de 1995). "Una correspondencia entre el estilo de paso de continuación y la forma de asignación única estática" . ACM SIGPLAN Notices . 30 (3): 13– 22. doi : 10.1145/202530.202532 .
- Appel, Andrew W. (abril de 1998). "SSA es programación funcional" . ACM SIGPLAN Notices . 33 (4): 17– 20. doi : 10.1145/278283.278285 . S2CID 207227209 .
- Pop, Sebastian (2006). El marco de representación SSA: semántica, análisis e implementación GCC (tesis doctoral). École des Mines de Paris .
- Matthias Braun; Sebastian Buchwald; Sebastian Hack; Roland Leißa; Christoph Mallon; Andreas Zwinkau (2013), "Construcción simple y eficiente de la forma de asignación única estática" , Compiler Construction , Lecture Notes in Computer Science, vol. 7791, Springer Berlin Heidelberg, pp. 102–122 , doi : 10.1007/978-3-642-37051-9_6 , ISBN 978-3-642-37050-2Consultado el 24 de marzo de 2013.
Enlaces externos
- Bosscher, Steven; y Novillo, Diego. GCC obtiene un nuevo marco de optimización . Un artículo sobre el uso de SSA por parte de GCC y cómo mejora con respecto a las versiones anteriores de IR.
- La bibliografía del SSA . Amplio catálogo de trabajos de investigación sobre el SSA.
- Zadeck, F. Kenneth. "El desarrollo del formato de asignación única estática" , charla de diciembre de 2007 sobre los orígenes de SSA.
- Optimizaciones del compilador