Aula 25: Otimizações Globais
Objetivos
- Aplicar otimizações independentes de arquitetura.
- Otimização de Loops (LICM).
Motivação
Otimizações globais são fundamentais para programas de grande porte e cargas de trabalho intensivas:
- Loops bem otimizados podem reduzir ordens de grandeza de tempo de execução.
- Técnicas como LICM e inlining preparam o terreno para que otimizadores de nível mais baixo (como LLVM) encontrem ainda mais oportunidades.
Conteúdo
Uma grande fração do tempo de execução é gasta em loops. Otimizações globais (que consideram o CFG inteiro) permitem mover código invariante para fora do loop (LICM), eliminar código morto em nível de função e aplicar inlining com cuidado.
flowchart LR
CFG[CFG] --> LICM[LICM]
CFG --> Inline[Inline]
CFG --> DCE[Dead code elim]
LICM --> IR2[IR melhorada]
Inline --> IR2
DCE --> IR2
Loop Invariant Code Motion (LICM)
Mover código que não muda dentro do loop para fora (pré-cabeçalho).
while(i < N) {
x = y + z; // y e z não mudam no loop
a[i] = x * i;
}Vira:
t1 = y + z;
while(i < N) {
a[i] = t1 * i;
}Function Inlining
Substituir a chamada de uma função pelo corpo dela. - Vantagens: Elimina overhead de call/ret, de empilhar parâmetros e permite otimizações inter-procedurais (ex: constant folding nos argumentos). - Desvantagem: Aumenta o tamanho do binário (Code Bloat).
Dead Code Elimination (Global)
Se uma variável é definida mas nunca está viva (liveness analysis), a instrução que a define pode ser removida. Isso surge frequentemente após outras otimizações (ex.: após constant folding, um if (false) deixa de ser alcançável e o código dentro vira dead code).
Resumo
- LICM: mover para o pré-cabeçalho do loop o código cujos operandos não mudam no loop. Inlining: substituir chamada pelo corpo da função; aumenta tamanho mas permite mais otimizações. DCE: remover definições que não são usadas (com base em liveness).
Referências
- Aho et al. (2006); Cooper & Torczon (2011).
Materiais da aula
Última atualização: 08/03/2026