DragonEgg logo

DragonEgg - Using LLVM as a GCC backend

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++.


Goals

Current Status

Releases

DragonEgg in action

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

Getting it

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.

Getting the development version

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.

It doesn't work!

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!

More information

There was a talk "Reimplementing llvm-gcc as a gcc plugin" about DragonEgg at the 2009 llvm developers meeting. At that time, DragonEgg was known as "the gcc plugin".

[Slides]

[Video(Computer)

[Video(Mobile)