QBE 1.3 añade nuevas optimizaciones, ABI de Windows y código independiente de posición

Fuentes: QBE 1.3 brings new IL matching, optimizations, Windows ABI, and PIC support
Imagen generada por IA con el prompt: Editorial illustration of a compiler backend pipeline transforming source code into optimized assembly, abstract data flow diagram, vintage terminal aesthetic, blue and orange tones
Imagen generada con IA

QBE 1.3 es la versión más ambiciosa del backend de compilador escrito en C desde el lanzamiento de la 1.0, con cerca de 7.000 líneas de código añadidas y 1.500 eliminadas. El compilador, conocido por su pequeño tamaño y su modelo de compilación por funciones en streaming, recibe en esta entrega un nuevo algoritmo de coincidencia de lenguaje intermedio, varias optimizaciones nuevas, compatibilidad con la ABI de Windows y soporte para código independiente de posición.

El trabajo de optimización fue coordinado por Roland Paterson-Jones, quien propuso utilizar el benchmark CoreMark de EEMBC como referencia. Las mediciones iniciales con QBE 1.2 situaban al compilador en torno al 40% del rendimiento de GCC con -O2, lejos del objetivo interno del 70%. Para cerrar esa brecha, el equipo implementó pases como GVN/GCM, optimización de bucles, eliminación de condicionales if y simplificación del CFG, aunque finalmente solo conservó un subconjunto verificado. Con esos cambios, QBE 1.3 supera el 63% del rendimiento de compiladores comerciales en CoreMark sin modificar; al inlinear manualmente la función ee_isdigit y sustituir el cálculo de CRC por una versión sin ramas, alcanza el 70% marcado como meta. La suite de pruebas del lenguaje Hare mejoró un 33% frente a QBE 1.2, pasando de 2,6 s a 1,7 s. El inlining se excluyó del conjunto de optimizaciones para no romper la arquitectura de compilación por funciones de QBE.

Otra incorporación relevante es mgen, una herramienta escrita en OCaml que compila patrones de IL al estilo Lisp en código C idiomático, responsable de reescribir la selección de instrucciones. El sistema numera los DAG siguiendo el método del compilador C de Plan 9 de Ken Thompson y asocia cada número a un bitset de patrones reconocidos. mgen también genera programas matcher en un bytecode simple que la función runmatch() interpreta; en el futuro podría aplicarse a otros backends y a pases de optimización, por ejemplo para reconocer rotaciones de bits.

Scott Graham aportó, además, el soporte para la ABI de Windows, basado en su derivado sqbe. La sintaxis del ensamblador sigue siendo AT&T y se recomienda Mingw como ensamblador; basta pasar -t amd64_win a QBE. Por último, la versión soporta código independiente de posición y puede producir objetos compartidos en la mayoría de destinos, gracias a un nuevo indicador de "constante dinámica" (DYNCONST) en el IL que habilita el acceso indirecto a variables globales equivalente a la GOT de ELF.