Introduction to Using LLVM as a Compiler Backend

Assembly and bitcode files

The LLVM intermediate representation (IR) language comes with two formats:

  • bitcode, a binary representation, typically stored in .bc files, and
  • assembly, an human-readable (text) representation, typically stored in .ll files

One can convert back and forth between the two by using an assembler and a disassembler:

llvm-as hello.ll

produces hello.bc, and similarly

llvm-dis hello.bc

produces hello.ll.

Producing assembly files from other languages

One can produce LLVM assembly files from, e.g., C programs as follows:

llvmc -emit-llvm -S hello.c

Changing the -S flag into -c will produce bitcode rather than assembly.

Producing an executable

One way to do it is to run

llvm-ld hello.bc

That's essentially a linker, but it also produces an executable in the end. Another way would be to use

llc hello.bc

which produces an assembly file for the target architecture (eg. x86), followed by:

gcc hello.s

to produce the actual executable. Note that llc can also directly work on .ll files.

Running bitcode as in a virtual machine

LLVM also comes with a JIT compiler for bitcode files:

lli hello.bc

will run the program as expected.