How could I tackle a simple "pass-through" code generator?

For historical reasons, the target I’m working on has a separate codegen program that takes a parenthesized form of LLVM IR and produces assembler. A small step towards removing that would be a pass-through LLVM CodeGen that uses our current conversion pass to dump the text into memory along with a quick modification for our codegen routines to parse that dump. Then I can work on integrating typical cross-compilation pieces using all the existing build machinery rather than trying to update our held-together-by-duct-tape build system…

All the existing documentation describes the right way to implement a target somewhat from scratch. Does anyone have advice on making a nigh-trivial pass-through CodeGen target (no ISel) where really only the assembler output is significantly modified to call something else?

I’d also have some intrinsic lowering, etc., but that’s rather straight-forward (mostly already in IntrinsicLowering).

Suffice it to say that searches for anything with “pass” in the name don’t quite help… :wink: I’ve tried multiple alternative phrasings without any search luck.

One example is HLSL and DirectX. There is no real codegen:

The other example is SPIR-V. It goes through GlobalIsel, but it is a virtual ISA.

Yes, thank you! The DirectX example looks like a fantastic analog.

At some point, we may add a trivial ISel pass so we incrementally can
move from our wonky codegen to a proper backend… I’m hoping to find a
route that produces results without having to completely re-implement
everything from the get-go.

Yea, the DirectX backend’s output is just LLVM 3.7 Bitcode. We have some passes that translate the IR and mutate metadata, but it is pretty straightforward.

We also use the MC layer to emit our final binary file, so it is kinda like a backend that skips Isel and MC passes, but then picks up again at the object emitters.