| <!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&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&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&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 ; <[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 |
| </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>] <font size="-1">(Computer)</font></p> |
| <p>[<a href="http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin-mobile.m4v">Video</a>] <font size="-1">(Mobile)</font></p> |
| </div> |
| </body> |
| </html> |