QBE 1.3 Adds Windows Support and Faster Compilation Speed

QBE 1.3 Adds Windows Support and Faster Compilation Speed
QBE 1.3 shipped today with support for Windows, a way to generate code that works with shared libraries, and performance improvements that make it 33% faster than the previous version. QBE is a compiler backend — a tool that converts code from a programming language into machine instructions — designed to be small and quick rather than heavily optimized. The official release notes show the update added about 7,000 new lines of code and removed 1,500, suggesting the developers cleaned things up as they added features.
The biggest addition is native Windows compilation support, contributed by developer Scott Graham. Until now, QBE worked with Linux, macOS, and some other systems, but Windows was missing. Now you can use the -t amd64_win flag to compile code for Windows. This matters because developers building programming languages or tools need their code to run everywhere, and having one compiler backend that handles all major platforms cuts down complexity.
What Got Faster
QBE 1.3 is 33% faster than version 1.2 on standard benchmarks. The backend now achieves more than 63% of the performance of commercial compilers like GCC and Clang on the CoreMark benchmark — a standard test that measures how fast code runs. That might sound modest, but QBE was designed with a different goal: deliver 70% of the performance of industrial compilers while using 10% of the code size and complexity.
The performance gains came from new optimization techniques contributed by Roland Paterson-Jones. These changes use a tool called mgen to improve how the compiler matches code patterns during compilation. That's technical detail, but the outcome is straightforward: the compiler does more work during its own compilation process so it can generate faster code.
To understand what this enables, consider that QBE can compile itself in two seconds on an older dual-core processor with standard optimizations turned on. That kind of compilation speed matters when you're working on language design or rapid prototyping — cases where waiting minutes for compilation breaks your focus.
Shared Libraries and Position-Independent Code
QBE 1.3 now supports generating code for shared libraries — reusable chunks of code that multiple programs can load and use at runtime. This required implementing a technical capability called position-independent code generation, which lets code work no matter where it gets loaded in memory.
For developers building programming languages, this closes a major gap. Until now, you could use QBE to generate standalone programs, but shared libraries — the way modern systems package reusable code — required workarounds or different tools.
Windows Calling Conventions
Scott Graham's Windows ABI implementation (ABI stands for Application Binary Interface — the rules about how code passes data between functions) allows QBE to generate code that follows Microsoft's Windows conventions. Windows and Unix-like systems handle function calls differently: they pass parameters in different places, align memory differently, and return values in different ways.
Without this support, anyone wanting to use QBE on Windows would need either a separate compiler backend for Windows, or a translation layer that converts QBE's output to Windows format — adding complexity. With it, the same intermediate language works everywhere.
A Different Philosophy
QBE operates on a simple principle: use one common representation for code throughout the entire compilation process. Most commercial compilers like GCC and Clang use multiple intermediate representations, each optimized for different tasks. That's powerful but complicated. QBE chose simplicity instead.
The backend targets processors and systems that matter in practice: x86-64 systems (most laptops and servers), ARM64 (phones and modern laptops), and RISC-V (mostly academic and embedded). Full compatibility with C means existing libraries can work with QBE-compiled code without special work.
The broader context here is worth noting. In the mid-2000s, a tool called LLVM changed compiler design by offering a clean intermediate representation that programming language creators could target without building backends from scratch for each processor. QBE follows similar thinking but makes a different trade-off: instead of trying to optimize code as aggressively as possible, it prioritizes getting code compiled fast and keeping the whole system small enough for one person to understand.
The 70% performance target reflects a pragmatic choice. Many applications spend most of their time waiting on disk drives, network requests, or algorithmic inefficiencies rather than running tight loops where aggressive compiler optimization helps. For rapid prototyping, educational projects, or systems where the compile step itself matters, QBE's design makes sense.
Development and Community
QBE development happens through a mailing list at ~mpu/qbe@lists.sr.ht and real-time discussion on the #myrddin IRC channel at irc.eigenstate.org. The project deliberately keeps scope narrow, which means individual contributors can make substantial changes — like Graham's Windows support — without years of committee review.
The pattern of adding 7,000 lines while removing 1,500 shows the maintainers actively refactor and consolidate features rather than just piling on new code. This matters because a codebase you can actually hold in your head is one that individuals can improve.
Version 1.3 establishes QBE as a practical option for anyone building a programming language or development tool that needs to generate native code for multiple platforms. For that use case, it offers a clear advantage over heavier, more complex alternatives: it's fast to compile with, easy to understand, and now finally covers Windows alongside the Unix-like systems it already supported.


