DragonEgg logo

DragonEgg - Using LLVM as a GCC backend

DragonEgg is a gcc plugin dragonegg.so that replaces gcc's optimizers and code generators with those from the LLVM project.

It is a reimplementation of llvm-gcc that works with gcc-4.5 or later.


Goals

Current Status

DragonEgg is not mature - while it works quite well, it should not be considered production quality.

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-2.9 source code:

	wget http://llvm.org/releases/2.9/dragonegg-2.9.tgz

Unpack it:

	tar xzf dragonegg-2.9.tgz

Download the LLVM-2.9 binaries (mysteriously referred to as clang binaries) for your platform and install them.

Get the gcc-4.5 source code:

	wget http://mirrors.kernel.org/gnu/gcc/gcc-4.5.2/gcc-4.5.2.tar.gz

Unpack it:

	tar xzf gcc-4.5.2.tar.gz

Apply the patch in dragonegg-2.9/gcc-patches/ to the gcc-4.5 source:

	patch -d gcc-4.5.2 -p1 < dragonegg-2.9/gcc-patches/i386_static.diff

Build and install gcc-4.5 in the usual way, except that you should add the configure options --enable-plugin and --enable-lto.

Doing

	GCC=directory_where_gcc_installed/bin/gcc make

in the dragonegg-2.9 directory should then build dragonegg.so. If you have arranged for the gcc executable to occur in your path with the name gcc-4.5 (using a symbolic link for example) then there is no need to set the GCC variable: you can just do "make". If the LLVM binaries are not in your path then you can use

	GCC=directory_where_gcc_installed/bin/gcc 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 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.

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 or gcc-4.6 (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 or gcc-4.6-plugin-dev).

Doing

	GCC=path_to_just_installed_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)