LLVM IR is a low-level intermediate representation used by the LLVM compiler framework. You can think of LLVM IR as a platform-independent assembly language with an infinite number of function local registers.
Clang: a C language family frontend for LLVM. The Clang project provides a language front-end and tooling infrastructure for languages in the C language family (C, C++, Objective C/C++, OpenCL, CUDA, and RenderScript) for the LLVM project.
By default, llvm-gcc compiles to native objects just like GCC does. If the -emit-llvm and -c options are given then it will generate LLVM bitcode files instead.
Given some C/C++ file foo.c
:
> clang -S -emit-llvm foo.c
Produces foo.ll
which is an LLVM IR file.
The -emit-llvm
option can also be passed to the compiler front-end directly, and not the driver by means of -cc1
:
> clang -cc1 foo.c -emit-llvm
Produces foo.ll
with the IR. -cc1
adds some cool options like -ast-print
. Check out -cc1 --help
for more details.
To compile LLVM IR further to assembly, use the llc
tool:
> llc foo.ll
Produces foo.s
with assembly (defaulting to the machine architecture you run it on). llc
is one of the LLVM tools - here is its documentation.
Use
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
If you have multiple source files, you probably actually want to use link-time-optimization to output one bitcode file for the entire program. The other answers given will cause you to end up with a bitcode file for every source file.
Instead, you want to compile with link-time-optimization
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
and for the final linking step, add the argument -Wl,-plugin-opt=also-emit-llvm
clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
This gives you both a compiled program and the bitcode corresponding to it (program.bc). You can then modify program.bc in any way you like, and recompile the modified program at any time by doing
clang program.bc -o program
although be aware that you need to include any necessary linker flags (for external libraries, etc) at this step again.
Note that you need to be using the gold linker for this to work. If you want to force clang to use a specific linker, create a symlink to that linker named "ld" in a special directory called "fakebin" somewhere on your computer, and add the option
-B/home/jeremy/fakebin
to any linking steps above.
If you have multiple files and you don't want to have to type each file, I would recommend that you follow these simple steps (I am using clang-3.8
but you can use any other version):
generate all .ll
files
clang-3.8 -S -emit-llvm *.c
link them into a single one
llvm-link-3.8 -S -v -o single.ll *.ll
(Optional) Optimise your code (maybe some alias analysis)
opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
Generate assembly (generates a optimised.s
file)
llc-3.8 optimised.ll
Create executable (named a.out
)
clang-3.8 optimised.s
Did you read clang
documentation ? You're probably looking for -emit-llvm
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With