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

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

Unpack it:

	tar xzf dragonegg-2.7.tgz

Download the LLVM-2.7 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.0/gcc-4.5.0.tar.gz

Unpack it:

	tar xzf gcc-4.5.0.tar.gz

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

	patch -d gcc-4.5.0 -p1 < dragonegg-2.7/gcc-patches/i386_static.diff

Build and install gcc-4.5 in the usual way.

Doing

	GCC=path_to_just_installed_gcc make

in the dragonegg-2.7 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.

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.

Get the gcc-4.5 source code:

	svn co http://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch gcc-4.5

Apply all of the patches in dragonegg/gcc-patches/, if any, to the gcc-4.5 source. You need to pass the -p1 option to patch. Build and install gcc-4.5 in the usual way.

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)