1. 23

  2. 14

    I’ve been paying attention to the project where they adapt the rustc frontend to a GCC backend. The amount of PRs addressing GCC shortcomings is facinating. Of note was the lack of support for types like i32 instead of int.

    1. 11

      This is one of the big differences between GCC and LLVM’s intermediate representations. Both cause pain points. LLVM’s representation has the advantage that types are not target-specific. This makes it quite easy to build cross compilers out of LLVM. They simply need to lower target-specific types to the correct generic type in the front end and then all of the optimisers are completely target agnostic. This is particularly useful for optimisations in heterogeneous code: it doesn’t matter if the code will finally execute on a CPU, GPU, or other accelerator, the types will be consistent across the entire program.

      The big downside of LLVM’s approach is that ABIs for non-C languages are typically defined in terms of C types. C ABIs already provide a platform abstraction and so it’s easy to define a C++ ABI (for example) in terms of void*, size_t, and so on and leave the mapping to any particular target to the C ABI. The fact that LLVM IR loses all C-level type information means that there are (poorly documented) implicit contracts between the back and front ends for defining ABIs. For example, a lot of C ABIs have different calling conventions for returning a structure containing two ints and a _Complex(int). Both of these might be lowered to {i32, i32} in LLVM IR and so you need some other hint to describe the ABI. Some of these are hideous. For example, if you want to return two 32-bit values in registers on a 32-bit x86 target then you return a single i64. If this is a pair of pointers then the optimisers suffer from the fact that you have pointer-to-int and in-to-pointer casts with shifts and masks in the middle, especially after inlining. This is probably my least favourite design choice in LLVM IR.

      1. 1

        Didn’t knew about that downside. But I doubt you’ll reach a point where you can simply replace the LLVM IR with something that isn’t C specific.

      2. 1

        that also sounds like the gcc internal implementation will totally vary in the ABI and some features (like i32s are just ignored?)