DragonEgg is a gcc plugin that replaces GCC's optimizers and code generators with those from the LLVM project. It works with gcc-4.5 or newer, can target the x86-32/x86-64 and ARM processor families, and has been successfully used on the Darwin, FreeBSD, KFreeBSD, Linux and OpenBSD platforms. It fully supports Ada, C, C++ and Fortran. It has partial support for Go, Java, Obj-C and Obj-C++.
DragonEgg-3.3 is the most recent DragonEgg release. It requires LLVM-3.3 and gcc 4.5 or newer.
The 3.3 release has the following notable changes:
DragonEgg-3.2 was the sixth DragonEgg release. It requires LLVM-3.2 and gcc-4.5, gcc-4.6 or gcc-4.7 (gcc-4.7 is only partially supported).
The 3.2 release has the following notable changes:
DragonEgg-3.1 was the fifth DragonEgg release. It requires LLVM-3.1 and gcc-4.5, gcc-4.6 or gcc-4.7 (gcc-4.7 is only partially supported).
The 3.1 release has the following notable changes:
DragonEgg-3.0 was the fourth DragonEgg release. It requires LLVM-3.0 and gcc-4.5 or gcc-4.6.
The 3.0 release has the following notable changes:
Known problems with the DragonEgg-3.0 release:
REVISION:=$(shell svnversion -n $(TOP_DIR))with
REVISION:=3.0
DragonEgg-2.9 was the third DragonEgg release. It requires LLVM-2.9 and gcc-4.5.
The 2.9 release has the following notable changes:
Common problems with building the DragonEgg-2.9 release:
CPPFLAGS="-I/path/to/header/files -I/another/header/path/" make
DragonEgg-2.8 was the second DragonEgg release. It requires LLVM-2.8 and gcc-4.5.
The 2.8 release had the following notable changes:
Known problems with the DragonEgg-2.8 release:
DragonEgg-2.7 was the first ever DragonEgg release. It works with LLVM-2.7 and gcc-4.5.
Known problems with the DragonEgg-2.7 release:
These problems have been fixed in the 2.8 release of DragonEgg.
Here is the result of compiling a simple "hello world" program with gcc-4.5:
$ gcc hello.c -S -O1 -o - .file "hello.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "Hello world!" .text .globl main .type main, @function main: subq $8, %rsp movl $.LC0, %edi call puts movl $0, %eax addq $8, %rsp ret .size main, .-main .ident "GCC: (GNU) 4.5.0 20090928 (experimental)" .section .note.GNU-stack,"",@progbits
Adding -fplugin=path/dragonegg.so to the gcc command line causes the program to be optimized and codegened by LLVM instead:
$ gcc hello.c -S -O1 -o - -fplugin=./dragonegg.so .file "hello.c" # Start of file scope inline assembly .ident "GCC: (GNU) 4.5.0 20090928 (experimental) LLVM: 82450:82981" # End of file scope inline assembly .text .align 16 .globl main .type main,@function main: subq $8, %rsp movl $.L.str, %edi call puts xorl %eax, %eax addq $8, %rsp ret .size main, .-main .type .L.str,@object .section .rodata.str1.1,"aMS",@progbits,1 .L.str: .asciz "Hello world!" .size .L.str, 13 .section .note.GNU-stack,"",@progbits
Adding -fplugin-arg-dragonegg-emit-ir or -flto causes LLVM IR to be output (you need to request assembler output, -S, rather than object code output, -c, since otherwise gcc will pass the LLVM IR to the system assembler, which will doubtless fail to assemble it):
$ gcc hello.c -S -O1 -o - -fplugin=./dragonegg.so -fplugin-arg-dragonegg-emit-ir ; ModuleID = 'hello.c' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" module asm "\09.ident\09\22GCC: (GNU) 4.5.0 20090928 (experimental) LLVM: 82450:82981\22" @.str = private constant [13 x i8] c"Hello world!\00", align 1 ; <[13 x i8]*> [#uses=1] define i32 @main() nounwind { entry: %0 = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0] ret i32 0 } declare i32 @puts(i8* nocapture) nounwind
Get the DragonEgg-3.3 source code:
wget http://llvm.org/releases/3.3/dragonegg-3.3.src.tar.gz
Unpack it:
tar xzf dragonegg-3.3.src.tar.gz
Install version 3.3 of LLVM, for example by downloading and installing the LLVM-3.3 binaries (mysteriously referred to as clang binaries) for your platform.
Make sure you have gcc-4.5, gcc-4.6, gcc-4.7 or gcc-4.8 installed (you do not need to build your own copy); gcc-4.6 works best. On Debian and Ubuntu you need to install the corresponding plugin-dev package (gcc-4.5-plugin-dev, gcc-4.6-plugin-dev, etc).
Doing
GCC=gcc-4.6 make
(if using gcc-4.6; otherwise replace gcc-4.6 with your gcc version) in the dragonegg-3.3.src directory should then build dragonegg.so. If the LLVM binaries are not in your path then you can use
GCC=gcc-4.6 LLVM_CONFIG=directory_where_llvm_installed/bin/llvm-config make
If you only built LLVM and did not install it then you can still build dragonegg by setting LLVM_CONFIG to point to the copy of llvm-config in the build tree.
To use dragonegg.so, compile something with gcc-4.6, or whatever version of gcc you used, adding -fplugin=path_to_dragonegg/dragonegg.so to the command line. See the README file for more details and useful command line options.
Get the source code for the development version of DragonEgg:
svn co http://llvm.org/svn/llvm-project/dragonegg/trunk dragonegg
Get the source code for the development version of LLVM:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
Build LLVM in the usual way.
Install gcc-4.5, gcc-4.6, gcc-4.7 or gcc-4.8 (you do not need to build your own copy). On Debian and Ubuntu you need to install the corresponding plugin-dev package (gcc-4.5-plugin-dev, gcc-4.6-plugin-dev, etc).
Doing
GCC=place_you_installed_gcc/bin/gcc make
in the dragonegg directory should then build dragonegg.so. See the README file for more details.
To use dragonegg.so, compile something with your just-installed version of gcc, adding -fplugin=path_to_dragonegg/dragonegg.so to the command line. See the README file for more details and useful command line options.
Sorry about that! Please report bugs and problems to the LLVM developers' mailing list, or using LLVM's bugzilla.
Suggestions for improvement are welcome. Patches are even more welcome!
[Slides]
[Video] (Computer)
[Video] (Mobile)