blob: 5b0d64f10bd8ce897478bd6433708be4240e8d28 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>DragonEgg</title>
</head>
<body>
<div>
<img src="dragoneggsmall.png" alt="DragonEgg logo" width="136" height="136" align="left" hspace="30">
<!--*********************************************************************-->
<h1>DragonEgg - Using LLVM as a GCC backend</h1>
<!--*********************************************************************-->
<p><a href="#gettingrelease">DragonEgg</a> is a
<a href="http://gcc.gnu.org/wiki/plugins">gcc plugin</a> <tt>dragonegg.so</tt>
that replaces gcc's optimizers and code generators with those from the
<a href="http://llvm.org">LLVM project</a>.</p>
<p>It is a reimplementation of
<a href="http://llvm.org/docs/CommandGuide/">llvm-gcc</a>
that works with <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a> or later.</p>
<br clear="all">
<!--=====================================================================-->
<h2>Goals</h2>
<!--=====================================================================-->
<ul>
<li>Work with unmodified gcc</li>
<li>Support all gcc languages</li>
</ul>
<!--=====================================================================-->
<h2>Current Status</h2>
<!--=====================================================================-->
<ul>
<li>C works well, for example you can build a working gcc using it</li>
<li>C++ works fairly well, for example you can build LLVM, clang and boost
with it (the resulting LLVM and clang work correctly; boost mostly works but
there are some mysterious failures)</li>
<li>Fortran works fairly well, for example SPEC CPU mostly compiles and works,
but there are some failures</li>
<li>It can compile quite a lot of Ada, and the compiled code mostly seems to
work</li>
<li>It can compile a small amount of Obj-C and Obj-C++</li>
<li>It fails to compile any Java</li>
<li>Limited debug info</li>
<li>Requires patching gcc</li>
<li>Only supports x86-32 and x86-64</li>
<li>Only supports linux, darwin and freebsd (additional gcc patches may be
needed on darwin, see the <tt>README</tt> file).
</ul>
<p>DragonEgg is not mature - while it works quite well, it should not be
considered production quality.</p>
<!--=====================================================================-->
<h2>Releases</h2>
<!--=====================================================================-->
<ul>
<li><p><a href="#gettingrelease">DragonEgg-2.8</a> is the most recent
DragonEgg release. It requires
<a href="http://llvm.org/releases/download.html#2.8">LLVM-2.8</a> and
<a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>.</p>
<p>The 2.8 release has the following notable changes:</p>
<ul>
<li>The plugin loads faster due to exporting fewer symbols.</li>
<li>Additional vector operations such as addps256 are now supported.</li>
<li>Ada global variables with no initial value are no longer zero initialized,
resulting in better optimization.</li>
<li>The '-fplugin-arg-dragonegg-enable-gcc-optzns' flag now runs all gcc
optimizers, rather than just a handful.</li>
<li>Fortran programs using common variables now link correctly.</li>
<li>GNU OMP constructs no longer crash the compiler.</li>
</ul>
<p>Known problems with the DragonEgg-2.8 release:</p>
<ul>
<li>Functions returning complex numbers are not handled in an ABI
conformant way. This means for example that if code compiled with
dragonegg calls a function in a system library that returns a complex
number then you get a bogus result. The fix in
<a href="http://llvm.org/viewvc/llvm-project?view=rev&amp;revision=117649">subversion commit 117649</a>
can be applied to the dragonegg-2.8 source to resolve the problem.</li>
<li>Calling <tt>floor</tt> then converting the result to a long integer
type can result in link failures due to an undefined reference to
<tt>__builtin_lfloor</tt>. Likewise for <tt>ceil</tt> and variants
like <tt>floorf</tt>. The fix in
<a href="http://llvm.org/viewvc/llvm-project?view=rev&amp;revision=118499">subversion commit 118499</a>
can be applied to the dragonegg-2.8 source to resolve the problem.</li>
<li>Some OpenMP programs fail to work when compiled without optimization.
This has been fixed in the development version of LLVM. Compile at
<tt>-O1</tt> or better to workaround this.</li>
<li>Programs that throw an uncaught exception when there are destructors
to be run when unwinding would crash rather than terminating cleanly.
The fix in
<a href="http://llvm.org/viewvc/llvm-project?view=rev&amp;revision=120096">subversion commit 120096</a>
can be applied to the dragonegg-2.8 source to resolve the problem.</li>
</ul>
<li><p>DragonEgg-2.7 was the first ever DragonEgg release. It works with
<a href="http://llvm.org/releases/download.html#2.7">LLVM-2.7</a> and
<a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>.</p>
<p>Known problems with the DragonEgg-2.7 release:</p>
<ul>
<li>If <tt>gcc-4.5</tt> was configured with a target triple of the form
<tt>x86_64-linux-gnu</tt> or <tt>i386-linux-gnu</tt> then the build
fails with <tt>"error: llvm-os.h: No such file or directory"</tt>.
Use the four component style <tt>x86_64-unknown-linux-gnu</tt> or
<tt>i386-unknown-linux-gnu</tt> instead.</li>
<li>Fortran common variables may not be output when they should be,
causing link failures.</li>
<li>Programs using OpenMP directives crash the plugin.</li>
</ul>
<p>These problems have been fixed in the
<a href="#gettingrelease">2.8 release</a> of DragonEgg.</p>
</li>
</ul>
<!--=====================================================================-->
<h2>DragonEgg in action</h2>
<!--=====================================================================-->
<p>Here is the result of compiling a simple "hello world" program with gcc-4.5:</p>
<pre>
$ 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
</pre>
<p>Adding <tt>-fplugin=path/dragonegg.so</tt> to the gcc command line causes
the program to be optimized and codegened by LLVM instead:</p>
<pre>
$ 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
</pre>
<p>Adding <tt>-fplugin-arg-dragonegg-emit-ir</tt> or <tt>-flto</tt> 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):</p>
<pre>
$ 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 ; &lt;[13 x i8]*&gt; [#uses=1]
define i32 @main() nounwind {
entry:
%0 = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i64 0, i64 0)) nounwind ; &lt;i32&gt; [#uses=0]
ret i32 0
}
declare i32 @puts(i8* nocapture) nounwind
</pre>
<!--=====================================================================-->
<h2><a name="gettingrelease">Getting it</a></h2>
<!--=====================================================================-->
<p>Get the
<a href="http://llvm.org/releases/download.html#2.8">DragonEgg-2.8 source code</a>:
<pre> wget http://llvm.org/releases/2.8/dragonegg-2.8.tar.gz</pre>
<p>Unpack it:</p>
<pre> tar xzf dragonegg-2.8.tar.gz</pre>
<p>Download the
<a href="http://llvm.org/releases/download.html#2.8">LLVM-2.8 binaries</a>
(mysteriously referred to as clang binaries) for your platform and install
them.</p>
<p>Get the <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5 source code</a>:</p>
<pre> wget http://mirrors.kernel.org/gnu/gcc/gcc-4.5.1/gcc-4.5.1.tar.gz</pre>
<p>Unpack it:</p>
<pre> tar xzf gcc-4.5.1.tar.gz</pre>
<p>Apply the patch in <tt>dragonegg-2.8/gcc-patches/</tt> to the gcc-4.5
source:</p>
<pre> patch -d gcc-4.5.1 -p1 < dragonegg-2.8/gcc-patches/i386_static.diff</pre>
<p><a href="http://gcc.gnu.org/install/">Build and install gcc-4.5</a> in the
usual way, except that you should add the configure options <tt>--enable-plugin</tt>
and <tt>--enable-lto</tt>.</p>
<p>Doing</p>
<pre> GCC=directory_where_gcc_installed/bin/gcc make</pre>
<p>in the <tt>dragonegg-2.8</tt> directory should then build <tt>dragonegg.so</tt>.
If you have arranged for the gcc executable to occur in your path with the
name <tt>gcc-4.5</tt> (using a symbolic link for example) then there is no
need to set the GCC variable: you can just do "<tt>make</tt>".
If the LLVM binaries are not in your path then you can use</p>
<pre> GCC=directory_where_gcc_installed/bin/gcc LLVM_CONFIG=directory_where_llvm_installed/bin/llvm-config make</pre>
<p>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.</p>
<p>To use <tt>dragonegg.so</tt>, compile something with your just-installed
version of <tt>gcc</tt>, adding <tt>-fplugin=path_to_dragonegg/dragonegg.so</tt>
to the command line. See the <tt>README</tt> file for more details and useful
command line options.</p>
<!--=====================================================================-->
<h2><a name="gettingdevel">Getting the development version</a></h2>
<!--=====================================================================-->
<p>Get the source code for the development version of DragonEgg:</p>
<pre> svn co http://llvm.org/svn/llvm-project/dragonegg/trunk dragonegg</pre>
<p>Get the source code for the development version of LLVM:</p>
<pre> svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</pre>
<p><a href="http://llvm.org/docs/GettingStarted.html">Build LLVM</a> in the
usual way.</p>
<p>Get the <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5 source code</a>:</p>
<pre> svn co http://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch gcc-4.5</pre>
<p>Apply all of the patches in <tt>dragonegg/gcc-patches/</tt>, if any, to the
gcc-4.5 source. You need to pass the <tt>-p1</tt> option to <tt>patch</tt>.
<a href="http://gcc.gnu.org/install/">Build and install gcc-4.5</a> in the
usual way.</p>
<p>Doing</p>
<pre> GCC=path_to_just_installed_gcc make</pre>
<p>in the <tt>dragonegg</tt> directory should then build <tt>dragonegg.so</tt>.
See the <tt>README</tt> file for more details.</p>
<p>To use <tt>dragonegg.so</tt>, compile something with your just-installed
version of <tt>gcc</tt>, adding <tt>-fplugin=path_to_dragonegg/dragonegg.so</tt>
to the command line. See the <tt>README</tt> file for more details and useful
command line options.</p>
<!--=====================================================================-->
<h2>It doesn't work!</h2>
<!--=====================================================================-->
<p>Sorry about that! Please report bugs and problems to the LLVM developers'
<a href="http://llvm.org/docs/#maillist">mailing list</a>, or using LLVM's
<a href="http://llvm.org/bugs/">bugzilla</a>.</p>
<p>Suggestions for improvement are welcome. Patches are even more welcome!</p>
<!--=====================================================================-->
<h2>More information</h2>
<!--=====================================================================-->
There was a talk "Reimplementing llvm-gcc as a gcc plugin" about DragonEgg at
the
<a href="http://llvm.org/devmtg/2009-10/">2009 llvm developers meeting</a>.
At that time, DragonEgg was known as "the gcc plugin".
<p>[<a href="http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf">Slides</a>]</p>
<p>[<a href="http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin-700kbps.mov">Video</a>]&nbsp;<font size="-1">(Computer)</font></p>
<p>[<a href="http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin-mobile.m4v">Video</a>]&nbsp;<font size="-1">(Mobile)</font></p>
</div>
</body>
</html>