blob: 70ab56716ebe548a57f0a1549efd70d333cf73d2 [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. These have all been fixed in the development
version.</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 can compile simple Java programs, but they don't execute properly
(this is a consequence of the java front-end not supporting GCC's LTO).</li>
<li>Limited debug info.</li>
<li>Versions 2.9 and earlier require patching gcc (the development version
does not).</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.9</a> is the most recent
DragonEgg release. It requires
<a href="http://llvm.org/releases/download.html#2.9">LLVM-2.9</a> and
<a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>.</p>
<p>The 2.9 release has the following notable changes:</p>
<ul>
<li>The plugin is much more stable when compiling Fortran.</li>
<li>Inline assembly where an asm output is tied to an input of a different
size is now supported in many more cases.</li>
<li>Basic support for the __float128 type was added. It is now possible
to generate LLVM IR from programs using __float128 but code generation
does not work yet.</li>
<li>Compiling Java programs no longer systematically crashes the
plugin.</li>
</ul>
<p>Common problems with building the DragonEgg-2.9 release:</p>
<ul>
<li>If you had to install the GMP, MPC or MPFR libraries locally in order
to build gcc-4.5, then the dragonegg build may fail due to not finding
header files from the libraries. You can tell the dragonegg build
system where to find them by setting CPPFLAGS before calling make:
<pre>
CPPFLAGS="-I/path/to/header/files -I/another/header/path/" make
</pre>
</li>
<li>
The build fails if you are using a case insensitive file system, such as
the default darwin filesystem <tt>HFS+</tt>. To fix this, apply
<a href="disambiguate.diff">this patch</a>.
</li>
</ul>
<li><p><a href="#gettingrelease">DragonEgg-2.8</a> was the second
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 had 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.9">DragonEgg-2.9 source code</a>:
<pre> wget http://llvm.org/releases/2.9/dragonegg-2.9.tgz</pre>
<p>Unpack it:</p>
<pre> tar xzf dragonegg-2.9.tgz</pre>
<p>Download the
<a href="http://llvm.org/releases/download.html#2.9">LLVM-2.9 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.2/gcc-4.5.2.tar.gz</pre>
<p>Unpack it:</p>
<pre> tar xzf gcc-4.5.2.tar.gz</pre>
<p>Apply the patch in <tt>dragonegg-2.9/gcc-patches/</tt> to the gcc-4.5
source:</p>
<pre> patch -d gcc-4.5.2 -p1 < dragonegg-2.9/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.9</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>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).</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>