I'm searching for compiler backends to use for my compiler. The things I'm looking for are:


  1. Either be written in C or have official bindings in C (actively maintained by the developers) so I could then easily bootstrap later on. This doesn't matter if we can use text input.
  2. Compilation times faster or at worse on par with GCC's backend (so LLVM is out because of that).
  3. At least 70% of `GCC -O2` runtime performance.
  4. Not alpha and very unstable. Of course, even GCC and Clang are not totally bug-free but I'm ready to start working in my language ASAP so I need something that will work even if not perfect.
  5. Not been a pain to work with.


I'm searching for months and I have found 3 great ones! Links in the bottom (in order) in form: `[name](link.url)`. Also GCC will now refer to `GCC -O2` (for the most part but not necessarily, you will be able to say).


  1. QBE. That was the first one that I found and it's awesome! I used Cproc as a C frontend to compare with GCC. I only run 1 real test. I compiled Cproc with GCC and then I compiled Cproc with itself resulting in two binaries. Then I used these two binaries to compile Cproc again (yeah, sorry. Lazy enough to find something else to test). The result was:

    Cproc compiled with itself about 6 times faster than GCC. The Cproc executable that was compiled with Cproc compiled Cproc in about 0.275s in average and the Cproc executable that was compiled with GCC compiled Cproc in about... the same time! So for my example, they have the same runtime performance. And of course, GCC is the official implementation so we are 100% sure that it is the best usage of the IR while Cproc is not the official implementation so it may not make the best usage.

    To add on that, QBE seems to have an active development with new commits pushed about every 2-4 days, depending in the period. The mailing list seems active. And in the end, there is a great reference that describes the IR so it will be very easy for anyone regardless of experience level to pick it up and use it! This seems like a dream to me!!! The only negative things I could find are:
    • QBE only supports a text interface and not a C library which means that there may be a backend that will be faster because text input mean having to write to a file and then having parse it and then generate the output. At the other hand, the library can just expect the input to be right and create the finally output. Thankfully, in the home page of QBE, it is said that a library interface is a work in progress.
    • QBE has some limitations. I don't know about everything as I'm very inexperienced and I don't know what misses but two things that I have found for sure is that there is no support for inline assembly and there is no `syscall` instruction. However, it seems that in the official page, it is said: "Some hardcoded limits might be hit. But they can also be tweaked easily.". At least for my example, this seems to be true for the second limitations as I have found something in the mailing list but for the first one, I haven't found something yet. However tbh, it will probably be unnecessary to directly write assembly if we can solve all the other limitations.
    • While the runtime performance seemed similar to GCC in my example, there is another example that shows Cproc producing code that was about 25 times (!!!) slower than GCC. That was almost 8 months ago (maybe things got better for QBE since then?) and it was for a float intensive task. That's the most important thing that worries me out of all.

  2. Firm. This is a graph based IR that has a C library API as an interface! The runtime performance and optimizations are something the developers care about from what I understand, there is even a post comparing Firm with LLVM that talks about how good the code that is generated with Firm is (at least for IE32). I used the Cparser frontend to check it out. This is the official frontend so I expect the best possible use of the IR. Like before, I tried to compile Cproc to do the benchmarks. Another thing to note is that the "AMD64" backend is experimental in Firm but "Cproc" compiled without any problems but I don't remember if I tested the resulting binary to see if I'll get any low level errors like "illegal hardware instruction" or the infamous "segmentation fault" when using it.
    • Compilation times: Cparser was 3 times slower than GCC. GCC isn't a fast compiler to begin with (hence my 2nd requirement for the backend) so 3 times slower than GCC will just not do. I don't know if the frontend is just very poorly written but how bad can it be? We are talking about 300% slow down? What it really weird and the reason I'm thinking about the Cparser frontend is that the example with the basic simple frontend was able to compile the same code (just a call to the `exit` syscall) as the equivalent C code (but with different syntax of course) a bit faster than GCC so I'm really confused here...
    • Runtime performance: Here, I got the same results with GCC so that's awesome!
    • Documentation and community: While there is a tutorial for creating a very simple frontend and there are documents that explain how the backend works, there is nothing more about how the API works other than the classic API reference. On top of that, the mailing list seems to not be active and nobody was on the IRC channel when I connected too.



  • With all that in mind, I'm abondoning Firm untill further note from someone that has experience with it. Of course, having alternatives is great and maybe I'm wrong. In any case, I wish the developers the best!



Well sorry, I messed the list quotetion for the last one. So, it is QBN! Well, I only found out about this some minutes before I start writting this thread. QBN is inspired by QBE! Some of the goals are to provide a C library API and output object files directly rather than assembly. These two could make the compilation times EXTREMELY fast. I LOVE THIS!!! This would also remove the need for an assembler and the less the dependencies, the better! Of course this will be super hard in practice (we are talking about an IR and an assembler at the same time). The only thing with QBN is that it is frozen at the moment because the maintainer works in a language frontend at the moment but still, it is worth mentioning and at least it is not abandoned!


This is what I could found. Unless something unexpecetd happens, my current plan is start building the full frontend and see if the maintainer of QBN wants to continue the project and work together at the time that I'll start writing the backend.

Another thing I thought is going crazy and creating a fully custom backend that will output binaries and object files. That was my initial plan as this has numerous advantages but it has the biggest disadvantge which is that I'll have to learn fricking machine language for every ISA that I want to support and a different file format for every OS that I want to support (I know Unix, MacOS and Windows have different ones at least) and probably other platform specific stuff that I don't even know yet! Let's be honest, this is very unrealistic. There is no way that a n00b like me will go from 0 to 100. I cannot even find a place to start and create a simple ELF binary that will just make the `exit` system call, there is no way I'm making a fully low level custom backend. So yeah, I don't waste more time and I want to start working NOW!

If you reached here, you probably have a lot of free time, XD! Seriously now, thakns for reading even if you don't have something to say!

Links:
[QBE](QBE - Compiler Backend)

[Cproc](cproc: Small C11 compiler based on QBE)

[QBE IR reference](QBE Intermediate Language)

[QBE syscall solution](Is there a plan for support of syscall ? — sourcehut lists)

[Cproc performance in float intensive task](MIR performance in float intensive tasks * Discussion #201 * vnmakarov/mir * GitHub)

[Firm](https://pp.ipd.kit.edu/firm/)

[Firm vs LLVM](https://pp.ipd.kit.edu/firm/LLVM.html)

[QBN](https://github.com/ssmid/qbn)