Lenguaje intermedio
Una representación intermedia (IR del inglés intermediate representation) o lenguaje intermedio es la estructura de datos o el código que utiliza internamente un compilador o una máquina virtual para representar el código fuente. Un IR está diseñado para facilitar el procesamiento posterior, como la optimización y la traducción. Un IR "bueno" debe ser preciso, capaz de representar el código fuente sin pérdida de información, e independiente de cualquier idioma de origen o de destino en particular. Un IR puede tomar una de varias formas: una estructura de datos en memoria, o un código especial basado en tuplas o pilas legible por el programa. En este último caso también se le llama lengua intermedia.
Un ejemplo canónico se encuentra en la mayoría de los compiladores modernos. Por ejemplo, el intérprete de CPython transforma el texto lineal legible por humanos que representa un programa en una estructura gráfica intermedia que permite el análisis de flujo y la reorganización antes de la ejecución. El uso de una representación intermedia como esta permite que muchos lenguajes de origen diferentes utilicen sistemas de compilación como GNU Compiler Collection y LLVM para generar código para muchas arquitecturas de destino diferentes.
Lenguaje intermedio
Un lenguaje intermedio es el lenguaje de una máquina abstracta diseñada para ayudar en el análisis de programas de computadora. El término proviene de su uso en compiladores, donde el código fuente de un programa se traduce a una forma más adecuada para transformaciones de mejora de código antes de usarse para generar código de objeto o de máquina para una máquina de destino. El diseño de un lenguaje intermedio generalmente difiere del de un lenguaje de máquina práctico en tres formas fundamentales:
- Cada instrucción representa exactamente una operación fundamental; por ejemplo, los modos de direccionamiento "shift-add" comunes en los microprocesadores no están presentes.
- La información del flujo de control puede no estar incluida en el conjunto de instrucciones.
- El número de registros de procesador disponibles puede ser grande, incluso ilimitado.
Un formato popular para idiomas intermedios es el código de tres direcciones.
El término también se usa para referirse a los lenguajes utilizados como intermediarios por algunos lenguajes de programación de alto nivel que no generan código de objeto o máquina por sí mismos, pero solo generan el lenguaje intermedio. Este lenguaje intermedio se envía a un compilador para dicho lenguaje, que luego genera un objeto terminado o un código de máquina. Esto generalmente se hace para facilitar el proceso de optimización o aumentar la portabilidad mediante el uso de un lenguaje intermedio que tiene compiladores para muchos procesadores y sistemas operativos, como C. Los lenguajes utilizados para esta caída en complejidad entre lenguajes de alto nivel y lenguajes de bajo nivel., como los lenguajes ensambladores.
Idiomas
Aunque no está diseñado explícitamente como un lenguaje intermedio, la naturaleza de C como una abstracción del ensamblaje y su ubicuidad como el lenguaje del sistema de facto en sistemas operativos similares a Unix y otros lo ha convertido en un lenguaje intermedio popular: Eiffel, Sather, Esterel, algunos dialectos de Lisp (Lush, Gambit), Haskell (Glasgow Haskell Compiler), Squeak's Smalltalk-subset Slang, Cython, Seed7, SystemTap, Vala, V y otros utilizan C como lenguaje intermedio. Se han diseñado variantes de C para proporcionar las características de C como un lenguaje ensamblador portátil, incluidos C-- y el lenguaje intermedio C.
Cualquier idioma dirigido a una máquina virtual o una máquina de código p puede considerarse un idioma intermedio:
- Código de bytes de Java
- El lenguaje intermedio común de Microsoft es un lenguaje intermedio diseñado para ser compartido por todos los compiladores de.NET Framework, antes de la compilación estática o dinámica en código de máquina.
- Si bien la mayoría de los lenguajes intermedios están diseñados para admitir lenguajes tipificados estáticamente, la representación intermedia de Parrot está diseñada para admitir lenguajes tipificados dinámicamente, inicialmente Perl y Python.
- Los compiladores utilizan TIMI en la plataforma IBM i.
- Código O para BCPL
- Código precompilado de MATLAB
- Código P de Microsoft
- Código p de Pascal
La colección de compiladores GNU (GCC) utiliza varios lenguajes intermedios internamente para simplificar la portabilidad y la compilación cruzada. Entre estos idiomas se encuentran
- el histórico lenguaje de transferencia de registros (RTL)
- el lenguaje del árbol GENÉRICO
- el GIMPLE basado en SSA. (Nivel más bajo que GENERIC; entrada para la mayoría de los optimizadores; tiene una notación compacta de "código de bytes").
GCC apoya la generación de estos IR, como objetivo final:
- Capa intermedia HSA
- Representación intermedia de LLVM (convertida de GIMPLE en el ahora desaparecido llvm-gcc que usa optimizadores LLVM y codegen)
El marco del compilador LLVM se basa en el lenguaje intermedio LLVM IR, cuya representación serializada binaria compacta también se conoce como "código de bits" y ha sido producida por Apple. Al igual que GIMPLE Bytecode, LLVM Bitcode es útil en la optimización del tiempo de enlace. Al igual que GCC, LLVM también apunta a algunos IR destinados a la distribución directa, incluidos PNaCl IR y SPIR de Google. Otro desarrollo dentro de LLVM es el uso de Representación Intermedia de Múltiples Niveles (MLIR) con el potencial de generar código para diferentes objetivos heterogéneos y combinar los resultados de diferentes compiladores.
El lenguaje intermedio de ILOC se usa en clases sobre diseño de compiladores como un lenguaje de destino simple.
Otro
Las herramientas de análisis estático suelen utilizar una representación intermedia. Por ejemplo, radare2 es una caja de herramientas para el análisis de archivos binarios y la ingeniería inversa. Utiliza los lenguajes intermedios ESIL y REIL para analizar archivos binarios.
Contenido relacionado
Máquina de estados finitos
Enlazador (informática)
Codificación Manchester diferencial