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 under heavy development and is not mature - it may crash or produce wrong code. It works with gcc-4.5 which is nowhere near being released yet and is changing rapidly. This is an additional source of instability, and means that DragonEgg may fail to build from time-to-time if it has not caught up with the latest gcc changes. DragonEgg uses the development version of LLVM which creates similar problems.

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 causes LLVM IR to be output.

$ 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 DragonEgg:

	svn co http://llvm.org/svn/llvm-project/dragonegg/trunk dragonegg

Get the development version of LLVM:

	svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

Build LLVM in the usual way. You do not need to install it.

Get the development version of gcc:

	svn co http://gcc.gnu.org/svn/gcc/trunk gcc

Apply all of the patches in dragonegg/gcc-patches/, if any, to gcc. You need to pass the -p1 option to patch. Build and install gcc 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)