Representação intermediária - Intermediate representation
Execução do programa |
---|
Conceitos gerais |
Tipos de código |
Estratégias de compilação |
Tempos de execução notáveis |
|
Compiladores e conjuntos de ferramentas notáveis |
|
Uma representação intermediária ( IR ) é a estrutura de dados ou código usado internamente por um compilador ou máquina virtual para representar o código-fonte . Um IR é projetado para ser propício para processamento posterior, como otimização e tradução . Um IR "bom" deve ser preciso - capaz de representar o código-fonte sem perda de informações - e independente de qualquer fonte ou idioma de destino em particular. Um IR pode assumir uma de várias formas: uma estrutura de dados na memória ou uma tupla especial - ou código baseado em pilha legível pelo programa. No último caso, também é chamada de linguagem intermediária .
Um exemplo canônico é encontrado na maioria dos compiladores modernos. Por exemplo, o interpretador CPython transforma o texto linear legível por humanos que representa um programa em uma estrutura gráfica intermediária que permite a análise de fluxo e a reorganização antes da execução. O uso de uma representação intermediária como essa permite que sistemas compiladores como o GNU Compiler Collection e o LLVM sejam usados por muitas linguagens de origem diferentes para gerar código para muitas arquiteturas de destino diferentes .
Linguagem intermediária
Uma linguagem intermediária é a linguagem de uma máquina abstrata projetada para auxiliar na análise de programas de computador . O termo vem de seu uso em compiladores , onde o código-fonte de um programa é traduzido em uma forma mais adequada para transformações de melhoria de código antes de ser usado para gerar código de objeto ou máquina para uma máquina de destino. O design de uma linguagem intermediária normalmente difere daquele de uma linguagem de máquina prática de três maneiras fundamentais:
- Cada instrução representa exatamente uma operação fundamental; por exemplo, modos de endereçamento "shift-add" comuns em microprocessadores não estão presentes.
- As informações de fluxo de controle podem não estar incluídas no conjunto de instruções.
- O número de registros de processador disponíveis pode ser grande, até mesmo ilimitado.
Um formato popular para linguagens intermediárias é o código de três endereços .
O termo também é usado para se referir a linguagens usadas como intermediários por algumas linguagens de programação de alto nível que não geram objetos ou códigos de máquina, mas geram apenas a linguagem intermediária. Essa linguagem intermediária é submetida a um compilador para tal linguagem, que então produz o objeto acabado ou código de máquina. Isto é normalmente feito para facilitar o processo de optimização , ou para aumentar a portabilidade usando uma linguagem intermediária que tem compiladores para muitos processadores e sistemas operativos , tais como C . As linguagens usadas para isso caem em complexidade entre as linguagens de alto nível e as linguagens de baixo nível , como as linguagens assembly .
línguas
Embora não seja explicitamente projetada como uma linguagem intermediária, a natureza do C como uma abstração de assembly e sua onipresença como a linguagem de sistema de fato no tipo Unix e outros sistemas operacionais tornou-o uma linguagem intermediária popular: Eiffel , Sather , Esterel , alguns dialetos de Lisp ( Lush , Gambit ), Haskell ( Glasgow Haskell Compiler ), Squeak 's Smalltalk-subconjunto Slang, Cython , Seed7 , SystemTap , Vala , V e outros usam C como uma linguagem intermediária. As variantes de C foram projetadas para fornecer os recursos de C como uma linguagem assembly portátil , incluindo C-- e a linguagem C intermediária .
Qualquer linguagem destinada a uma máquina virtual ou máquina de código p pode ser considerada uma linguagem intermediária:
- Bytecode Java
- A Common Intermediate Language da Microsoft é uma linguagem intermediária projetada para ser compartilhada por todos os compiladores do .NET Framework , antes da compilação estática ou dinâmica para código de máquina.
- Enquanto a maioria das linguagens intermediárias são projetadas para suportar linguagens tipadas estaticamente, a representação intermediária do Parrot é projetada para suportar linguagens tipadas dinamicamente - inicialmente Perl e Python.
- TIMI é usado por compiladores na plataforma IBM i .
- O-code para BCPL
- Código pré-compilado MATLAB
- Microsoft P-Code
- Pascal p-code
O GNU Compiler Collection (GCC) usa várias linguagens intermediárias internamente para simplificar a portabilidade e a compilação cruzada . Entre essas línguas estão
- o histórico Register Transfer Language (RTL)
- a linguagem da árvore GENÉRICA
- o GIMPLE baseado em SSA . (Nível inferior a GENERIC; entrada para a maioria dos otimizadores; tem uma notação compacta de "bytecode".)
O GCC oferece suporte à geração desses IRs, como um alvo final:
- Camada intermediária HSA
- Representação intermediária LLVM (convertido de GIMPLE no agora extinto llvm-gcc que usa otimizadores LLVM e codegen)
A estrutura do compilador LLVM é baseada na linguagem intermediária LLVM IR , da qual a representação serializada binária compacta também é conhecida como "código de bits" e foi produzida pela Apple. Como o GIMPLE Bytecode, o LLVM Bitcode é útil na otimização de tempo de link. Como o GCC, o LLVM também tem como alvo alguns IRs destinados à distribuição direta, incluindo PNaCl IR e SPIR do Google . Um desenvolvimento adicional dentro do LLVM é o uso de Representação Intermediária de Vários Níveis (MLIR) com o potencial de gerar código para diferentes alvos heterogêneos e combinar as saídas de diferentes compiladores.
A linguagem intermediária ILOC é usada em aulas de design de compilador como uma linguagem de destino simples.
De outros
As ferramentas de análise estática geralmente usam uma representação intermediária. Por exemplo, radare2 é uma caixa de ferramentas para análise de arquivos binários e engenharia reversa. Ele usa as linguagens intermediárias ESIL et REIL para analisar arquivos binários.
Veja também
- Tradução automática interlingual
- Linguagem dinâmica
- Árvore de sintaxe abstrata
- Bytecode (código intermediário)
- Tabela de símbolos
- Compilador fonte-a-fonte
- Reescrita de gráficos e reescrita de termos
- UNCOL