| <!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> that replaces GCC's |
| optimizers and code generators with those from the |
| <a href="http://llvm.org">LLVM project</a>. It works with |
| <a href="http://gcc.gnu.org">gcc-4.5 or newer</a>, |
| can target the x86-32/x86-64 and ARM processor families, and has been |
| successfully used on the Darwin, FreeBSD, KFreeBSD, Linux and OpenBSD |
| platforms. It fully supports Ada, C, C++ and Fortran. It has partial support |
| for Go, Java, Obj-C and Obj-C++.</p> |
| |
| <br clear="all"> |
| |
| <!--=====================================================================--> |
| <h2>Goals</h2> |
| <!--=====================================================================--> |
| |
| <ul> |
| <li>Fully support all GCC languages</li> |
| </ul> |
| |
| <!--=====================================================================--> |
| <h2>Current Status</h2> |
| <!--=====================================================================--> |
| |
| <ul> |
| <li>Works best with <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a>.</li> |
| <li>Fortran works very well. Ada, C and C++ also work well. Ada works poorly |
| with <a href="http://gcc.gnu.org/gcc-4.7/">gcc-4.7</a> and later.</li> |
| <li>It can compile a reasonable amount of Obj-C, Obj-C++ and Go.</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>Debug info is poor.</li> |
| </ul> |
| |
| <!--=====================================================================--> |
| <h2>Releases</h2> |
| <!--=====================================================================--> |
| |
| <ul> |
| <li><p><a href="#gettingrelease">DragonEgg-3.3</a> is the most recent |
| DragonEgg release. It requires |
| <a href="http://llvm.org/releases/download.html#3.3">LLVM-3.3</a> and |
| <a href="http://gcc.gnu.org/">gcc 4.5 or newer</a>. |
| <p>The 3.3 release has the following notable changes:</p> |
| <ul> |
| |
| <li>Supports gcc-4.8 (requires gcc-4.8.1 or newer).</li> |
| <li>Object files can be written directly using LLVM’s integrated assembler.</li> |
| <li>Produces saner debug info.</li> |
| <li>Bitfields can now contain arbitrary scalar types (useful for Ada).</li> |
| |
| </ul> |
| |
| <li><p>DragonEgg-3.2 was the sixth DragonEgg release. It requires |
| <a href="http://llvm.org/releases/download.html#3.2">LLVM-3.2</a> and |
| <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>, |
| <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a> or |
| <a href="http://gcc.gnu.org/gcc-4.7/">gcc-4.7</a> (gcc-4.7 is only |
| partially supported). |
| <p>The 3.2 release has the following notable changes:</p> |
| <ul> |
| |
| <li>Able to load LLVM plugins such as Polly.</li> |
| |
| <li>Supports thread-local storage models.</li> |
| |
| <li>Passes knowledge of variable lifetimes to the LLVM optimizers.</li> |
| |
| <li>No longer requires GCC to be built with LTO support.</li> |
| |
| </ul> |
| |
| <li><p>DragonEgg-3.1 was the fifth DragonEgg release. It requires |
| <a href="http://llvm.org/releases/download.html#3.1">LLVM-3.1</a> and |
| <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>, |
| <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a> or |
| <a href="http://gcc.gnu.org/gcc-4.7/">gcc-4.7</a> (gcc-4.7 is only |
| partially supported). |
| <p>The 3.1 release has the following notable changes:</p> |
| <ul> |
| |
| <li>Partial support for gcc-4.7. Ada support is poor, but other languages |
| work fairly well.</li> |
| |
| <li>Support for ARM processors. Some essential gcc headers that are needed |
| to build DragonEgg for ARM are not installed by gcc. To work around |
| this, copy the missing headers from the gcc source tree.</li> |
| |
| <li>Better optimization for Fortran by exploiting the fact that Fortran |
| scalar arguments have 'restrict' semantics.</li> |
| |
| <li>Better optimization for all languages by passing information about |
| type aliasing and type ranges to the LLVM optimizers.</li> |
| |
| <li>A regression test-suite was added.</li> |
| |
| </ul> |
| |
| <li><p>DragonEgg-3.0 was the fourth DragonEgg release. It requires |
| <a href="http://llvm.org/releases/download.html#3.0">LLVM-3.0</a> and |
| <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a> or |
| <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a>. |
| <p>The 3.0 release has the following notable changes:</p> |
| <ul> |
| <li>GCC version 4.6 is now fully supported.</li> |
| |
| <li>Patching and building GCC is no longer required: the plugin should work |
| with your system GCC (version 4.5 or 4.6; on Debian/Ubuntu systems the |
| gcc-4.5-plugin-dev or gcc-4.6-plugin-dev package is also needed).</li> |
| |
| <li>The <tt>-fplugin-arg-dragonegg-enable-gcc-optzns</tt> option, which runs |
| GCC's optimizers as well as LLVM's, now works much better. This is the |
| option to use if you want ultimate performance! It is still experimental |
| though: it may cause the plugin to crash. Setting the optimization level |
| to <tt>-O4</tt> when using this option will optimize even harder, though |
| this usually doesn't result in any improvement over <tt>-O3</tt>.</li> |
| |
| <li>The type and constant conversion logic has been almost entirely rewritten, |
| fixing a multitude of obscure bugs.</li> |
| </ul> |
| <p>Known problems with the DragonEgg-3.0 release:</p> |
| <ul> |
| <li>The Makefile tries to use <tt>svnversion</tt> to get the LLVM |
| revision. To fix this, replace this line |
| <pre> |
| REVISION:=$(shell svnversion -n $(TOP_DIR)) |
| </pre> |
| with |
| <pre> |
| REVISION:=3.0 |
| </pre> |
| </li> |
| </ul> |
| <li><p>DragonEgg-2.9 was the third 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>DragonEgg-2.8 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&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 2.8 release 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#3.3">DragonEgg-3.3 source code</a>: |
| <pre> wget http://llvm.org/releases/3.3/dragonegg-3.3.src.tar.gz</pre> |
| <p>Unpack it:</p> |
| <pre> tar xzf dragonegg-3.3.src.tar.gz</pre> |
| <p>Install version 3.3 of LLVM, for example by downloading and installing the |
| <a href="http://llvm.org/releases/download.html#3.3">LLVM-3.3 binaries</a> |
| (mysteriously referred to as clang binaries) for your platform.</p> |
| <p>Make sure you have <a href="http://gcc.gnu.org/gcc-4.5/">gcc-4.5</a>, |
| <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a>, |
| <a href="http://gcc.gnu.org/gcc-4.7/">gcc-4.7</a> or |
| <a href="http://gcc.gnu.org/gcc-4.8/">gcc-4.8</a> installed (you do not need |
| to build your own copy); <a href="http://gcc.gnu.org/gcc-4.6/">gcc-4.6</a> works |
| best. On Debian and Ubuntu you need to install the corresponding |
| plugin-dev package (gcc-4.5-plugin-dev, gcc-4.6-plugin-dev, etc).</p> |
| <p>Doing</p> |
| <pre> GCC=gcc-4.6 make</pre> |
| <p>(if using gcc-4.6; otherwise replace gcc-4.6 with your gcc version) |
| in the <tt>dragonegg-3.3.src</tt> directory should then build |
| <tt>dragonegg.so</tt>. If the LLVM binaries are not in your path then you |
| can use</p> |
| <pre> GCC=gcc-4.6 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 gcc-4.6, or whatever |
| version of gcc you used, 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, gcc-4.6, gcc-4.7 or gcc-4.8 (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, gcc-4.6-plugin-dev, etc).</p> |
| <p>Doing</p> |
| <pre> GCC=place_you_installed_gcc/bin/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> |