pythonic
pythonic

Reputation: 21665

How to make clang compile to llvm IR

I want clang to compile my C/C++ code to LLVM bitcode rather than a binary executable. How can I achieve that?

And if I have the LLVM bitcode, how can I further compile it to a binary executable?

I want to add some of my own code to the LLVM bitcode before compiling to a binary executable.

Upvotes: 207

Views: 165056

Answers (6)

abhinav tiwari
abhinav tiwari

Reputation: 1

First, let us understand what clang is:

Clang is a front-end, what does it mean by front-end exactly?
Front end = source -> AST -> IR

So now your question
Given some C/C++ file or any source code that clang supports, eg.c:

> clang -S -emit-llvm eg.c

Why do we give flag -S and -emit-llvm? What do they mean?

-S => tells compiler to stop after generating the assembly code and do not create an object file.

-emit-llvm => This tells us to generate the LLVM IR

Now, the question comes: Do we need to give both the flags?
If we only use the command

> clang -emit-llvm eg.c

we will face an error as

clang: error: -emit-llvm cannot be used when linking

It says that we can't use the flag -emit-llvm for the linking purpose, only for the compilation purpose, we should use.

So the answer is yes we need to use both the flag to generate IR

some of the basic command are

Command Output File Output Type
clang -S hello.c hello.s Assembly code
clang -emit-llvm -c hello.c hello.bc LLVM Bitcode (binary format)
clang -S -emit-llvm hello.c hello.ll LLVM IR (human-readable)

Upvotes: 0

Kiko Fernandez
Kiko Fernandez

Reputation: 1007

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):

  1. generate all .ll files

    clang-3.8 -S -emit-llvm *.c
    
  2. link them into a single one

    llvm-link-3.8 -S -v -o single.ll *.ll
    
  3. (Optional) Optimise your code (maybe some alias analysis)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
    
  4. Generate assembly (generates a optimised.s file)

    llc-3.8 optimised.ll
    
  5. Create executable (named a.out)

    clang-3.8 optimised.s
    

Upvotes: 29

Jeremy Salwen
Jeremy Salwen

Reputation: 8428

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.

Upvotes: 30

Eli Bendersky
Eli Bendersky

Reputation: 273836

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.

Upvotes: 273

Christoph
Christoph

Reputation: 169813

Use

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc

Upvotes: 24

rotoglup
rotoglup

Reputation: 5283

Did you read clang documentation ? You're probably looking for -emit-llvm.

Upvotes: 14

Related Questions