LLVM se ha convertido en un proyecto paraguas que contiene múltiples componentes.
Front endsEdit
LLVM fue escrito originalmente para ser un reemplazo del generador de código existente en la pila de GCC, y muchos de los front ends de GCC han sido modificados para trabajar con él, resultando en la ahora desaparecida suite LLVM-GCC. Las modificaciones generalmente implican un paso de GIMPLE a LLVM IR para poder utilizar los optimizadores y el codegen de LLVM en lugar del sistema GIMPLE de GCC. Apple fue un importante usuario de LLVM-GCC a través de Xcode 4.x (2013). Este uso del frontend de GCC se consideró sobre todo una medida temporal, pero con la llegada de Clang y las ventajas de LLVM y la base de código moderna y modular de Clang (así como la velocidad de compilación), es en su mayoría obsoleta.
LLVM actualmente soporta la compilación de Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust, y Swift usando varios front ends.
El interés generalizado en LLVM ha llevado a varios esfuerzos para desarrollar nuevos front ends para una variedad de lenguajes. El que ha recibido más atención es Clang, un nuevo compilador que soporta C, C++ y Objective-C. Apoyado principalmente por Apple, Clang pretende sustituir el compilador de C-Objetivo-C del sistema GCC por un sistema que se integre más fácilmente con los entornos de desarrollo integrados (IDE) y tenga un mayor soporte para el multihilo. El soporte para las directivas OpenMP se ha incluido en Clang desde la versión 3.8.
El compilador Haskell de Utrecht puede generar código para LLVM. Aunque el generador está en las primeras etapas de desarrollo, en muchos casos ha sido más eficiente que el generador de código C. Existe un backend del compilador Glasgow Haskell (GHC) que utiliza LLVM y que consigue una aceleración del 30% del código compilado respecto a la compilación de código nativo mediante GHC o la generación de código C seguida de compilación, faltando sólo una de las muchas técnicas de optimización implementadas por el GHC.
Muchos otros componentes están en varias etapas de desarrollo, incluyendo, pero no limitado a, el compilador de Rust, un front-end de bytecode Java, un front-end de Common Intermediate Language (CIL), la implementación de MacRuby de Ruby 1.9, varios frontales para Standard ML, y un nuevo asignador de registros para colorear gráficos.
Representación intermediaEditar
El núcleo de LLVM es la representación intermedia (IR), un lenguaje de programación de bajo nivel similar al ensamblador. IR es un conjunto de instrucciones RISC (reduced instruction set computing) fuertemente tipado que abstrae la mayoría de los detalles del objetivo. Por ejemplo, la convención de llamada se abstrae mediante instrucciones call y ret con 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 soporta tres formas equivalentes de IR: un formato de ensamblaje legible por humanos, un formato en memoria adecuado para frontends, y un formato de código de bits denso para serializar. Un simple programa «¡Hola, mundo!» en el formato IR:
@.str = internal constant c"hello, world\0A\00"declare i32 @printf(i8*, ...)define i32 @main(i32 %argc, i8** %argv) nounwind {entry: %tmp1 = getelementptr , * @.str, i32 0, i32 0 %tmp2 = call i32 (i8*, ...) @printf( i8* %tmp1 ) nounwind ret i32 0}
Las muchas convenciones diferentes utilizadas y las características proporcionadas por los diferentes objetivos significan que LLVM no puede producir realmente un IR independiente del objetivo y retargeting sin romper algunas reglas establecidas. Ejemplos de dependencia del objetivo más allá de lo que se menciona explícitamente en la documentación se pueden encontrar en una propuesta de 2011 para «wordcode», una variante totalmente independiente del objetivo de LLVM IR destinada a la distribución en línea. Un ejemplo más práctico es PNaCl.
Finalidades de la edición
En la versión 3.4, LLVM soporta muchos conjuntos de instrucciones, incluyendo ARM, Qualcomm Hexagon, MIPS, Nvidia Parallel Thread Execution (PTX; llamado NVPTX en la documentación de LLVM), PowerPC, AMD TeraScale, AMD Graphics Core Next (GCN), SPARC, z/Architecture (llamado SystemZ en la documentación de LLVM), x86, x86-64, y XCore. Algunas características no están disponibles en algunas plataformas. La mayoría de las funciones están presentes en x86, x86-64, z/Architecture, ARM y PowerPC. RISC-V está soportado a partir de la versión 7. En el pasado LLVM también soportaba total o parcialmente otros backends, incluyendo C backend, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) y Nios2, pero la mayor parte de este hardware es en su mayoría obsoleto, y el soporte y mantenimiento de LLVM para él no podría justificarse.
LLVM también es compatible con WebAssembly como objetivo, permitiendo que los programas compilados se ejecuten en entornos habilitados para WebAssembly como Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari o WAVM. Los compiladores de WebAssembly compatibles con LLVM suelen admitir, en su mayoría, código fuente sin modificar escrito en C, C++, D, Rust, Nim, Kotlin y varios otros lenguajes.
El subproyecto de código máquina (MC) de LLVM es el marco de trabajo de LLVM para traducir las instrucciones de la máquina entre las formas textuales y el código máquina. Anteriormente, LLVM dependía del ensamblador del sistema, o de uno proporcionado por una cadena de herramientas, para traducir el ensamblaje a código máquina. El ensamblador integrado de LLVM soporta la mayoría de los objetivos de LLVM, incluyendo x86, x86-64, ARM y ARM64. Para algunos objetivos, incluyendo los diversos conjuntos de instrucciones MIPS, el soporte de ensamblaje integrado es utilizable pero todavía en la etapa beta.
LinkerEdit
El subproyecto lld es un intento de desarrollar un enlazador integrado e independiente de la plataforma para LLVM. lld tiene como objetivo eliminar la dependencia de un enlazador de terceros. A partir de mayo de 2017, lld es compatible con ELF, PE/COFF, Mach-O y WebAssembly en orden descendente de integridad. lld es más rápido que ambos sabores de GNU ld.
A diferencia de los enlazadores de GNU, lld tiene soporte incorporado para la optimización en tiempo de enlace. Esto permite una generación de código más rápida ya que evita el uso de un plugin de enlazador, pero por otro lado prohíbe la interoperabilidad con otros sabores de LTO.
Las bibliotecas estándar de C++Edit
El proyecto LLVM incluye una implementación de la biblioteca estándar de C++ llamada libc++, con licencia dual bajo la licencia MIT y la licencia UIUC.
Desde la v9.0.0, se relicenció a la Licencia Apache 2.0 con Excepciones de LLVM.
PollyEdit
Este implementa un conjunto de optimizaciones de localización de caché, así como autoparalelismo y vectorización utilizando un modelo poliédrico.