10

I would like to compile software using the autotools build system to LLVM bitcode; that is, I would like the executables obtained at the end to be LLVM bitcode, not actual machine code.

(The goal is to be able to run LLVM bitcode analysis tools on the whole program.)

I've tried specifying CC="clang -emit-llvm -use-gold-plugins" and variants to the configure script, to no avail. There is always something going wrong (e.g. the package builds .a static libraries, which are refused by the linker).

It seems to me that the correct way to do it would be that LLVM bitcode should be a cross-compilation target. to be set with --host=, but there is no such standard target (even though there is a target for Knuth's MMIX).

So far I've used kludges, such as compiling with CC="clang -emit-llvm -use-gold-plugins" and running linking lines (using llvm-ld or llvm-link) manually. This works for simple packages such as grep.

I would like a method that's robust and works with most, if not all, configure scripts, including when there are intermediate .a files, or intermediate targets.

David Monniaux
  • 1,948
  • 12
  • 23
  • llvm-ld seems to imply that it accepts .a files http://llvm.org/releases/2.7/docs/CommandGuide/html/llvm-ld.html – τεκ May 09 '13 at 20:29
  • llvm-ld no longer exists in later LLVM releases. – David Monniaux May 12 '13 at 12:00
  • Have you looked into use lld for 'linking'? http://lld.llvm.org/ – Dan O Sep 29 '13 at 05:56
  • You cannot easily pass `-emit-llvm` (hm, wasn’t this `-emit-bc` before?) to $CC to configure because most GNU autoconf scripts rely on the ability to compile, link and even run test programs. You should write custom Makefile rules that add that flag, or override it on the make commandline (`make CC='clang -emit-llvm -use-gold-plugins' all`). When using libtool, though, you will be pretty much out of luck. You could copy/paste the CC lines manually though… – mirabilos Dec 06 '13 at 00:39

1 Answers1

2

There are some methods like this. But for simple builds where intermediate static libraries are not used, then you can do something simpler. The list of things you will need are

  1. llvm, configured with gold plugin support. Refer to this
  2. clang
  3. dragonegg, if you need front-end for fortran, go, etc.

The key is to enable '-flto' for either clang or dragonegg(front-end), both at compile time and link time. It is straightforward for clang:

CC = clang
CLINKER = clang
CFLAGS = -flto -c
CLINKFLAGS = -flto -Wl,-plugin-opt=also-emit-llvm

If needed, add additional '-plugin-opt' option to specify llvm-specific codegen option:

-Wl,-plugin-opt=also-emit-llvm,-plugin-opt=-disable-fp-elim

The dumped whole problem bytecode would be sitting along with your final executable.

Two additional things are needed when using dragonegg.

First, the dragonegg is not aware of the location of llvm gold plugin, it needs to be specified in the linker flags like this -Wl,-plugin=/path/to/LLVMgold.so,-plugin-opt=...

Second, dragonegg is only able to dump IR rather than bytecode. You need a wrapper script for that purpose. I created one here. Works fine for me.

kula85
  • 73
  • 1
  • 9