Back-End Compilação aula-11-back-end.pdf Compilação Back-end Todo o processo de geração de código para a máquina alvo é feita na etapa de compilação conhecida como back-end ou síntese. Uma representação do código em uma estrutura de árvore (árvore sintática) é recebida das etapas do front-end após a execução da análise semântica. O que ocorre em muitos casos é que a geração de código pode ser realizada através de ações semânticas processo conhecido com Tradução Dirigida por Sintaxe. Compilação Back-end Em geral a geração de código pode ocorrer diretamente para a máquina alvo ou o que mais comum e a geração de código ser realizada para uma etapa intermediaria e posteriormente ser gerado código para maquina alvo. Livro Geração de código intermediário Transforma a árvore de derivação em um segmento de código denominado código intermediário. Geração de código intermediário Vantagens de utilização de uma representação intermediária. Otimização do código de modo a obter um código mais eficiente. Simplificação de código pois o código intermediário representa uma versão inteligível do código. Possibilidade da tradução do código intermediário em diversas máquinas. Geração de código intermediário A representação intermediária deve ser fácil de ser produzida, ou seja, criada e fácil de ser traduzida para a máquina alvo. A maior principal diferença entre o código intermediário e o código final é que o código intermediário não especifica detalhes da máquina alvo, ela será uma representação da linguagem de alto nível com a linguagem assembly ou de máquina O código intermediário deve representar todas as expressões do programa fonte. Código de três endereços É uma forma de representar uma linguagem intermediaria, é a forma mais comum de ser utilizada e cada instrução faz referência a no máximo três variáveis (endereços de memória). As instruções básicas dessa linguagem são as seguintes: Código de três endereços Onde A, B, e C representam variáveis, op representa operadores, oprel um operadores relacionais e L um rótulo. Código de três endereços O código de três endereços é composto por uma sequência de instruções envolvendo operações e atribuições e desvios. Dessa forma as expressões da linguagem são decompostas na representação em uma serie de instruções. Outro detalhe importante é o uso de variáveis temporárias nesse processo. Com esse tipo de representação intermediara obtemos um código mais próximo possível ao assembly o que consequentemente facilita a geração de código para a máquina alvo. Código de três endereços Exemplo mais complexo de um código intermediário. Código de três endereços Exemplo mais complexo de um código intermediário. JVM Ver exemplos de Byte Code em Java Linguagem de programação que possuem implementação para a JVM javap -c br.com.unoesc.Nome JRuby http://en.wikipedia.org/wiki/List_of_JVM_languages Otimização de código Essa fase é responsável por gerar um código mais eficiente que envolvem diretamente o uso de memória, espaço e velocidade de execução da instruções. Normalmente quando a ganhos de espaços a perda de tempo de execução e vice-versa. Nessa etapa são aplicados técnicas que permitem detectar processos que otimizem o código. Otimização de código As técnicas podem variar de compilador par compilador e devem manter o significado do programa original. Devem executar a maior parte das melhorais de código dentro de um dentro de um determinado nível de esforço de otimização. Essa etapa tende a consumir muito tempo na compilação e deve ser implementada somente se o compilador exigir um código mais eficiente. Otimização de código O processo de otimização de código envolve duas tarefas: Otimização de código intermediário: Com base no código intermediário é eliminado atribuições redundantes, expressões comuns, variáveis temporárias desnecessárias, troca de instruções de lugar. Otimização de código Otimização de código O processo de otimização de código envolve duas tarefas: Otimização de código objeto: Realiza a troca de instruções de maquinas por instruções mais rápidas e de melhor utilização de registradores. Otimização de código Otimização de código em C Exemplo em utilizando o compilador GCC No compilador gcc temos o parâmetro -O que determina esse esforço. O comando gcc –O0 (nenhuma optimização) até gcc –O3 (Máxima otimização) Otimização de código em C Parâmetro -O0 O que faz Nenhuma otimização -O1 Reduzir o tempo de compilação e o tamanho do executável. -O2 Não causa aumento do executável, é o melhor, mais seguro (por conta da portabilidade) e o mais usado nos dias atuais na distribuição de softwares em Linux; -O3 Opção com melhor nível de otimização; entretanto, é a que mais causa efeitos colaterais: arquivos maiores, maior uso de memória RAM. Exercícios