Compiler output language - LLVM IR vs C

I doubt you can implement proper debugging support for your language when targeting C.


LLVM advantages:

  1. JIT - you can compile and run your code dynamically. Sure the same is possible with C (e.g., using an embedded tcc), but it is a much less robust and portable option.
  2. You can run your own optimisation passes over the generated IR.
  3. Reflection for free - inspecting the generated code is much easier with LLVM.
  4. LLVM library is not as big as most of the C compilers (not counting tcc, of course).

LLVM drawbacks:

  1. Code is not portable, you have to change it slightly depending on your target. There is a somewhat portable subset of LLVM, but it is still a dodgy practice.
  2. Runtime dependency on the C++ libraries, might be a bit of an issue.

I've used LLVM IR for a few compiler back ends and have worked with compilers that use C as a back end. One thing that I found that gave the LLVM IR an advantage is that it is typed. It is hard to make completely ill-formed output without getting errors from the LLVM libraries.

It is also easier to keep a close correlation between the source code and the IR for debugging, in my opinion.

Plus, you get all the cool LLVM command line tools to analyse and process the IR your front end emits.