[5] La optimización es el campo donde se hace más investigación en los compiladores hoy en día.
Si se ejecuta una instrucción del bloque se ejecutan todas en un orden conocido en tiempo de compilación[8]) dado que los bloques básicos no tienen control de flujo, estas optimizaciones necesitan muy poco análisis (lo que ahorra tiempo y reduce los requisitos de almacenamiento), pero esto también significa que ninguna información se conserva a través de saltos, y las optimizaciones al ser tan puntuales no tienen gran impacto sobre el programa.
Dado esto, varias técnicas de optimización similares pueden ser utilizadas en todos los lenguajes.
[16] Algunos tipos de optimizaciones son muy comunes debido a sus características y es importante nombrarlos individualmente.
Las optimizaciones peephole son transformaciones simples que dan un beneficio suficiente como para ser implementadas en cualquier compilador.
Puede haber varias formas de llevar a cabo una tarea determinada, con CISC suelen ofrecer más alternativas que RISC.
El código de sincronización puede necesitar ser predecible, en lugar de tan rápido como sea posible, el almacenamiento en caché del código puede ser desactivado, junto con las optimizaciones del compilador que lo requieran.
En gran medida, las técnicas de optimización del compilador tienen los siguientes temas, que a veces en conflicto.
Reutilizar los resultados que ya están calculados y almacenarlos para su uso posterior, en vez de recalcular ellos aumenta significativamente el rendimiento general.
Por otra parte, en los sistemas embebidos, menos código trae un costo de producto más bajo.
Los saltos (condicionales o incondicionales) interfieren con fetching previo de instrucciones, lo que ralentiza el código.
[28] Reordenar las operaciones para permitir que múltiples cálculos se produzcan en paralelo, ya sea en la instrucción, la memoria, o a nivel de hilo.
Cuanto más precisa sea la información que el compilador tiene, mejor se puede emplear cualquiera o todas estas técnicas de optimización.
La información recopilada durante una ejecución de prueba se puede utilizar en una optimización guiada por perfiles.
Dado que los procesadores modernos pueden operar rápido en vectores esto aumenta la velocidad.
En un bucle estrecho esta técnica oculta la latencia entre la carga y el uso de valores.
[43] De las técnicas de optimización la más trivial es la que se refiere a la compactación del código, es decir que algunas expresiones pueden ser simplificadas mediante la evaluación del compilador como puede ser "8+3+C+d", en la declaración el compilador la dejará como "11+C+d", claramente se observa que el compilador reemplaza los números 8 y 3 por su resultante, por supuesto se aplica casi para cualquier tipo de operación.
[43] Similar el plegamiento ésta constante se sustituye y es reescrita de una forma implícita.
Así por ejemplo, cuando hacemos la evaluación de: c = 4; valor = c/2 éste puede ser mejor usado como valor = 4/2, y éste a su vez ser plegado como se mencionó anteriormente.
[44] Eliminar las asignaciones a variables que no son posteriormente leídas, ya sea por la vida útil de la variable o debido a que se sobrescribirá el primer valor antes de ser usado.
Muchas optimizaciones que figuran en otras secciones también se benefician sin cambios especiales, tales como asignación de registros.
Es importante que el conjunto de instrucciones sea uniforme y completo.
Esto se realiza en conjunto con la asignación de registros para evitar derrames.
Cambiar instrucciones en la memoria baja puede acceder a las rutinas en cualquier dirección.
Esto es un grave cuello de botella en ciertas aplicaciones tales como código científico.
[57] Elige el desplazamiento de la rama más corta que llega a destino.
[60] La expansión en línea es una técnica de optimización del compilador que reduce la sobrecarga de una llamada a una función, simplemente no haciendo la llamada, por el contrario, el compilador reescribe eficazmente la función en el programa como si la definición de la función llamada se insertó en cada sitio que fue invocada.
[61] En este paso, consecutivos saltos condicionales predichos total o parcialmente en la misma condición se fusionan.
Esta técnica complementa la evaluación perezosa pero solo se pueden utilizar cuando las pruebas no son dependientes uno del otro.
Esto puede ser demostrado mediante la consideración de una llamada a una función, foo().