12

QBE - Compiler Backend

 2 years ago
source link: https://c9x.me/compile/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Compiler Backend

Compiler Backend

QBE aims to be a pure C embeddable backend that provides 70% of the performance of advanced compilers in 10% of the code. Its small size serves both its aspirations of correctness and our ability to understand, fix, and improve it. It also serves its users by providing trivial integration and great flexibility.

git clone git://c9x.me/qbe.git

QBE is known to compile and pass its test suite on amd64 Linux, FreeBSD, and OSX. Compiling QBE requires GNU Make and a C99 compiler. The HTML documentation is generated from regular text files by an OCaml program.

Contact

Patches and discussions about QBE are hosted on the mailing list ~mpu/[email protected].

IRC: irc.eigenstate.org in #myrddin (nick: mpu).

Status

QBE is in constant change. It is a young project and I still have many ideas to try. The core of it should now work pretty reliably for simple language experiments. To palliate the youth and lack of users, complex parts of the register allocator and the ABI implementation have been thoroughly fuzz tested.

Some smartness is already baked in at this time.

  • Very good compatibility with C code.
  • IEEE floating points support.
  • SSA-based intermediate language.
  • Copy elimination.
  • Sparse conditional constant propagation.
  • Dead instructions elimination.
  • Registerization of small stack slots.
  • Split spiller and register allocator thanks to SSA form. (Simpler and faster than graph coloring.)
  • Smart spilling heuristic based on loop analysis.
  • Linear register allocator with hinting.
  • Recognizes and uses x64 addressing modes.
  • Uniform and simple IL syntax.
  • Gets compiled really quick (2 seconds on my Core 2 Duo with CFLAGS=-O2).

You might encounter some friction because of these points.

  • Only x64 platforms are currently supported. ARM support is planned.
  • Computed goto (switch) is not provided. It will be implemented.
  • Some hardcoded limits might be hit. But they can also be tweaked easily.
  • Text input only. A C library interface is work in progress.

Documentation

  • The reference document for QBE's intermediate language.
  • A short comparison with LLVM.
  • A bibliography useful to understand and hack QBE.
  • A tutorial by Brian Callahan to build a Brainfuck compiler with QBE.
  • A simple description of the UNIX x64 ABI used in QBE.
  • A tutorial frontend is included in the distribution in the minic/ directory. In less than 1000 lines it compiles a dumbed-down C. Small benchmarks are provided too.

Projects using QBE.

  • Michael Forney authored cproc, the most comprehensive C frontend for QBE. Cproc is known to bootstrap GCC and used as main C compiler in the oasis Linux distribution.
  • Antimony uses QBE as backend.
  • An ambitious C99 compiler from Roberto E. Vargas Caballero (k0ga).
  • Two frontends for brainfuck and C were written in Myrddin by Andrew Chambers.
  • A testimony to QBE's good design is the PACC compiler from Benjamin Rosseaux; it reuses both the IL design and many passes from QBE.
  • Some ongoing work on the Myrddin compiler aims to use QBE as backend.

Hello World

The intermediate language used as input to QBE is spoken by all the compilation passes and can be dumped anytime in the compiler pipeline using command line options. The example program below can call the C function printf out of the box, with no special syntax. C compatibility is baked in. Similarly C can call any function compiled with QBE.

function w $add(w %a, w %b) {              # Define a function add
@start
	%c =w add %a, %b                   # Adds the 2 arguments
	ret %c                             # Return the result
}
export function w $main() {                # Main function
@start
	%r =w call $add(w 1, w 1)          # Call add(1, 1)
	call $printf(l $fmt, w %r, ...)    # Show the result
	ret 0
}
data $fmt = { b "One and one make %d!\n", b 0 }

Toss the above in a file, then run qbe -o asm.s file.ssa && cc asm.s. You should get a binary executable file ready to rock.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK