<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1862878851303132605</id><updated>2011-11-01T09:13:53.207-04:00</updated><category term='GRIN'/><category term='LLVM'/><category term='benchmark'/><category term='native code generator'/><category term='typeclasses'/><category term='Optimizations'/><category term='garbage collection'/><title type='text'>Notes on the LHC</title><subtitle type='html'>No, not that Hadron Collider. The Haskell Compiler.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>SamB</name><uri>http://www.blogger.com/profile/06560268240719951351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.gravatar.com/avatar.php?gravatar_id=165e55c78689e561c554c3dec671fb50'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-8888684820432265267</id><published>2010-10-19T16:09:00.005-04:00</published><updated>2010-10-19T18:30:02.791-04:00</updated><title type='text'>Rough organizational overview.</title><content type='html'>The exact details are constantly changing but here's a rough overview of the LHC pipeline.&lt;div&gt;&lt;ol&gt;&lt;li&gt;External Core.&lt;br /&gt;We've designed our compiler to use GHC as its frontend. This means that GHC will handle the parsing and type-checking of the Haskell code in addition to some of the optimization (GHC particularly excels at high-level local optimizations). LHC benefits greatly by automatically supporting many of the Haskell extensions offered by GHC.&lt;br /&gt;Notable characteristics: Non-strict, local functions, complex let-bindings. Pretty much just Haskell code with zero syntactic sugar.&lt;br /&gt;Example snippet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  base:Data.Either.$fShowEither :: ghc-prim:GHC.Types.Int =&lt;br /&gt;    ghc-prim:GHC.Types.I# (11::ghc-prim:GHC.Prim.Int#);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Simple Core.&lt;br /&gt;Since External Core isn't immediately ready to be processed into GRIN code, we first translate it to Simple Core by removing or simplifying out a couple of features. The most noticeable feature of External Core is locally scoped functions which simply does not fit in with the GRIN model. When translating to Simple Core, we hoist out all local functions to the top-level.&lt;br /&gt;Notable characteristics: Non-strict, no local functions, simplified let-bindings.&lt;/li&gt;&lt;li&gt;Grin Stage 1.&lt;br /&gt;Let me start by introducing GRIN: GRIN (Graph Reduction Intermediate Notation) is a first order, strict, (somewhat) functional language.&lt;br /&gt;The purpose of this first stage of grin code is to encode the laziness explicitly. It turns out that you can translate a lazy language (like Simple Core) to a strict language (like GRIN) using only two primitives: Eval and apply. The 'eval' primitives takes a closure, evaluates it if need be and returns the resulting object. The 'apply' primitives simply adds an argument to a closure. Haskell compilers such as GHC, JHC and UHC all use this model for implementing laziness.&lt;br /&gt;Notable characteristics: Strict, explicit laziness, opaque closures.&lt;br /&gt;Example snippet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;base:Foreign.C.Types.@lifted_exp@ w ws =&lt;br /&gt;  do x2508 &lt;- @eval ws&lt;br /&gt;     case x2508 of&lt;br /&gt;       (Cbase:GHC.Int.I32# x#)&lt;br /&gt;         -&gt; do x2510 &lt;- unit 11&lt;br /&gt;               base:GHC.Show.$wshowSignedInt x2510 x# w&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Grin Stage 2.&lt;br /&gt;At the time of writing, each of the mentioned compilers stop at the previous stage (or at what would be their equivalent of that stage).[1]  LHC follows in the footsteps of the original GRIN compiler and applies a global control-flow analysis to eliminate/inline all eval/apply primitives. In the end, a lazy/suspended function taking, say, two arguments simply becomes a data constructor with two fields.&lt;br /&gt;Notable characteristics: Strict, transparent closures.&lt;br /&gt;Example snippet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;base:Foreign.Marshal.Utils.toBool1_caf =&lt;br /&gt;  do [x2422] &lt;- constant 0&lt;br /&gt;     [x2423] &lt;- @realWorld#&lt;br /&gt;     [x2424 x2425] &lt;- (foreign lhc_mp_from_int) x2422 x2423&lt;br /&gt;     [x2426] &lt;- constant Cinteger-gmp:GHC.Integer.Type.Integer&lt;br /&gt;     unit [x2426 x2425]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Grin Stage 3.&lt;br /&gt;Things are starting to get fairly low-level already at stage 2. However, stage 2 is still a bit too high-level for some optimizations to be easily implemented. Stage 3 breaks the code into smaller blocks that can easily be moved, inlined and short-circuited. The code is now sufficiently low-level that it can be pretty-printed as C.&lt;br /&gt;Notable characteristics: Functions are broken down to functional units. Otherwise same as stage 2.&lt;br /&gt;Example snippet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;base:GHC.IO.Encoding.Iconv.@lifted@_lvl60swYU38 rb3 rb4 =&lt;br /&gt;  do [x21578] &lt;- @-# rb4 rb3&lt;br /&gt;     case x21578 of&lt;br /&gt;       0 -&gt; constant Cghc-prim:GHC.Bool.False&lt;br /&gt;       () -&gt; constant Cghc-prim:GHC.Bool.True&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Grin--.&lt;br /&gt;Grin-- is the latest addition to the heap and not much is known about it for certain. It is even up for debate whether it belongs to the GRIN family at all since it diverge from the SSA style.&lt;br /&gt;The purpose of Grin-- is to provide a vessel for expressing stack operations.&lt;br /&gt;Notable characteristics: Operates on global virtual registers, enables explicit stack management.&lt;br /&gt;Example snippet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;base:GHC.IO.Encoding.Iconv.@lifted@_lvl60swYU38:&lt;br /&gt;  do x21578 := -# rb4 rb3&lt;br /&gt;     case x21578 of&lt;br /&gt;       0 -&gt; do x88175 := Cghc-prim:GHC.Bool.False&lt;br /&gt;               ret&lt;br /&gt;       () -&gt; do x88175 := Cghc-prim:GHC.Bool.True&lt;br /&gt;                ret&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Feel free to ask if you have any questions on the how and why of LHC.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[1] UHC does have the mechanics for lowering the eval/apply primitives but it is not enabled by default.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-8888684820432265267?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/8888684820432265267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/rough-organizational-overview.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/8888684820432265267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/8888684820432265267'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/rough-organizational-overview.html' title='Rough organizational overview.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-1818382839170393764</id><published>2010-10-16T13:13:00.004-04:00</published><updated>2010-10-18T08:41:57.500-04:00</updated><title type='text'>Accurate garbage collection.</title><content type='html'>So, let's talk about garbage collection. Garbage collection is a very interesting topic because it is exceedingly simple in theory but very difficult in practice.&lt;br /&gt;&lt;br /&gt;To support garbage collection, the key thing a language implementor has to do is to provide a way for the GC to find all live heap pointers (called root pointers). This sounds fairly easy to do but can get quite complicated in the presence of aggressive optimizations and register allocation. A tempting (and often used) solution would be to break encapsulation and make the optimizations aware of the GC requirements. This of course becomes harder the more advanced the optimizations are and with LHC it is pretty much impossible. Consider the following GRIN code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-- 'otherFunction' returns an object of type 'Maybe Int' using two virtual registers.&lt;br /&gt;-- If 'x' is 'Nothing' then 'y' is undefined.&lt;br /&gt;-- If 'x' is 'Just' then 'y' is a root pointer.&lt;br /&gt;someFunction&lt;br /&gt; = do x, y &lt;- otherFunction; .... &lt;/pre&gt;&lt;br /&gt;The above function illustrates that it is not always straightforward to figure out if a variable contains a root pointer. Sometimes determining that requires looking at other variables.&lt;br /&gt;&lt;br /&gt;So how might we get around this hurdle, you might ask. Well, if the code for marking roots resides in user-code instead of in the RTS then it can be as complex as it needs be. This fits well with the GRIN ideology of expressing an much in user-code as possible.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that we're familiar with the problem and the general concept of the solution, let's work out some of the details. Here's what happens when a GC event is triggered, described algorithmically:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Save registers to memory.&lt;br /&gt;This is to avoid clobbering the registers and to make them accessible from the GC code.&lt;/li&gt;&lt;li&gt;Save stack pointer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Initiate temporary stack.&lt;br /&gt;Local variables from the GC code will be placed on this stack.&lt;/li&gt;&lt;li&gt;Jump to code for marking root pointers.&lt;br /&gt;This will peel back each stack frame until the bottom of the call graph has been reached.&lt;/li&gt;&lt;li&gt;Discard temporary stack.&lt;/li&gt;&lt;li&gt;Restore stack pointer&lt;/li&gt;&lt;li&gt;Restore registers.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Using the approach for exception involves stack cutting and a more advanced transfer of control which will be discussed in a later post.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In conclusion, these are the advantages native-code stack walking:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Allows for objects to span registers as well as stack slots.&lt;/li&gt;&lt;li&gt;Separates the concerns of the optimizer, the garbage collector and the code generator.&lt;/li&gt;&lt;li&gt;Might be a little bit faster than dynamic stack walking since the stack layout is statically encoded.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-1818382839170393764?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/1818382839170393764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/accurate-garbage-collection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1818382839170393764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1818382839170393764'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/accurate-garbage-collection.html' title='Accurate garbage collection.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-6282255810574675296</id><published>2010-10-16T11:55:00.005-04:00</published><updated>2010-10-16T14:40:11.621-04:00</updated><title type='text'>A few updates.</title><content type='html'>Not much has been put up on this blog lately but work is still going on under the hood. The most significant changes in the pipeline are proper tail-calls and a copying garbage collector.&lt;br /&gt;&lt;br /&gt;As it stands now, LHC uses the C stack extensively but this is obviously not ideal as it makes garbage collection, exceptions and tail-calls nigh impossible to implement. Since the ideal solution of using a third party target language isn't available (neither LLVM or C-- supports arbitrary object models), I've decided to slowly inch closer to a native code generator for LHC. It is fortunate that I find &lt;a href="http://code.haskell.org/lhc/papers/Automatically%20Generating%20the%20Backend%20of%20a%20Compiler%20Using%20Declarative%20Machine%20Descriptions.pdf"&gt;Joao Dias' dissertation&lt;/a&gt; nearly as interesting as the &lt;a href="http://code.haskell.org/lhc/papers/Code%20Optimization%20Techniques%20for%20Lazy%20Functional%20Languages.pdf"&gt;GRIN paper&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The first step would be to make the stack layout explicit in the GRIN code. This is necessary but not sufficient for tail-calls (some register coalescing is also required. More on this later).  More importantly, accurate garbage collection now becomes a possibility. The way I want to implement garbage collection (and exceptions for that matter) is through alternative return points. This is one of three methods discussed in a &lt;a href="http://research.microsoft.com/en-us/um/people/simonpj/papers/c--/c--exn.htm"&gt;C-- paper by Norman Ramsey and Simon Peyton Jones&lt;/a&gt; for implementing &lt;span style="font-style: italic;"&gt;exceptions&lt;/span&gt;. I believe this method is versatile enough for garbage collection as well.&lt;br /&gt;&lt;br /&gt;The concept revolves around using specialized code at each call site that knows enough about the stack layout to mark root pointers and to jump to the next stack frame. I will describe the details in another blog post. An interesting point is that the garbage collectors could be written in user-code instead of in the RTS.&lt;br /&gt;&lt;br /&gt;So, to recap: Accurate garbage collection is just around the corner and proper tail-calls will follow in its heels. These two missing features are the reason that so many of the benchmarks fail to run for LHC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-6282255810574675296?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/6282255810574675296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/few-updates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/6282255810574675296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/6282255810574675296'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/10/few-updates.html' title='A few updates.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-5653666825112978620</id><published>2010-07-25T17:09:00.002-04:00</published><updated>2010-07-25T17:19:31.715-04:00</updated><title type='text'>The Great Haskell Compiler shootout</title><content type='html'>David has been working very hard recently on improving LHC and the nobench benchmark suite, in order to actively benchmark LHC against several other haskell compilers: GHC, JHC and UHC.&lt;br /&gt;&lt;br /&gt;I figured I'd pop in and announce the benchmarks now that the latest HEAD version of LHC can compile many of them and we can get some meaningful numbers. You can see the results &lt;a href="http://mirror.seize.it/report.html"&gt;here&lt;/a&gt;. Note there are two columns for JHC: one using john's new garbage collector (via `-fjgc`) and one without, because naturally it tends to affect performance characteristics quite a bit. Some of the numbers are quite interesting: in particular, JHC is nearly 400x faster(!) than GHC on the atom benchmark, and UHC dominates the calendar benchmark currently (we haven't investigated why GHC isn't winning here.) There are also some interesting variations in JHC, where the garbage collector wins in some cases, loses in others, but makes the difference in some between actually running and running out of memory (as you would expect.)&lt;br /&gt;&lt;br /&gt;Perhaps somewhat regrettably, LHC loses in every benchmark. But we're only just beginning to implement real optimizations now that things are somewhat stabilized and the interface isn't arcane - prior to this we had very few optimizations outside of dead code elimination, simplification and a bit of inlining. David's begun implementing some more exotic optimizations recently, so it'll be interesting to see the results soon.&lt;br /&gt;&lt;br /&gt;Now we'll be able to more actively see the progress of optimizing haskell compilers. Should be fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-5653666825112978620?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/5653666825112978620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/07/great-haskell-compiler-shootout.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/5653666825112978620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/5653666825112978620'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/07/great-haskell-compiler-shootout.html' title='The Great Haskell Compiler shootout'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-1840175132892196801</id><published>2010-06-11T11:22:00.004-04:00</published><updated>2010-06-11T11:26:20.445-04:00</updated><title type='text'>Mirroring Boquists' GRIN papers</title><content type='html'>Urban Boquists PhD thesis, Code Optimization Techniques for Lazy Functional Languages, and its accompanying &lt;a href="http://www.cs.chalmers.se/%7Eboquist/"&gt;website&lt;/a&gt; have gone offline. Because these papers describe GRIN, the intermediate language we use in LHC, I have decided to mirror Boquist's 3 GRIN-related papers on my own server &lt;a href="http://0xff.ath.cx/%7Eas/code/lhc/papers/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If someone inside Chalmers could explain where his papers moved and if we could get them back online, that would be great!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-1840175132892196801?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/1840175132892196801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/06/mirroring-boquists-grin-papers.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1840175132892196801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1840175132892196801'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/06/mirroring-boquists-grin-papers.html' title='Mirroring Boquists&apos; GRIN papers'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-1935842952859753459</id><published>2010-05-29T12:16:00.004-04:00</published><updated>2010-06-02T14:39:59.344-04:00</updated><title type='text'>The new interface</title><content type='html'>After hacking away for a little bit, I've finally gotten the new user interface for LHC working!&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;a ~/code/lhc/test $ lhc --help&lt;br /&gt;The LHC Haskell Compiler, v0.11, (C) 2009-2010 David Himmelstrup, Austin Seipp&lt;br /&gt;&lt;br /&gt;lhc [FLAG] [FILE]&lt;br /&gt;Compile Haskell code&lt;br /&gt;&lt;br /&gt;-? --help[=FORMAT]        Show usage information (optional format)&lt;br /&gt;-V --version              Show version information&lt;br /&gt;-v --verbose              Higher verbosity&lt;br /&gt;-q --quiet                Lower verbosity&lt;br /&gt;--llvm                 Use LLVM backend&lt;br /&gt;--ghc-opts=VALUE       Give GHC frontend options&lt;br /&gt;-i --install-library      Don't compile; install modules under a library&lt;br /&gt;-b --build-library        Used when compiling a library (cabal only)&lt;br /&gt;-O =VALUE                 Set optimization level (default=1)&lt;br /&gt;--numeric-version      Raw numeric version output&lt;br /&gt;--supported-languages  List supported LANGUAGE pragmas&lt;br /&gt;-c                        Do not link, only compile&lt;br /&gt;-o =VALUE                 output file for binary (default=a.out)&lt;br /&gt;--src-dir=VALUE        source code directory&lt;br /&gt;a ~/code/lhc/test $ lhc HelloWorld.hs&lt;br /&gt;[1 of 1] Compiling Main             ( HelloWorld.hs, HelloWorld.o )&lt;br /&gt;.....................&lt;br /&gt;Found fixpoint in 7 iterations.&lt;br /&gt;Lowering apply primitives...            done in   0.09s&lt;br /&gt;Heap points-to analysis...              ...........................done in   0.95s&lt;br /&gt;HPT fixpoint found in 27 iterations.&lt;br /&gt;..................................................................................&lt;br /&gt;Found fixpoint in 11 iterations.&lt;br /&gt;Compiling C code...                     done in   0.11s&lt;br /&gt;a ~/code/lhc/test $ ./HelloWorld&lt;br /&gt;Hello, world!&lt;br /&gt;a ~/code/lhc/test $&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The changes should be landing shortly. It will require a patch to Cabal. There is also a bug in cabal/cmdargs that I have not yet tracked down which makes installing cabal packages difficult, although still possible, with this new scheme.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Edit 6-2-2010&lt;/span&gt;: all of the necessary patches have been pushed to both LHC and Cabal to make the new user interface work. Try it out (install using 'cabal install -fwith-libs' provided you have the darcs HEAD version of Cabal,) and tell us of any corner cases on IRC (#lhc-compiler on freenode)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-1935842952859753459?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/1935842952859753459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/new-interface.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1935842952859753459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1935842952859753459'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/new-interface.html' title='The new interface'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-4927659293763305740</id><published>2010-05-27T11:36:00.008-04:00</published><updated>2010-05-27T12:05:02.389-04:00</updated><title type='text'>A new user interface for LHC</title><content type='html'>The current user interface for LHC is pretty unwieldy - it requires you to invoke lhc twice: once to generate an external core file, and another to generate the executable with LHC itself.&lt;br /&gt;&lt;br /&gt;There are a couple of problems with this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It requires -you- to keep track of the generated .hcr files, which is a PITA.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It makes the test suite complicated, as we currently our own regression tool to handle things like #1. I would like to use Simon Michael's excellent &lt;a href="http://hackage.haskell.org/package/shelltestrunner"&gt;shelltestrunner&lt;/a&gt; library, but the two-step compilation process would make the test files nastier than they would be, and it so we currently maintain our own regression tool.&lt;/li&gt;&lt;li&gt;It made some of LHC's code very gross: we basically copied GHC's "Main.hs" file and stuck it in our source tree with some modifications, because we need to be able to accept all GHC options, even "insert arbitrary ghc option here" (for general usage, and cabal install support.) This was - as you could guess, incredibly fragile in terms of maintenance and fowards/backwards compatibility. &lt;/insert&gt;&lt;/li&gt;&lt;/ol&gt;So now I've devised a new approach. We will instead run GHC in the background, twice: the first, we will call GHC to compile your code with your provided options, and we will generally always stick something like '--make -fext-core -c' onto your command line to generate external core. The second time, we will call GHC &lt;span style="font-style: italic;"&gt;again&lt;/span&gt;, but instead we will call ghc with the '-M' command line flag. This flag calls GHC to generate a Makefile that describes the dependency information between modules. Running it on Tom Hawkin's &lt;a href="http://hackage.haskell.org/package/atom"&gt;atom&lt;/a&gt; project, you get something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# DO NOT DELETE: Beginning of Haskell dependencies&lt;br /&gt;Language/Atom/Expressions.o : Language/Atom/Expressions.hs&lt;br /&gt;Language/Atom/Elaboration.o : Language/Atom/Elaboration.hs&lt;br /&gt;Language/Atom/Elaboration.o : Language/Atom/Expressions.hi&lt;br /&gt;Language/Atom/Analysis.o : Language/Atom/Analysis.hs&lt;br /&gt;Language/Atom/Analysis.o : Language/Atom/Expressions.hi&lt;br /&gt;Language/Atom/Analysis.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Scheduling.o : Language/Atom/Scheduling.hs&lt;br /&gt;Language/Atom/Scheduling.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Scheduling.o : Language/Atom/Analysis.hi&lt;br /&gt;Language/Atom/Language.o : Language/Atom/Language.hs&lt;br /&gt;Language/Atom/Language.o : Language/Atom/Expressions.hi&lt;br /&gt;Language/Atom/Language.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Language.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Common.o : Language/Atom/Common.hs&lt;br /&gt;Language/Atom/Common.o : Language/Atom/Language.hi&lt;br /&gt;Language/Atom/Code.o : Language/Atom/Code.hs&lt;br /&gt;Language/Atom/Code.o : Language/Atom/Scheduling.hi&lt;br /&gt;Language/Atom/Code.o : Language/Atom/Expressions.hi&lt;br /&gt;Language/Atom/Code.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Code.o : Language/Atom/Analysis.hi&lt;br /&gt;Language/Atom/Compile.o : Language/Atom/Compile.hs&lt;br /&gt;Language/Atom/Compile.o : Language/Atom/Language.hi&lt;br /&gt;Language/Atom/Compile.o : Language/Atom/Elaboration.hi&lt;br /&gt;Language/Atom/Compile.o : Language/Atom/Scheduling.hi&lt;br /&gt;Language/Atom/Compile.o : Language/Atom/Code.hi&lt;br /&gt;Language/Atom.o : Language/Atom.hs&lt;br /&gt;Language/Atom.o : Language/Atom/Language.hi&lt;br /&gt;Language/Atom.o : Language/Atom/Common.hi&lt;br /&gt;Language/Atom.o : Language/Atom/Compile.hi&lt;br /&gt;Language/Atom.o : Language/Atom/Code.hi&lt;br /&gt;# DO NOT DELETE: End of Haskell dependencies&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This tells us the location of where all the generated object files are. GHC will put external core files next to these other object files (in all cases, as you cannot redirect the output location of external core files.) So we can just parse this simple Makefile, remove duplicates, and substitute '.o' files for '.hcr' files. LHC takes care of the rest.&lt;br /&gt;&lt;br /&gt;This is of course in the event you want to compile an executable. If you want to compile a library, it's mostly the same, only when we parse the files we just store them for later.&lt;br /&gt;&lt;br /&gt;But what about "obscure ghc option"? No fear! We'll just provide something like a --ghc-options flag which will get passed onto GHC's invocations. LHC can then have it's own, more general command line interface to control various options in the whole-program stages (on this note, Neil Mitchell's &lt;a href="http://hackage.haskell.org/package/cmdargs"&gt;cmdargs&lt;/a&gt; library is amazing for this stuff!)&lt;br /&gt;&lt;br /&gt;For default options to GHC, I think we should perhaps stick to the Haskell 2010 standard - that is, by default, LHC will run GHC with language options to enable compilation of compliant Haskell 2010 code without any OPTIONS_GHC or LANGUAGE pragmas. Optimization levels for GHC can be implied by LHC's supplied optimization level or explicitly via --ghc-options.&lt;br /&gt;&lt;br /&gt;Comments are always welcome.&lt;/obscure&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-4927659293763305740?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/4927659293763305740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/new-user-interface-for-lhc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/4927659293763305740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/4927659293763305740'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/new-user-interface-for-lhc.html' title='A new user interface for LHC'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-4784074898598194083</id><published>2010-05-24T09:54:00.003-04:00</published><updated>2010-05-24T16:33:42.836-04:00</updated><title type='text'>Limited release.</title><content type='html'>This release of lhc-0.10 marks the move to GHC-6.12 and hopefully a more stable build infrastructure. As it stands, lhc-0.10 still lacks support for several important features, such as floating point values and large parts of the FFI.&lt;br /&gt;&lt;br /&gt;To install LHC you need the development versions of Cabal and cabal-install. They can be fetched from these darcs repositories:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  darcs get --lazy http://darcs.haskell.org/cabal&lt;br /&gt;  darcs get --lazy http://darcs.haskell.org/cabal-install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you've installed both Cabal and cabal-install, lhc-0.10 can be installed with the following command:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  cabal install lhc-0.10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's how to use LHC once it has been successfully installed:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  lhc -c SourceFile.hs        # This compiles SourceFile.hs to SourceFile.hcr&lt;br /&gt;  lhc compile SourceFile.hcr  # This compiles SourceFile.hcr to the executable SourceFile.&lt;br /&gt;  ./SourceFile&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy Hacking.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-4784074898598194083?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/4784074898598194083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/limited-release.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/4784074898598194083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/4784074898598194083'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/limited-release.html' title='Limited release.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-9078585081764514791</id><published>2010-05-18T12:48:00.003-04:00</published><updated>2010-05-18T20:39:22.798-04:00</updated><title type='text'>Laziness and polymorphism.</title><content type='html'>This may be obvious to some but I truly didn't grok the relationship between laziness and polymorphism before I started work on LHC.&lt;br /&gt;&lt;br /&gt;The Haskell language has two very distinguishing features: Laziness and parametric polymorphism. At a glance, these two features may not seem to have that much in common. However, laziness can be seen as a form of implicit polymorphism (and it tends to be implemented as such). Consider the function with the following type signature:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;f :: Integer -&gt; Integer&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;One could say this function is polymorphic in the first argument: The argument can either be an actual Integer or it can be something that &lt;span style="font-style:italic;"&gt;evaluates&lt;/span&gt; to an Integer. When we look at laziness as a form of polymorphism, it becomes clear that eliminating polymorphism will also eliminate laziness.&lt;br /&gt;This is largely irrelevant for the average Jane Doe hacker. But if you're working on optimizations aimed at improving the time or space characteristics by eliminating "unwanted" polymorphism, it becomes important to keep laziness in mind. The hint here is for adaptive containers.&lt;br /&gt;&lt;br /&gt;Well, to make a short story even shorter: Laziness and polymorphism are different sides of the same coin. If you optimize away polymorphism, you will (perhaps inadvertently) also squash laziness.&lt;br /&gt;&lt;br /&gt;All this is obvious in retrospect but I didn't get it until it was right in front of me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-9078585081764514791?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/9078585081764514791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/laziness-and-polymorphism.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9078585081764514791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9078585081764514791'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2010/05/laziness-and-polymorphism.html' title='Laziness and polymorphism.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-973608889421611230</id><published>2009-09-04T17:16:00.005-04:00</published><updated>2009-09-04T17:36:29.609-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Yet another unfair benchmark.</title><content type='html'>A lot of things has happened in LHC over the last couple of weeks. With the inclusion of Integer and IEEE float support, LHC is finally usable enough for simple benchmarks.&lt;br /&gt;&lt;br /&gt;I've excavated the old 'nobench' benchmark and pitched four Haskell implementation up against each other. It should be noted that these benchmark numbers are even more unreliable than usual. UHC's C backend doesn't work on x84-64 and thus it compiles to bytecode. All in all, you should trust benchmarks as much as you trust politicians.&lt;br /&gt;&lt;br /&gt;The benchmark results can be found here: &lt;a href="http://darcs.haskell.org/%7Elemmih/nobench/x86_64/results.html"&gt;http://darcs.haskell.org/~lemmih/nobench/x86_64/results.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The results are updated frequently.&lt;br /&gt;&lt;br /&gt;The benchmark source can be found here: &lt;a href="http://nobench.seize.it/"&gt;http://nobench.seize.it/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-973608889421611230?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/973608889421611230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/09/yet-another-unfair-benchmark.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/973608889421611230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/973608889421611230'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/09/yet-another-unfair-benchmark.html' title='Yet another unfair benchmark.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-7301716985813186706</id><published>2009-08-15T08:19:00.002-04:00</published><updated>2009-08-15T08:36:32.674-04:00</updated><title type='text'>Status update: New Integer implementation.</title><content type='html'>We've finally gotten around to replacing our Integer type with a real bignum implementation. The bignum code was written by Isaac Dupree in wonderfully pure Haskell, and it was a snug fit for our needs. After stripping the Prelude dependency and hooking it up to the Integer interface, it worked without a hitch.&lt;br /&gt;&lt;br /&gt;Let's try it out:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;david@desktop:lhc$ cat HelloWorld.hs&lt;br /&gt;module Main where&lt;br /&gt;main = do print (2^150)&lt;br /&gt;          print (3*10^13*299792458)&lt;br /&gt;david@desktop:lhc$ ./HelloWorld&lt;br /&gt;1427247692705959881058285969449495136382746624&lt;br /&gt;8993773740000000000000&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-7301716985813186706?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/7301716985813186706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/08/status-update-new-integer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7301716985813186706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7301716985813186706'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/08/status-update-new-integer.html' title='Status update: New Integer implementation.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-1706187924862393537</id><published>2009-06-08T12:19:00.004-04:00</published><updated>2009-06-08T14:04:31.107-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='native code generator'/><title type='text'>New backend.</title><content type='html'>The new C backend has been pushed to the repository and it seems to work without a hitch. No particular effort has been directed at making it efficient (and none will since this backend is only a temporary measure). Initial testing shows it to be around 40-50 times faster than the interpreter.&lt;br /&gt;Writing this backend was surprisingly easy; low-level Grin (LHC's intermediate language) can be directly pretty-printing as C code. By far the hardest part was giving up on LLVM and settling for C.&lt;br /&gt;&lt;br /&gt;Future development will focus on grin-to-grin optimizations and a native code generator.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-1706187924862393537?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/1706187924862393537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/06/new-backend.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1706187924862393537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1706187924862393537'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/06/new-backend.html' title='New backend.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-2783880837539685229</id><published>2009-05-21T03:25:00.003-04:00</published><updated>2009-05-21T04:30:20.952-04:00</updated><title type='text'>New release: LHC 0.8</title><content type='html'>It's been about 5 months but, finally, a new release of LHC has been born and is on hackage - so you should get it now!&lt;br /&gt;&lt;br /&gt;This new release has been a lot of hard work on behalf of David especially, and we've spent the past day or two working out a lot of installation issues on my MacBook etc.. But the result is looking really nice, even if premature. There are still some bugs to work out, but for the most part all our installation issues are fixed, and development can steam ahead on more interesting stuff.&lt;br /&gt;&lt;br /&gt;Perhaps the biggest change in this release is that LHC is now a backend for GHC instead of its own codebase. Amongst other things, this pretty much means that LHC already has support for all of GHC's language extensions. Also, it shares the exact same command line options (and a few more,) so it's pretty similar to GHC on the hood.&lt;br /&gt;&lt;br /&gt;The code base is very small, but it is simple: there is no garbage collection or exceptions, threading etc.. Everything is slow right now and the heap etc. are dummy. The result already works well though, and so we're releasing it now for your pleasure.&lt;br /&gt;&lt;br /&gt;There are full installation instructions for LHC + libraries &lt;a href="http://lhc.seize.it/Front+Page#installing"&gt;HERE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-2783880837539685229?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/2783880837539685229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/05/new-release-lhc-08.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2783880837539685229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2783880837539685229'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/05/new-release-lhc-08.html' title='New release: LHC 0.8'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-2882631637200046724</id><published>2009-05-04T12:57:00.009-04:00</published><updated>2009-05-05T14:00:43.545-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Optimizations'/><title type='text'>Constructor specialization and laziness.</title><content type='html'>Edward recently publicised some experiments with constructor specialization and the state monad. You can find the sources &lt;a href="http://www.reddit.com/r/haskell/comments/8hbgu/an_adaptive_state_monad_40_faster_than_our_best/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What he did was basically to remove laziness and polymorphism from the state monad using a fancy new GHC feature called &lt;a href="http://www.haskell.org/haskellwiki/GHC/Type_families"&gt;indexed type families&lt;/a&gt;. Benchmarking the different implementation was done by calculating the Fibonacci sequence and printing the 400,000th element.&lt;br /&gt;&lt;br /&gt;There are quite a number of such adaptive data types. They range from lists to maps to monads but they all share two fundamental drawbacks: (1) All usage combinations must be explicitly enumerated, (2) laziness must be eliminated. Fortunately for LHC, using whole-program optimization solve both problems (by static analysis and unboxing at a higher granularity).&lt;br /&gt;&lt;br /&gt;I believe it's important to realise that polymorphism and laziness are two sides of the same coin. Destroy one and you are likely to inadvertently destroy the other. 'Is this a bad thing?' you might ask. Well, the short answer is "yes!". Laziness, when used correctly, is incredibly powerful. Let's have another look at the State monad benchmark.&lt;br /&gt;&lt;br /&gt;The following program implements the above mentioned benchmark. It is 10 times faster and uses 50 times less memory than the most efficient strict version.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{-# OPTIONS_GHC -O2 -XBangPatterns #-}&lt;br /&gt;import Control.Monad&lt;br /&gt;import Control.Monad.State&lt;br /&gt;&lt;br /&gt;main = print . last . fst $ fib 400000&lt;br /&gt;&lt;br /&gt;fib n = unS (fibN n) (0,1::Int)&lt;br /&gt;fibN n = replicateM' n oneFib&lt;br /&gt;oneFib = (get &gt;&gt;= \(m,n) -&gt; put (n,m+n) &gt;&gt; return m)&lt;br /&gt;&lt;br /&gt;replicateM' 0 fn = return []&lt;br /&gt;replicateM' n fn&lt;br /&gt;   = do !e ←  fn&lt;br /&gt;        r ←  replicateM' (n−1 ∷ Int) fn&lt;br /&gt;        return (e:r)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, in conclusion: Constructor specialization is an interesting technique but its full power can only be realised as an interprocedural optimization pass.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-2882631637200046724?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/2882631637200046724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/05/constructor-specialization-and-laziness.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2882631637200046724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2882631637200046724'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/05/constructor-specialization-and-laziness.html' title='Constructor specialization and laziness.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-2373178144033592746</id><published>2009-04-10T13:39:00.004-04:00</published><updated>2009-04-11T08:55:54.186-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GRIN'/><title type='text'>A new beginning.</title><content type='html'>The LHC project has finally resumed development after a few weeks of inactivity. Things have taken big steps in a new direction, however, and nearly everything except the name has changed.&lt;br /&gt;We're no longer a fork of JHC. Maintaining a complete Haskell front-end was too much of a hassle, especially considering we're only interested in optimization on the GRIN level. For this reason, LHC has reinvented itself as an alternative backend to the Glorious Glasgow Haskell Compiler.&lt;br /&gt;&lt;br /&gt;The lack of testability was a major problem in the previous version of LHC but hopefully we've learned from our mistakes. The new development efforts will be structured around a decremental reliance on a GRIN evaluator. In other words, we want to run the full testsuite between each and every significant code transformation. That no transformation should change the external behaviour of a GRIN program is a very simple invariant.&lt;br /&gt;&lt;br /&gt;The current toolchain looks as following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;david@desktop:basic$ cat Args.hs&lt;br /&gt;import System&lt;br /&gt;&lt;br /&gt;main :: IO ()&lt;br /&gt;main = do&lt;br /&gt;    as &lt;- getArgs&lt;br /&gt;    mapM_ putStrLn as&lt;br /&gt;david@desktop:basic$ ghc -fforce-recomp -O2 -fext-core -c Args.hs &lt;br /&gt;david@desktop:basic$ lhc compile Args.hcr &gt; Args.lhc&lt;br /&gt;david@desktop:basic$ ./Args.lhc One Two Three&lt;br /&gt;One&lt;br /&gt;Two&lt;br /&gt;Three&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The contents of 'Args.lhc' is unoptimized GRIN code. It is not by any means efficient or fast but it serves its purpose.&lt;br /&gt;&lt;br /&gt;Development will now focus on creating GRIN transformations that reduces the need for the RTS (our GRIN evaluator serves as the RTS).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-2373178144033592746?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/2373178144033592746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/04/new-beginning.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2373178144033592746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2373178144033592746'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/04/new-beginning.html' title='A new beginning.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-3716731184265791110</id><published>2009-04-08T10:56:00.002-04:00</published><updated>2009-04-08T11:04:01.156-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GRIN'/><title type='text'>Hello world!</title><content type='html'>After weeks of development, lhc is finally able to interpret Hello World!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;david@desktop:lhc$ cat HelloWorld.hs&lt;br /&gt;module Main where&lt;br /&gt;main = putStr "Hello world\n"&lt;br /&gt;david@desktop:lhc$ ghc -O2 -fext-core HelloWorld.hs -c&lt;br /&gt;david@desktop:lhc$ lhc build HelloWorld.hcr &gt; HelloWorld.grin&lt;br /&gt;Parsing core files...&lt;br /&gt;Tracking core dependencies...&lt;br /&gt;Translating to grin...&lt;br /&gt;Removing dead code...&lt;br /&gt;Printing grin...&lt;br /&gt;david@desktop:lhc$ wc -l HelloWorld.grin&lt;br /&gt;8054 HelloWorld.grin&lt;br /&gt;david@desktop:lhc$ lhc eval HelloWorld.hcr &lt;br /&gt;Parsing core files...&lt;br /&gt;Tracking core dependencies...&lt;br /&gt;Translating to grin...&lt;br /&gt;Removing dead code...&lt;br /&gt;Hello world&lt;br /&gt;Node (Aliased 251 "ghc-prim:GHC.Prim.(#,#)") (ConstructorNode 0) [Empty,HeapPointer 263]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Supported primitives include: indexCharOffAddr#, newPinnedByteArray#, *MutVar, *MVar.&lt;br /&gt;&lt;br /&gt;Exceptions are currently ignored and the heap is never garbage collected. However, since I'm evaluating the GRIN (as opposed to translating it to LLVM or C), adding these features should be easy as cake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-3716731184265791110?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/3716731184265791110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/04/hello-world.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3716731184265791110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3716731184265791110'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/04/hello-world.html' title='Hello world!'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-6719415247236128207</id><published>2009-03-22T13:48:00.000-04:00</published><updated>2009-03-22T13:48:00.224-04:00</updated><title type='text'>Ease of implementation.</title><content type='html'>Developing a usable compiler for a high-level language such as Haskell isn't a trivial thing to do. Any effort to trade developer time against CPU time is likely to be a wise choice. In this post I will outline a few attempts to deal with the complexity of LHC in high-level ways. Hopefully the end result won't be too slow.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Case short-circuiting.&lt;/span&gt;&lt;br /&gt;Since case expressions in GRIN do not force the evaluation of the scrutinized value, they are usually preceded by a call to 'eval'. Then, after the 'eval' calls have been inlined, case-of-case patterns like this are very common:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;do val &lt;- case x of&lt;br /&gt;            []         -&gt; unit []&lt;br /&gt;            CCons x xs -&gt; unit (CCons x xs)&lt;br /&gt;            Ffunc a    -&gt; func a&lt;br /&gt;case val of&lt;br /&gt;  []         -&gt; jumpToNilCase&lt;br /&gt;  CCons x xs -&gt; jumpToConsCase x xs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is obviously inefficient since the case for Nil and Cons will be scrutinized twice. In the GRIN paper, Boquist deals with this by implementing a case short-circuiting optimization after the GRIN code has been translated to machine code. However, dealing with optimizations on the machine code level is quite a tricky thing to do and I'd much rather implement this optimization in GRIN. By making aggressive use of small functions we can do exactly that:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;do case x of&lt;br /&gt;   []         -&gt; jumpToNilCase&lt;br /&gt;   CCons x xs -&gt; jumpToConsCase x xs&lt;br /&gt;   Ffunc a    -&gt; do val &lt;- func a; checkCase val&lt;br /&gt;&lt;br /&gt;checkCase val =&lt;br /&gt;  case val of&lt;br /&gt;    []         -&gt; jumpToNilCase&lt;br /&gt;    CCons x xs -&gt; jumpToConsCase x xs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Register allocation and tail calls.&lt;/span&gt;&lt;br /&gt;Using a fixed calling convention is not necessary for whole-program compilers like LHC. Instead, we choose to create a new calling method for each procedure (this is easier than it sounds).&lt;br /&gt;This has the obvious consequence of requiring the convention for return values to be identical for procedures that invoke each other with tail-calls. This was deemed an unacceptable restriction in the GRIN paper, and all tail-calls were subsequently removed before register allocation took place. Afterwards, another optimization step reintroduced tail-calls where possible.&lt;br /&gt;I believe this is too much trouble for too little gain. The possible performance hit is out-weighed by the ease of implementation and the guarantee of tail-calls.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Simple node layout.&lt;/span&gt;&lt;br /&gt;An unevaluated value is represented simply by a function name (or tag) and a fixed number of arguments. This value is then overwritten once it has been evaluated. However, the new value may be bigger than what was allocated to represent the unevaluated function.&lt;br /&gt;One way to deal with this is to have two different node layouts: a fixed size node for small values, and a variable size node for big values. This is the approach taken in the GRIN paper and it understandably adds quite a bit of complexity.&lt;br /&gt;Another method is to use indirections. This trades smaller average node size and ease of implementation against more heap allocations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-6719415247236128207?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/6719415247236128207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/03/ease-of-implementation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/6719415247236128207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/6719415247236128207'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/03/ease-of-implementation.html' title='Ease of implementation.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-7434231044024426374</id><published>2009-02-05T14:00:00.000-05:00</published><updated>2009-02-05T15:38:38.247-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GRIN'/><title type='text'>Grin a little.</title><content type='html'>It has come to my attention that we are not using GRIN to it fullest. More specifically, it seems that the 'eval' and 'update' operations are handled by the RTS. This has unfortunate consequences for both the optimizer and the backend code.&lt;br /&gt;Without an explicit control-flow graph (given by inlining eval/apply), many of our more important transformations cannot be performed. Even worse than the lost optimization opportunities is the increased complexity of the RTS. Dealing with issues of correctness is an annoying distraction from the more enjoyable endeavour of applying optimizations.&lt;br /&gt;&lt;br /&gt;Moving away from the magical implementation of 'update' means we have to starting thinking about our memory model. The GRIN paper suggests using a fixed node size with a tail pointer for additional space if necessary. With this scheme we can update common-case nodes without allocating more heap space. However, since we're most likely to encounter complications with respect to concurrency and certain forms of garbage collection, I think a simpler approach is more apt.&lt;br /&gt;Replacing nodes with indirections is very easy to implement, it doesn't clash with any optimizations (the original GRIN approach interfere with fetch movement), and it opens the door for advanced features such as concurrency.&lt;br /&gt;&lt;br /&gt;So this is what I'll be working on in the near future. All magic has to be purged from the kingdom so logic and reason can reign supreme.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-7434231044024426374?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/7434231044024426374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/02/grin-little.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7434231044024426374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7434231044024426374'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/02/grin-little.html' title='Grin a little.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-9151053563174187454</id><published>2009-01-27T00:34:00.005-05:00</published><updated>2009-01-27T15:57:51.165-05:00</updated><title type='text'>Release notes.</title><content type='html'>Version 0.6.20090126 has been released. It has been more than a month since our last release and we've made a lot of progress. The code is available from Hackage and can be installed as such:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cabal install lhc -fwith-base&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's our changelog:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fixed type classes.&lt;/li&gt;&lt;li&gt;Better variable ids.&lt;/li&gt;&lt;li&gt;Base library reorganization.&lt;/li&gt;&lt;li&gt;Better support for non-Linux systems.&lt;/li&gt;&lt;li&gt;Removed tagging on Int and Word.&lt;/li&gt;&lt;li&gt;Got Control.Arrow and Control.Applicative working by improving the handling of (-&gt;) as well as fixing type classes.&lt;/li&gt;&lt;li&gt;More extensive testsuite.&lt;/li&gt;&lt;li&gt;Lots of code clean-up.&lt;/li&gt;&lt;/ul&gt;Future effort will be directed at adding Integer support in the base library, improving the efficiency of LHC and restoring control-flow analysis.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;  The LHC Team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-9151053563174187454?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/9151053563174187454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/release-notes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9151053563174187454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9151053563174187454'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/release-notes.html' title='Release notes.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-3785074818898936121</id><published>2009-01-25T03:08:00.005-05:00</published><updated>2009-01-27T12:46:50.505-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='native code generator'/><title type='text'>Thoughts on a new code generator</title><content type='html'>&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.76.3796"&gt;Code selection through object code optimization&lt;/a&gt; by Davidson and Fraser describes a compiler architecture where instead of taking an AST and optimizing it, then generating code for a target machine, we instead take the AST and immediately generate &lt;span style="font-style: italic;"&gt;worst-case &lt;/span&gt;instructions which we then subsequently optimize, and then emit into assembly language. These instructions we generate and optimize are called &lt;span style="font-style: italic;"&gt;register-transfer lists&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; or RTLs.&lt;br /&gt;&lt;br /&gt;RTLs are quite simple - a solitary RTL is just a single abstract machine instruction. A sequence of RTLs might look like so:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;t[1] := reg[12]&lt;br /&gt;t[2] := mem[8] * reg[0]&lt;br /&gt;t[3] := t[1] + reg[3]&lt;br /&gt;t[4] := t[2] * 10&lt;/code&gt;&lt;/pre&gt;An RTL must specify a simple property - &lt;span style="font-style: italic;"&gt;the machine invariant&lt;/span&gt;, which states that any RTL maps to a single instruction on the target machine.&lt;br /&gt;&lt;br /&gt;The compilation process is like so, the input language (for example, C--, GRIN or any AST for that matter) is taken and fed to the &lt;span style="font-style: italic;"&gt;code expander&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; which takes the input AST and generates a simple sequence of RTLs representing the AST - no attention at this point is paid to the generated code, and this keeps the code expander's job simple and easy. The code expander, however is a machine-dependent part of the backend - it requires knowledge of the target machine so that it may establish the machine invariant.&lt;br /&gt;&lt;br /&gt;After expansion, the code is subsequently optimized using e.g peephole optimization, constant subexpression elimination and dead code elimination. These optimizer parts are machine independent. Every optimization must make sure it does not violate the machine invariant.&lt;br /&gt;&lt;br /&gt;After optimization, we perform the task of code emission, it being the only other machine-dependent part of the compiler.&lt;br /&gt;&lt;br /&gt;In application to LHC, it is quite obvious a new backend is necessary. I believe this compilation method is applicable and preferable. Combined with whole program analysis, and my plans for a small and simple as possible runtime, this makes the compiler easier to retarget, and I wish for LHC to be a cross-compiler as well. It's obvious C is not the way to go, so minimizing burden on retargeting seems like a good strategy. My inevitable plans are for you to be able to take a haskell application, use LHC to compile it and get nice ASM code for whatever architecture you wish.&lt;br /&gt;&lt;br /&gt;The overall structure of the new backend I am thinking of is something like this (drawn very badly using &lt;a href="http://draw.labs.autodesk.com/ADDraw/draw.html"&gt;Project Draw&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;object type="image/svg+xml" data="http://thoughtpolice.stringsandints.com/code/haskell/lhc/new-backend.svg" width="400" height="600"&gt;&lt;br /&gt;&lt;img src="http://thoughtpolice.stringsandints.com/code/haskell/lhc/new-backend.svg" /&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;We will perform as many optimizations as possible on the whole-program while it is in GRIN form, leaving the backend to do the task of peephole optimization/DCE/etc. in a machine-independent way, and then emit assembly code.&lt;br /&gt;&lt;br /&gt;On the note of the implementing an optimization engine for which to perform these operations, the approach described in &lt;a href="http://www.cs.tufts.edu/%7Enr/pubs/zipcfg-abstract.html"&gt;An Applicative Control-flow Graph based on Huet's Zipper&lt;/a&gt; seems promising as well. Garbage collection as well needs definite addressing before we can get LHC to compile truly serious programs; this will take a little more time to think and talk about with David. Eventually, we may even look into using &lt;a href="http://www.eecs.harvard.edu/dias/dissertation/dissertation.pdf"&gt;Joao Dias' thesis research&lt;/a&gt; to automatically generate compiler backends, like I believe GHC HQ wants to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-3785074818898936121?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/3785074818898936121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/thoughts-on-new-code-generator.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3785074818898936121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3785074818898936121'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/thoughts-on-new-code-generator.html' title='Thoughts on a new code generator'/><author><name>Austin Seipp</name><uri>http://www.blogger.com/profile/08003235138924772402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-8290535780522520358</id><published>2009-01-22T10:57:00.006-05:00</published><updated>2009-01-22T17:14:48.901-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='typeclasses'/><title type='text'>Typeclasses are working, now we're missing a bunch of instances...</title><content type='html'>Well, I finally figured out why the only two test cases that were working were HelloWorld and Kleisli. The compiler had been implicitly generating a lot of hard-wired instances for Int,Word,CInt, and all their numerous cousins -- but it was generating the methods too late (during conversion from HsSyn language to the E intermediate language) for the methods to be properly associated with their classes (which FrontEnd.Class does before typechecking even properly begins). Since none of us much liked the idea of having all this hardwired into the compiler, we decided that rather than try to adjust the machinery to work with the new handling of methods, we'd rather implement the instances in the library. So, that is what we have to do for every type in the following list:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lhc.Prim.Int&lt;/li&gt;&lt;li&gt;Lhc.Basics.Integer&lt;/li&gt;&lt;li&gt;Data.Int.Int8&lt;/li&gt;&lt;li&gt;Data.Int.Int16&lt;/li&gt;&lt;li&gt;Data.Int.Int32&lt;/li&gt;&lt;li&gt;Data.Int.Int64&lt;/li&gt;&lt;li&gt;Data.Int.IntMax&lt;/li&gt;&lt;li&gt;Data.Int.IntPtr&lt;/li&gt;&lt;li&gt;Data.Word.Word&lt;/li&gt;&lt;li&gt;Data.Word.Word8&lt;/li&gt;&lt;li&gt;Data.Word.Word16&lt;/li&gt;&lt;li&gt;Data.Word.Word32&lt;/li&gt;&lt;li&gt;Data.Word.Word64&lt;/li&gt;&lt;li&gt;Data.Word.WordMax&lt;/li&gt;&lt;li&gt;Data.Word.WordPtr&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CChar&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CShort&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CInt&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CUInt&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CSize&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CWchar&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CWint&lt;/li&gt;&lt;li&gt;Foreign.C.Types.CTime&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So bear with us if this takes a while to iron out. We have managed to get mini-base to build and many of the tests to run now, though getArgs apparantly doesn't compile yet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-8290535780522520358?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/8290535780522520358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/typeclasses-are-working-now-were.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/8290535780522520358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/8290535780522520358'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/typeclasses-are-working-now-were.html' title='Typeclasses are working, now we&apos;re missing a bunch of instances...'/><author><name>SamB</name><uri>http://www.blogger.com/profile/06560268240719951351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.gravatar.com/avatar.php?gravatar_id=165e55c78689e561c554c3dec671fb50'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-3415146530645707018</id><published>2009-01-19T23:00:00.003-05:00</published><updated>2009-01-20T01:30:42.082-05:00</updated><title type='text'>Functions in Haskell.</title><content type='html'>Function calls in Haskell are typically far more numerous than in more traditional languages. This is in part due to laziness. Being lazy means that functions in Haskell do as little as possible to return a result. So to get all the data you need, you often have to call the functions multiple times.&lt;br /&gt;&lt;br /&gt;Consider the following snippet of code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;upto :: Int -&gt; Int -&gt; [Int]&lt;br /&gt;upto from to&lt;br /&gt;  = if from &gt; to&lt;br /&gt;    then []&lt;br /&gt;    else from : upto (from+1) to&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's what the compiled function would look like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-- Arguments and results are (usually) kept in registers.&lt;br /&gt;-- We generate a new calling convention for each function.&lt;br /&gt;upto from to&lt;br /&gt;  = case from `gtInt` to of&lt;br /&gt;     1 -&gt; do -- Return a single tag representing '[]'.&lt;br /&gt;             return [CNil]&lt;br /&gt;     0 -&gt; do -- Allocate 5 heap cells.&lt;br /&gt;             heap &lt;- allocate 5&lt;br /&gt;             -- CInt is the constructor for Int.&lt;br /&gt;             heap[0] := CInt&lt;br /&gt;             heap[1] := from&lt;br /&gt;             -- Fupto represents a suspended call to 'upto'.&lt;br /&gt;             heap[2] := Fupto&lt;br /&gt;             heap[3] := from+1&lt;br /&gt;             heap[4] := to&lt;br /&gt;             -- Return a node as three separate pieces.&lt;br /&gt;             -- &amp;amp;heap[0] is the head of the list and &amp;amp;heap[2] is the tail.&lt;br /&gt;             return [CCons, &amp;amp;heap[0], &amp;amp;heap[2]]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As we can see, calling this function will only give us a single node (the node in this case is either a CNil or a CCons with two arguments). We will have to call it again to get more information out of it. For example, fully computing 'upto 1 10' requires 11 calls to 'upto' (10 CCons nodes and 1 CNil).&lt;br /&gt;&lt;br /&gt;Looking at the steps in 'upto' shows us that it isn't doing a whole lot. All variables (even arguments and results) are in registers and the data can easily fit in the cache. We could almost say that calling this function is as fast as looping in C. Let's add a bit more code and see what happens:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;main = showMyList (upto 1 10)&lt;br /&gt;showMyList [] = return ()&lt;br /&gt;showMyList (x:xs)&lt;br /&gt;  = do print x&lt;br /&gt;       showMyList xs&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The same code, now compiled to our intermediate language:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;main = do heap &lt;- allocate 3&lt;br /&gt;          heap[0] := Fupto&lt;br /&gt;          heap[1] := 1&lt;br /&gt;          heap[2] := 10&lt;br /&gt;          showMyList &amp;amp;heap[0]&lt;br /&gt;&lt;br /&gt;showMyList lst&lt;br /&gt;  = do -- Read the arguments to 'upto' from the 'lst' pointer.&lt;br /&gt;       Fupto from to &lt;- fetch lst&lt;br /&gt;       -- Call 'upto'. The results are kept in registers.&lt;br /&gt;       -- 'a' and 'b' are undefined if 't' is CNil.&lt;br /&gt;       [t, a, b] &lt;- upto from to&lt;br /&gt;       -- Inspect the node tag.&lt;br /&gt;       case t of&lt;br /&gt;         CNil -&gt; return [CUnit]&lt;br /&gt;         CCons -&gt; do -- Call print on 'a'. This call might invoke the garbage collector.&lt;br /&gt;                     print a&lt;br /&gt;                     -- Recurse on the tail.&lt;br /&gt;                     showMyList b&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This looks rather well. We could be proud if this was the end. However, there is one thing that we haven't considered: garbage collection. The garbage collector may run when we call 'print' and if it does then the pointer we have in 'b' will no longer be valid.&lt;br /&gt;A common solution is to push 'b' to a stack (which the GC can walk and modify) and reload it after 'print' has returned. However, a stack allocation cost about as much as the call to 'upto' and hence incurs an overhead of nearly 50%.&lt;br /&gt;&lt;br /&gt;Fortunately there's a way around this. We can "simply" have the garbage collector update all registers that contain heap pointers. Doing so isn't exactly easy but it does allow us to keep pointers in registers and to avoid all unnecessary stack allocations.&lt;br /&gt;The details of how to accomplish this will have to wait for another time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-3415146530645707018?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/3415146530645707018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/functions-in-haskell.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3415146530645707018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3415146530645707018'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/functions-in-haskell.html' title='Functions in Haskell.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-3078964744414936591</id><published>2009-01-17T18:11:00.003-05:00</published><updated>2009-01-17T19:10:55.776-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LLVM'/><title type='text'>LLVM is great.</title><content type='html'>It seems that the LLVM crowd have mistaken my blog posts for criticism of LLVM. Let me make it clear that I have nothing but respect for LLVM.&lt;br /&gt;&lt;br /&gt;I've previously mentioned that LLVM doesn't support zero-overhead garbage collection. Big deal. It's about the same as saying LLVM doesn't answer whether P=NP. I apparently failed in conveying that this is an unsolved problem in computer science.&lt;br /&gt;&lt;br /&gt;Solving this problem isn't as simple as putting heap pointers in registers (although it is required). The real beef lies in determining which registers are heap pointers when it isn't known statically. Determining at run-time which registers are heap pointers is intimately tied to the data model of the high-level language. Doing this well in an agnostic way is an unsolved problem. (Note that pointer tagging is generally avoided).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Several people apparently took it personally when I mentioned writing yet another NCG. Let it be clear that I'd never rewrite any of LLVM nor wish to belittle the effort it takes to write a general compiler. I was merely talking about writing a non-optimizing translator from an extremely limited IR to machine code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;LLVM is great. I do not wish to criticise any part of it.&lt;/li&gt;&lt;li&gt;What you guys have created is impressive. I do not wish to belittle your efforts.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;LLVM is not a silver bullet. It does not solve all open questions in the academic world and no one expects it to.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-3078964744414936591?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/3078964744414936591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/llvm-is-great.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3078964744414936591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/3078964744414936591'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/llvm-is-great.html' title='LLVM is great.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-7146437814528545786</id><published>2009-01-17T11:52:00.004-05:00</published><updated>2009-01-17T17:38:19.020-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LLVM'/><category scheme='http://www.blogger.com/atom/ns#' term='garbage collection'/><title type='text'>Why LLVM probably won't replace C--.</title><content type='html'>It seems that I didn't do a good job at explaining why LHC won't be using LLVM. In this post I will elaborate on why some people think C-- has more promise than LLVM as a substrate for lazy, functional languages.&lt;br /&gt;&lt;br /&gt;Let me start by making one thing clear: LLVM &lt;span style="font-style: italic;"&gt;does&lt;/span&gt; have support for garbage collectors. I am not disputing that. However, as Henderson has shown, so does C and every other language. The question we have to ask is not "Does this environment support garbage collection?" but rather "How efficiently does this environment support garbage collection?".&lt;br /&gt;&lt;br /&gt;To recap, Henderson's technique involves placing root pointers (the set of pointers which can be followed to find all live data) on a shadow stack. Since we manage this stack ourself, it shouldn't be a problem for the GC to walk it.&lt;br /&gt;In short, each heap allocation incurs an unnecessary stack allocation and heap pointers are never stored in registers for long.&lt;br /&gt;&lt;br /&gt;Now what does this mean for languages like Haskell? Well, unlike programs written in more traditional languages, a Haskell application might very well do between 10 and 20 million heap allocations per second.&lt;br /&gt;Writing Haskell programs is more about producing the correct data stream than it is about performing the right side-effects. It's common for functions in Haskell to manipulate data without execuing any side-effects. (Think spreadsheets.)&lt;br /&gt;This way of computing obviously requires a very cheap method of allocation. Performing 10 million unnecessary stack allocations per second would severely hurt performance, and not having heap pointers in registers could easily be equally devastating.&lt;br /&gt;&lt;br /&gt;So what about LLVM? Shouldn't the built-in GC support in LLVM be more efficient than any cheap hack? Well, it turns out it isn't. The conflict between garbage collection and optimizations haven't changed, and neither have the solution: disabling or bypassing optimizations. This in turn means unnecessary stack allocations and sub-optimal use of registers.&lt;br /&gt;&lt;br /&gt;That LLVM haven't solved the problem of zero-overhead garbage collection isn't too surprising. Solving this while staying agnostic of the data model is an open question in computer science.&lt;br /&gt;It is here C-- differs from LLVM. C-- is a research project that aims at solving difficult problems such as supporting efficient GCs and cheap concurrency. LLVM, on the other hand, is an engineering project.&lt;br /&gt;&lt;br /&gt;In conclusion: garbage collection in LLVM incurs unacceptable overhead, and while C-- and LLVM do have some overlap, the problems they're trying to solve are quite different.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-7146437814528545786?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/7146437814528545786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/why-llvm-probably-wont-replace-c.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7146437814528545786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7146437814528545786'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/why-llvm-probably-wont-replace-c.html' title='Why LLVM probably won&apos;t replace C--.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-7606834439986025100</id><published>2009-01-15T20:07:00.005-05:00</published><updated>2009-01-16T18:16:11.425-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='native code generator'/><category scheme='http://www.blogger.com/atom/ns#' term='LLVM'/><category scheme='http://www.blogger.com/atom/ns#' term='garbage collection'/><title type='text'>The case against C/LLVM.</title><content type='html'>Many people have pointed out that garbage collection can be implemented in a portable fashion in uncooperative environments such as C or LLVM. Specific details of how to do this can be found in Fergus Henderson's paper &lt;span style="font-size:100%;"&gt;"&lt;/span&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.5570"&gt;&lt;span style="font-size:100%;"&gt;Accurate garbage collection in an uncooperative environment&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:100%;"&gt;"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Henderson's technique is simply to put each pointer to newly allocated data on the stack. This bypasses all concerns about which variables will be put in registers and which will be spilled to the stack. However, the overhead of never using registers and performing unnecessary stack allocations can be quite significant.&lt;br /&gt;&lt;br /&gt;Since the goal of LHC is to generate efficient executables, shoehorning our executive model into a "hostile" environment like C or LLVM isn't an option. Writing a simplistic NCG won't be too much trouble, hopefully.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-7606834439986025100?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/7606834439986025100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/case-against-cllvm.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7606834439986025100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7606834439986025100'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/case-against-cllvm.html' title='The case against C/LLVM.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-7036541577332231556</id><published>2009-01-14T19:04:00.000-05:00</published><updated>2009-01-14T19:18:52.557-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='typeclasses'/><title type='text'>Typeclass Blues</title><content type='html'>Well, I've been having some trouble with the typeclass implementation. I got rid of the long-standing bug where ill-typed rules were generated in &lt;tt&gt;E.FromHs&lt;/tt&gt;, and I've gotten &lt;tt&gt;FrontEnd.Class&lt;/tt&gt; to generate rules for method implementations which appear in instance declarations, but I haven't figured out how to implicitly fall back to the default implementation. The one approach I actually tried was to generate method implementations like:&lt;br /&gt;&lt;pre&gt;Lhc.Order./= = Instance@.iLhc.Order./=.default&lt;/pre&gt;which would quickly be rewritten to:&lt;br /&gt;&lt;pre&gt;Instance@.iLhc.Order./=.Lhc.IO.IOError = Instance@.iLhc.Order./=.default&lt;/pre&gt;but unfortunately, the typechecker stated that &lt;tt&gt;Instance@.iLhc.Order./=.default&lt;/tt&gt; was not in the type-checking environment, and I couldn't figure out why :-(.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-7036541577332231556?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/7036541577332231556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/typeclass-blues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7036541577332231556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/7036541577332231556'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/typeclass-blues.html' title='Typeclass Blues'/><author><name>SamB</name><uri>http://www.blogger.com/profile/06560268240719951351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.gravatar.com/avatar.php?gravatar_id=165e55c78689e561c554c3dec671fb50'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-9011581151403765747</id><published>2009-01-14T10:24:00.000-05:00</published><updated>2009-01-14T19:29:25.900-05:00</updated><title type='text'>Resources.</title><content type='html'>You can follow the LHC development using these resources:&lt;br /&gt;&lt;br /&gt;Mailing list: &lt;a href="http://projects.haskell.org/cgi-bin/mailman/listinfo/lhc"&gt;http://projects.haskell.org/cgi-bin/mailman/listinfo/lhc&lt;/a&gt;&lt;br /&gt;Wiki: &lt;a href="http://lhc.seize.it/"&gt;http://lhc.seize.it/&lt;br /&gt;&lt;/a&gt;Bug tracker: &lt;a href="http://trac.haskell.org/lhc/report/1"&gt;http://trac.haskell.org/lhc/report/1&lt;/a&gt;&lt;br /&gt;IRC channel: irc.freenode.net#lhc-compiler&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-9011581151403765747?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/9011581151403765747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/resources.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9011581151403765747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/9011581151403765747'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/resources.html' title='Resources.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-1999690163220590545</id><published>2009-01-14T07:58:00.000-05:00</published><updated>2009-01-14T19:29:47.594-05:00</updated><title type='text'>What is LHC?</title><content type='html'>It might be difficult to get a sense of how feature-complete LHC is just by looking at the wiki and the mailing list. In this post I will try to answer the common questions of what LHC supports and where LHC is going.&lt;br /&gt;&lt;br /&gt;Let me start by introducing LHC itself. The LHC Haskell Compiler (LHC for short) was born out of &lt;a href="http://repetae.net/computer/jhc/"&gt;JHC&lt;/a&gt; on a cold Tuesday morning, November 18th, 2008. Her birth was necessitated by a conflict of opinion between John Meacham (the author of JHC) and myself. We simply couldn't agree on which build system would be the most appropriate: make or cabal. Since then we've made many changes that are unlikely to be merged back into JHC.&lt;br /&gt;&lt;br /&gt;As of this writing, LHC differs from JHC in the following ways:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cabalized build system instead of Make.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Extensive use of Haskell libraries. We have six more dependencies than JHC.&lt;/li&gt;&lt;li&gt;We use 'derive' instead of the unwieldy 'DrIFT' package. This, among other things, makes it possible to generate HPC information.&lt;/li&gt;&lt;li&gt;We support both GHC-6.8.x and GHC-6.10.x.&lt;/li&gt;&lt;li&gt;We're available on Hackage.&lt;/li&gt;&lt;li&gt;We've eliminated some usage of unsafe IO. On a project of this magnitude, getting segfaults instead of type-errors isn't acceptable.&lt;/li&gt;&lt;li&gt;We're very liberal in granting commit access. It's easier to undo bad patches than to make people contribute.&lt;/li&gt;&lt;/ul&gt;Although we are not JHC, we are still similar enough to share many of the same disorders. Most importantly, we don't have support for exceptions, garbage collection or proper type-classes.&lt;br /&gt;&lt;br /&gt;The issues with type-classes is purely due to bugs in our code, and hopefully we can resolve them without too much headache. It should be noted that since Monad is a type-class, there are very few programs that LHC can compile at this stage.&lt;br /&gt;&lt;br /&gt;Exceptions and garbage collection are more fundamental problems, though. We simply cannot implement those feature efficiently in C. Using C-- is an obvious solution but unfortunately there are no usable C-- compilers. Using LLVM[1] is out of the question for the same reasons as C. We will probably end up writing our own native code generator.&lt;br /&gt;&lt;br /&gt;All in all, our future plans are like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Disable features until we can correctly compile Haskell98 programs.&lt;/li&gt;&lt;li&gt;Extend our testsuite to cover most of the codebase.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Address performance issues. We are about 5-10 times slower than GHC and there are no fundamental reasons for this.&lt;/li&gt;&lt;li&gt;Write a code generator that supports exceptions and garbage collection.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;[1]: On the surface it looks like LLVM has decent support for exceptions and garbage collecting. However, the documentation shows that it is essentially no better than in C.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-1999690163220590545?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/1999690163220590545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/what-is-lhc.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1999690163220590545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/1999690163220590545'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/what-is-lhc.html' title='What is LHC?'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1862878851303132605.post-2367095099300054125</id><published>2009-01-12T15:32:00.000-05:00</published><updated>2009-01-12T19:35:24.779-05:00</updated><title type='text'>The mess with variable ids.</title><content type='html'>Variable identification tags can contain four different types of information. In Haskell we would write it as such:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data Id = Empty            -- Unused binding. Eg: '\ _ -&gt; ...'.&lt;br /&gt;        | Etherial Int     -- Internal variable. Only used when type-checking.&lt;br /&gt;        | Anonymous Int    -- Anonymous variable created by the compiler.&lt;br /&gt;        | Named Name       -- Named variable created by the user.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, in LHC this data structure was unrolled and packed into an Int. The encoding went as following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Empty        = zero&lt;br /&gt;  Etherial     = negative numbers&lt;br /&gt;  Anonymous    = even, positive numbers&lt;br /&gt;  Named        = odd, positive numbers, used as keys in a global hash table.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This encoding gives us very fast operations on Sets and Maps but it also punishes mistakes with a vengeance. The increased performance is definitely not worth it and we've been working on untangling the Ids from day-1.&lt;br /&gt;&lt;br /&gt;As of today, I'm glad to say that we've finally restored the beautiful ADT and we can now hack without fear of segfaulting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1862878851303132605-2367095099300054125?l=lhc-compiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lhc-compiler.blogspot.com/feeds/2367095099300054125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/mess-with-variable-ids.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2367095099300054125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1862878851303132605/posts/default/2367095099300054125'/><link rel='alternate' type='text/html' href='http://lhc-compiler.blogspot.com/2009/01/mess-with-variable-ids.html' title='The mess with variable ids.'/><author><name>David Himmelstrup</name><uri>http://www.blogger.com/profile/12982136700651117492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
