Convert C code with external library access to llvm

Hi,

I have written a c program which accesses sqlite database.

Normally I compile the program as

$ clang insertselect.c -l sqlite3

To emit-llvm I use:

$ clang insertselect.c -S -emit-llvm

How do I link the sqlite3 library so that llvm can generate IR with the IR being linked to the external library?

Thanks for your help?

Thanks
Prakash

Hi Prakash,

There are multiple answers to this question which depend on what you
mean by intend to do with IR and what you mean by "link" in your
context. Here are at least two things I can think of

1) You want to run "insertselect.c" using LLVM's MCJIT infrastructure
inside your application.

In this case you wouldn't need to "link" the LLVM IR to the library.
You would just

- Load the LLVM IR module into memory
- Make sure your library (i.e. libsqlite3.so) is dynamically loaded
(I'm pretty sure LLVM has infrastructure for this). This would be
needed so the MCJIT can resolve calls to the sqlite library.
- Use the MCJIT to "JIT" the loaded LLVM IR module so you can run it

I'm sorry if this is vague, I'm not familiar with the MCJIT.

2) You want to analyse your "insertselect.c" program in some way at
the LLVM IR level and need access to the implementations and globals
of library functions as LLVM IR.

In this case you effectively want a single LLVM IR module that has
everything in it (i.e. "insertselect.c" and all the used functions and
globals from the sqlite library).

So you'll need to compile sqlite as LLVM IR.

There is also a hacky way of doing this using a tool called
whole-program-llvm [1] which you could use to build a static library
(for sqlite) containing LLVM IR modules. Once you have that you could
extract all the modules from the archive and then run

$ llvm-link inserselect.bc sqlite_moduel0.bc sqlite_moduel1.bc .... -o messy.bc

then you'll want to run the internalize and globaldce passes strip all
the dead code because llvm-link just merges the modules (I'm assuming
you have a single entry point called main)

$ opt -internalize-public-api-list=main -internalize -globaldce
messy.bc -o final.bc

There is probably a nicer way of doing all this using the LLVM gold
plugin and using ``-use-gold-plugin -Wl,-plugin-opt=also-emit-llvm``
with clang but I've never tried.

[1] https://github.com/travitch/whole-program-llvm

Hope that helps.

Dan Liew
PhD Student - Imperial College London

If you're under Linux you can do this

$ LD_PRELOAD=/usr/lib/libsqlite3.so lli output.s

This will preload the sqlite library so that the interpreter can find
the external functions.

On a completely different note please remember to do "reply-all" when
replying to emails so that llvmdev gets CC'ed so that everyone can
benefit from this discussion.

Hope that helps.