stringtranslate.com

LLVM

LLVM es un conjunto de tecnologías de compilación y cadena de herramientas [4] que se pueden utilizar para desarrollar un frontend para cualquier lenguaje de programación y un backend para cualquier arquitectura de conjunto de instrucciones . LLVM está diseñado en torno a una representación intermedia (IR) independiente del lenguaje que sirve como un lenguaje ensamblador portátil de alto nivel que se puede optimizar con una variedad de transformaciones en múltiples pasadas. [5] El nombre LLVM originalmente significaba Low Level Virtual Machine, aunque el proyecto se ha expandido y el nombre ya no es oficialmente un acrónimo .

LLVM está escrito en C++ y está diseñado para la optimización en tiempo de compilación , tiempo de enlace , tiempo de ejecución y "tiempo de inactividad". Originalmente implementado para C y C++, el diseño agnóstico del lenguaje de LLVM ha generado desde entonces una amplia variedad de interfaces: los lenguajes con compiladores que usan LLVM (o que no usan directamente LLVM pero pueden generar programas compilados como LLVM IR) incluyen ActionScript , Ada , C# para .NET , [6] [7] [8] Common Lisp , PicoLisp , Crystal , CUDA , D , Delphi , Dylan , Forth , [9] Fortran , FreeBASIC , Free Pascal , Halide , Haskell , Java bytecode , Julia , Kotlin , el lenguaje G de LabVIEW , [10] [11] Lua , Objective-C , OpenCL , [12] SQL y PLpgSQL de PostgreSQL , [13] Ruby , [14] Rust , [15] Scala , [16] [17] Swift , Xojo , y Zig .

Historia

El proyecto LLVM comenzó en 2000 en la Universidad de Illinois en Urbana-Champaign , bajo la dirección de Vikram Adve y Chris Lattner . LLVM se desarrolló originalmente como una infraestructura de investigación para investigar técnicas de compilación dinámica para lenguajes de programación estáticos y dinámicos . LLVM se lanzó bajo la Licencia de código abierto de la Universidad de Illinois/NCSA , [3] una licencia de software libre permisiva . En 2005, Apple Inc. contrató a Lattner y formó un equipo para trabajar en el sistema LLVM para varios usos dentro de los sistemas de desarrollo de Apple. [18] LLVM ha sido una parte integral de las herramientas de desarrollo Xcode de Apple para macOS e iOS desde Xcode 4 en 2011. [19]

En 2006, Lattner comenzó a trabajar en un nuevo proyecto llamado Clang . La combinación del frontend de Clang y el backend de LLVM se llama Clang/LLVM o simplemente Clang.

El nombre LLVM era originalmente un acrónimo de Low Level Virtual Machine . Sin embargo, el proyecto LLVM evolucionó hasta convertirse en un proyecto paraguas que tiene poca relación con lo que la mayoría de los desarrolladores actuales consideran una máquina virtual . Esto hizo que el acrónimo fuera "confuso" e "inapropiado", y desde 2011 LLVM "oficialmente ya no es un acrónimo", [20] sino una marca que se aplica al proyecto paraguas LLVM. [21] El proyecto abarca la representación intermedia (IR) de LLVM, el depurador de LLVM , la implementación de LLVM de la biblioteca estándar de C++ (con soporte completo de C++11 y C++14 [22] ), etc. LLVM es administrado por la Fundación LLVM. La ingeniera de compiladores Tanya Lattner se convirtió en su presidenta en 2014 [23] y ocupó el cargo a partir de marzo de 2024. [ 24]

"Por el diseño e implementación de LLVM" , la Asociación para Maquinaria Computacional le otorgó a Vikram Adve, Chris Lattner y Evan Cheng el Premio al Sistema de Software ACM 2012. [25]

El proyecto estaba originalmente disponible bajo la licencia UIUC . Después del lanzamiento de la versión v9.0.0 en 2019, [26] LLVM cambió su licencia a la Licencia Apache 2.0 con Excepciones LLVM. [3] A noviembre de 2022, alrededor de 400 contribuciones no habían cambiado su licencia. [27] [28]

Características

LLVM puede proporcionar las capas intermedias de un sistema de compilador completo, tomando el código de representación intermedia (IR) de un compilador y emitiendo un IR optimizado. Este nuevo IR puede luego convertirse y vincularse a un código de lenguaje ensamblador dependiente de la máquina para una plataforma de destino. LLVM puede aceptar el IR de la cadena de herramientas de GNU Compiler Collection (GCC) , lo que permite su uso con una amplia gama de interfaces de compilador existentes escritas para ese proyecto. LLVM también puede construirse con gcc después de la versión 7.5. [29]

LLVM también puede generar código de máquina reubicable en tiempo de compilación o de enlace o incluso código de máquina binario en tiempo de ejecución.

LLVM admite un conjunto de instrucciones y un sistema de tipos independientes del lenguaje . [5] Cada instrucción está en forma de asignación única estática (SSA), lo que significa que cada variable (llamada registro tipificado) se asigna una vez y luego se congela. Esto ayuda a simplificar el análisis de dependencias entre variables. LLVM permite que el código se compile estáticamente, como en el sistema GCC tradicional, o se deje para una compilación tardía desde el IR al código de máquina mediante la compilación justo a tiempo (JIT), similar a Java . El sistema de tipos consta de tipos básicos como números enteros o de punto flotante y cinco tipos derivados : punteros , matrices , vectores , estructuras y funciones . Una construcción de tipo en un lenguaje concreto se puede representar combinando estos tipos básicos en LLVM. Por ejemplo, una clase en C++ se puede representar mediante una mezcla de estructuras, funciones y matrices de punteros de función .

El compilador JIT de LLVM puede optimizar las ramas estáticas innecesarias de un programa en tiempo de ejecución y, por lo tanto, es útil para la evaluación parcial en casos en los que un programa tiene muchas opciones, la mayoría de las cuales se pueden determinar fácilmente como innecesarias en un entorno específico. Esta característica se utiliza en la canalización OpenGL de Mac OS X Leopard (v10.5) para brindar soporte para las características de hardware faltantes. [30]

El código gráfico dentro de la pila OpenGL se puede dejar en una representación intermedia y luego compilarlo cuando se ejecuta en la máquina de destino. En sistemas con unidades de procesamiento gráfico (GPU) de alta gama, el código resultante sigue siendo bastante fino, pasando las instrucciones a la GPU con cambios mínimos. En sistemas con GPU de gama baja, LLVM compilará procedimientos opcionales que se ejecutan en la unidad central de procesamiento (CPU) local que emulan instrucciones que la GPU no puede ejecutar internamente. LLVM mejoró el rendimiento en máquinas de gama baja que utilizan chipsets Intel GMA . Se desarrolló un sistema similar bajo el LLVMpipe de Gallium3D y se incorporó al shell de GNOME para permitir que se ejecutara sin un controlador de hardware 3D adecuado cargado. [31]

En 2011, los programas compilados por GCC superaron a los de LLVM en un 10%, en promedio. [32] [33] En 2013, phoronix informó que LLVM había alcanzado a GCC, compilando binarios de rendimiento aproximadamente igual. [34]

Componentes

LLVM se ha convertido en un proyecto general que contiene múltiples componentes.

Interfaces

LLVM fue escrito originalmente para ser un reemplazo para el generador de código existente en la pila GCC, [35] y muchos de los frontends de GCC han sido modificados para trabajar con él, dando como resultado la suite LLVM-GCC ahora extinta. Las modificaciones generalmente involucran un paso IR de GIMPLE a LLVM para que los optimizadores y el generador de código de LLVM se puedan usar en lugar del sistema GIMPLE de GCC. Apple fue un usuario significativo de LLVM-GCC hasta Xcode 4.x (2013). [36] [37] Este uso del frontend de GCC se consideró principalmente una medida temporal, pero con la llegada de Clang y las ventajas de LLVM y la base de código modular y moderna de Clang (así como la velocidad de compilación), está prácticamente obsoleto.

LLVM actualmente [¿ a partir de? ] admite la compilación de Ada , C , C++ , D , Delphi , Fortran , Haskell , Julia , Objective-C , Rust y Swift mediante varias interfaces .

El interés generalizado en LLVM ha llevado a varios esfuerzos para desarrollar nuevas interfaces para muchos lenguajes. El que ha recibido más atención es Clang, un compilador más nuevo que soporta C, C++ y Objective-C. Clang, soportado principalmente por Apple, tiene como objetivo reemplazar el compilador C/Objective-C en el sistema GCC con un sistema que se integra más fácilmente con entornos de desarrollo integrados (IDE) y tiene un soporte más amplio para subprocesos múltiples . El soporte para directivas OpenMP se ha incluido en Clang desde la versión 3.8. [38]

El compilador Utrecht Haskell puede generar código para LLVM. Si bien el generador se encontraba en las primeras etapas de desarrollo, en muchos casos era más eficiente que el generador de código C. [39] El backend Glasgow Haskell Compiler (GHC) utiliza LLVM y logra una aceleración del 30 % del código compilado en relación con la compilación de código nativo a través de GHC o la generación de código C seguida de compilación, sin contar solo una de las muchas técnicas de optimización implementadas por GHC. [40]

Muchos otros componentes se encuentran en diversas etapas de desarrollo, incluidos, entre otros, el compilador Rust , una interfaz de código de bytes de Java , una interfaz de lenguaje intermedio común (CIL), la implementación MacRuby de Ruby 1.9, varias interfaces para Standard ML y un nuevo asignador de registros de coloración de gráficos . [ cita requerida ]

Representación intermedia

LLVM IR lo utilizan, por ejemplo, Radeonsi y Llvmpipe. Ambos forman parte de Mesa 3D .

El núcleo de LLVM es la representación intermedia (IR), un lenguaje de programación de bajo nivel similar al lenguaje ensamblador. IR es un conjunto de instrucciones de computadora de conjunto reducido de instrucciones fuertemente tipado (RISC) que abstrae la mayoría de los detalles del objetivo. Por ejemplo, la convención de llamada se abstrae a través de instrucciones cally retcon argumentos explícitos. Además, en lugar de un conjunto fijo de registros, IR utiliza un conjunto infinito de temporales de la forma %0, %1, etc. LLVM admite tres formas equivalentes de IR: un formato de ensamblaje legible para humanos, [41] un formato en memoria adecuado para frontends y un formato de código de bits denso para serialización. Un programa simple "¡Hola, mundo!" en formato IR:

@.str = constante interna [ 14 x i8 ] c "Hola, mundo\0A\00"       declarar i32 @printf ( ptr , ...)   definir i32 @main ( i32 %argc , ptr %argv ) nounwind { entrada: %tmp1 = getelementptr [ 14 x i8 ], ptr @.str , i32 0 , i32 0 %tmp2 = llamar a i32 ( ptr , ...) @printf ( ptr %tmp1 ) nounwind ret i32 0 }                                 

Las diferentes convenciones utilizadas y las características proporcionadas por los distintos objetivos significan que LLVM no puede producir verdaderamente un IR independiente del objetivo y redirigirlo sin romper algunas reglas establecidas. Se pueden encontrar ejemplos de dependencia del objetivo más allá de lo que se menciona explícitamente en la documentación en una propuesta de 2011 para "wordcode", una variante totalmente independiente del objetivo de LLVM IR destinada a la distribución en línea. [42] Un ejemplo más práctico es PNaCl . [43]

El proyecto LLVM también introduce otro tipo de representación intermedia denominada MLIR [44] que ayuda a construir una infraestructura de compilador reutilizable y extensible mediante el empleo de una arquitectura de complemento denominada Dialect. [45] Permite el uso de información de nivel superior sobre la estructura del programa en el proceso de optimización, incluida la compilación poliédrica .

Backends

En la versión 16, LLVM admite muchos conjuntos de instrucciones , incluidos IA-32 , x86-64 , ARM , Qualcomm Hexagon , LoongArch , M68K , MIPS , NVIDIA Parallel Thread Execution (PTX, también llamado NVPTX en la documentación de LLVM), PowerPC , AMD TeraScale , [46] las GPU AMD más recientes (también llamadas AMDGPU en la documentación de LLVM), [47] SPARC , z/Architecture (también llamado SystemZ en la documentación de LLVM) y XCore .

Algunas funciones no están disponibles en algunas plataformas. La mayoría de las funciones están presentes para IA-32, x86-64, z/Architecture, ARM y PowerPC. [48] RISC-V es compatible a partir de la versión 7.

En el pasado, LLVM también soportaba otros backends, total o parcialmente, incluyendo C backend, Cell SPU , mblaze (MicroBlaze) , [49] AMD R600, DEC/Compaq Alpha ( Alpha AXP ) [50] y Nios2 , [51] pero ese hardware está mayormente obsoleto, y los desarrolladores de LLVM decidieron que los costos de soporte y mantenimiento ya no estaban justificados. [ cita requerida ]

LLVM también admite WebAssembly como destino, lo que permite que los programas compilados se ejecuten en entornos habilitados para WebAssembly, como Google Chrome / Chromium , Firefox , Microsoft Edge , Apple Safari o WAVM. Los compiladores WebAssembly compatibles con LLVM generalmente admiten código fuente mayoritariamente sin modificar escrito en C, C++, D, Rust, Nim, Kotlin y varios otros lenguajes.

El subproyecto de código de máquina (MC) de LLVM es el marco de trabajo de LLVM para traducir instrucciones de máquina entre formatos textuales y código de máquina. Anteriormente, LLVM dependía del ensamblador del sistema, o de uno proporcionado por una cadena de herramientas, para traducir el ensamblador a código de máquina. El ensamblador integrado de LLVM MC es compatible con la mayoría de los objetivos de LLVM, incluidos IA-32, x86-64, ARM y ARM64. Para algunos objetivos, incluidos los diversos conjuntos de instrucciones MIPS, se puede utilizar la compatibilidad con el ensamblador integrado, pero aún se encuentra en la etapa beta. [ cita requerida ]

Enlazador

El subproyecto lld es un intento de desarrollar un enlazador integrado e independiente de la plataforma para LLVM. [52] lld tiene como objetivo eliminar la dependencia de un enlazador de terceros. A partir de mayo de 2017 , lld admite ELF , PE/COFF , Mach-O y WebAssembly [53] en orden descendente de completitud. lld es más rápido que ambas versiones de GNU ld . [ cita requerida ]

A diferencia de los enlazadores GNU, lld tiene soporte integrado para optimización en tiempo de enlace (LTO). Esto permite una generación de código más rápida ya que evita el uso de un complemento enlazador, pero por otro lado prohíbe la interoperabilidad con otras versiones de LTO. [54]

Biblioteca estándar de C++

El proyecto LLVM incluye una implementación de la biblioteca estándar de C++ denominada libc++, con doble licencia bajo la licencia MIT y la licencia UIUC . [55]

Desde la versión v9.0.0, se le cambió la licencia a la Licencia Apache 2.0 con excepciones LLVM. [3]

Polly

Esto implementa un conjunto de optimizaciones de localidad de caché, así como autoparalelismo y vectorización utilizando un modelo poliédrico . [56]

Depurador

Biblioteca estándar C

llvm-libc es una biblioteca estándar C incompleta, próxima a aparecer, independiente de ABI, diseñada por y para el proyecto LLVM. [57]

Derivados

Debido a su licencia permisiva, muchos proveedores publican sus propios diapasones de LLVM. Esto está reconocido oficialmente por la documentación de LLVM, que sugiere no usar números de versión en las comprobaciones de características por este motivo. [58] Algunos de los proveedores incluyen:

Véase también

Literatura

Referencias

  1. ^ "Logotipo de LLVM". Proyecto de infraestructura del compilador LLVM .
  2. ^ "Lanzamiento de LLVM 19.1.2 · llvm/llvm-project" . Consultado el 16 de octubre de 2024 .
  3. ^ abcd "LICENCIA.TXT". llvm.org . Consultado el 24 de septiembre de 2019 .
  4. ^ "El proyecto de infraestructura del compilador LLVM" . Consultado el 11 de marzo de 2016 .
  5. ^ ab "Manual de referencia del lenguaje LLVM" . Consultado el 9 de junio de 2019 .
  6. ^ "Anuncio de LLILC: un nuevo compilador basado en LLVM para .NET". dotnetfoundation.org . Archivado desde el original el 12 de diciembre de 2021 . Consultado el 12 de septiembre de 2020 .
  7. ^ "Mono LLVM" . Consultado el 10 de marzo de 2013 .
  8. ^ Lattner, Chris (2011). "LLVM". En Brown, Amy; Wilson, Greg (eds.). La arquitectura de las aplicaciones de código abierto.
  9. ^ "Movimiento". GitHub . 28 de noviembre de 2021.
  10. ^ William Wong (23 de mayo de 2017). "¿Cuál es la diferencia entre LabVIEW 2017 y LabVIEW NXG?". Diseño electrónico .
  11. ^ "Compilador NI LabVIEW: bajo el capó".
  12. ^ Larabel, Michael (11 de abril de 2018). "Khronos anuncia oficialmente su traductor LLVM/SPIR-V". Phoronix.com .
  13. ^ "32.1. ¿Qué es la compilación JIT?". Documentación de PostgreSQL . 12 de noviembre de 2020 . Consultado el 25 de enero de 2021 .
  14. ^ "Características". RubyMotion . Scratchwork Development LLC . Consultado el 17 de junio de 2017 . RubyMotion transforma el código fuente Ruby de su proyecto en ... código de máquina utilizando un compilador anticipado (AOT), basado en LLVM.
  15. ^ "Generación de código: guía para el desarrollo de Rustc". rust-lang.org . Consultado el 4 de enero de 2023 .
  16. ^ Reedy, Geoff (24 de septiembre de 2012). "Compiling Scala to LLVM". St. Louis, Missouri, Estados Unidos . Consultado el 19 de febrero de 2013 .
  17. ^ "Scala Native" . Consultado el 26 de noviembre de 2023 .
  18. ^ Adam Treat (19 de febrero de 2005), mkspecs y parches para la compilación LLVM de Qt4, archivado desde el original el 4 de octubre de 2011 , consultado el 27 de enero de 2012
  19. ^ "Descripción general de las herramientas para desarrolladores". Apple Developer . Apple. Archivado desde el original el 23 de abril de 2011.
  20. ^ Lattner, Chris (21 de diciembre de 2011). «El nombre de LLVM». llvm-dev (Lista de correo) . Consultado el 2 de marzo de 2016 ."LLVM" ya no es oficialmente un acrónimo. El acrónimo al que se amplió en el pasado resultó confuso e inapropiado casi desde el primer día. :) A medida que LLVM fue creciendo y abarcó otros subproyectos, se volvió aún menos útil y carente de sentido.
  21. ^ Lattner, Chris (1 de junio de 2011). "LLVM". En Brown, Amy; Wilson, Greg (eds.). La arquitectura de las aplicaciones de código abierto . Lulu.com. ISBN 978-1257638017El nombre «LLVM» alguna vez fue un acrónimo, pero ahora es solo una marca para el proyecto general .
  22. ^ ""libc++" Biblioteca estándar de C++".
  23. ^ Lattner, Chris (3 de abril de 2014). "La Fundación LLVM". Blog del proyecto LLVM .
  24. ^ "Junta Directiva". Fundación LLVM . Consultado el 19 de marzo de 2024 .
  25. ^ "Premio ACM al mejor sistema de software". ACM.
  26. ^ Wennborg, Hans (19 de septiembre de 2019). "[llvm-announce] Lanzamiento de LLVM 9.0.0".
  27. ^ "Renovación de la licencia de Long Tail". foundation.llvm.org . 11 de noviembre de 2022.
  28. ^ "Relicenciamiento de LLVM: cola larga". Proyecto LLVM . Consultado el 27 de noviembre de 2022 a través de Google Docs.
  29. ^ "⚙ D156286 [docs] Aumento de la versión mínima de GCC a 7.5". reviews.llvm.org . Consultado el 28 de julio de 2023 .
  30. ^ Lattner, Chris (15 de agosto de 2006). "Un uso interesante de LLVM en Apple: la pila OpenGL". llvm-dev (Lista de correo) . Consultado el 1 de marzo de 2016 .
  31. ^ Michael Larabel, "GNOME Shell funciona sin compatibilidad con controladores de GPU", phoronix , 6 de noviembre de 2011
  32. ^ Makarov, V. "SPEC2000: Comparación de LLVM-2.9 y GCC4.6.1 en x86" . Consultado el 3 de octubre de 2011 .
  33. ^ Makarov, V. «SPEC2000: Comparación de LLVM-2.9 y GCC4.6.1 en x86_64» . Consultado el 3 de octubre de 2011 .
  34. ^ Larabel, Michael (27 de diciembre de 2012). "El compilador LLVM/Clang 3.2 compite con GCC" . Consultado el 31 de marzo de 2013 .
  35. ^ Lattner, Chris ; Adve, Vikram (mayo de 2003). Architecture For a Next-Generation GCC. First Annual GCC Developers' Summit . Consultado el 6 de septiembre de 2009 .
  36. ^ "Descripción general del compilador LLVM". developer.apple.com .
  37. ^ "Notas de la versión de Xcode 5". Apple Inc.
  38. ^ "Notas de la versión de Clang 3.8" . Consultado el 24 de agosto de 2016 .
  39. ^ "Compiling Haskell To LLVM" (Compilación de Haskell en LLVM) . Consultado el 22 de febrero de 2009 .
  40. ^ "Blog del proyecto LLVM: El compilador Glasgow Haskell y LLVM". 17 de mayo de 2010. Consultado el 13 de agosto de 2010 .
  41. ^ "Manual de referencia del lenguaje LLVM". LLVM.org . 10 de enero de 2023.
  42. ^ Kang, Jin-Gu. "Wordcode: código de bits LLVM más independiente del objetivo" (PDF) . Consultado el 1 de diciembre de 2019 .
  43. ^ "PNaCl: Portable Native Client Executables" (PDF) . Archivado desde el original (PDF) el 2 de mayo de 2012. Consultado el 25 de abril de 2012 .
  44. ^ "MLIR". mlir.llvm.org . Consultado el 7 de junio de 2022 .
  45. ^ "Dialectos - MLIR". mlir.llvm.org . Consultado el 7 de junio de 2022 .
  46. ^ Stellard, Tom (26 de marzo de 2012). "[LLVMdev] RFC: R600, un nuevo backend para GPU AMD". llvm-dev (Lista de correo).
  47. ^ "Guía del usuario para AMDGPU Backend — Documentación LLVM 15.0.0git".
  48. ^ Notas de implementación específicas del objetivo: Matriz de características del objetivo // El generador de código independiente del objetivo LLVM, sitio LLVM.
  49. ^ "Eliminar el backend mblaze de llvm". GitHub . 25 de julio de 2013 . Consultado el 26 de enero de 2020 .
  50. ^ "Eliminar el backend Alpha". GitHub . 27 de octubre de 2011 . Consultado el 26 de enero de 2020 .
  51. ^ "[Nios2] Eliminar el backend de Nios2". GitHub . 15 de enero de 2019 . Consultado el 26 de enero de 2020 .
  52. ^ "lld - El enlazador LLVM". El proyecto LLVM . Consultado el 10 de mayo de 2017 .
  53. ^ "Puerto lld de WebAssembly".
  54. ^ "42446 – lld no puede manejar archivos LTO gcc". bugs.llvm.org .
  55. ^ ""libc++" Biblioteca estándar de C++".
  56. ^ "Polly - Optimizaciones poliédricas para LLVM".
  57. ^ "llvm-libc: una biblioteca estándar compatible con ISO C — documentación de libc 15.0.0git". libc.llvm.org . Consultado el 18 de julio de 2022 .
  58. ^ "Extensiones del lenguaje Clang". Documentación de Clang 12. Tenga en cuenta que no se deben utilizar los números de versión de marketing para comprobar las características del lenguaje, ya que los distintos proveedores utilizan distintos esquemas de numeración. En su lugar, utilice las macros de comprobación de características.
  59. ^ "apple/llvm-project". Apple. 5 de septiembre de 2020.
  60. ^ "Los compiladores IBM C/C++ y Fortran adoptarán la infraestructura de código abierto LLVM".
  61. ^ "Los compiladores Intel C/C++ completan la adopción de LLVM". Intel . Consultado el 17 de agosto de 2021 .
  62. ^ "lanl/kitsune". Laboratorio Nacional de Los Álamos. 27 de febrero de 2020.
  63. ^ "Especificación NVVM IR 1.5". La NVVM IR actual se basa en LLVM 5.0
  64. ^ Cadena de herramientas para desarrolladores de ps4 (PDF) , consultado el 24 de febrero de 2015
  65. ^ Lattner, Chris (15 de marzo de 2012). "Capítulo 11". La arquitectura de las aplicaciones de código abierto . Amy Brown, Greg Wilson. ISBN 978-1257638017.

Enlaces externos