Stealing ideas from the latest GCC release

Hi all, While looking at the GCC 4.7 [1] release notes I saw something that's perhaps worth stealing. Taken from the release notes: The inter-procedural constant propagation pass has been rewritten. It now performs generic function specialization. For example when compiling the following: void foo(bool flag) { if (flag) ... do something ... else ... do something else ... } void bar (void) { foo (false); foo (true); foo (false); foo (true); foo (false); foo (true); } GCC will now produce two copies of foo. One with flag being true, while other with flag being false. This leads to performance improvements previously possibly only by inlining all calls. Cloning causes a lot less code size growth. I found myself wanting something like this just today. A common pattern I see in code is this: data Options = Options { ... } defaultOptions :: Options defaultOptions = ... foo :: ... foo = fooWith defaultOptions fooWith :: Options -> ... fooWith = ... It'd be nice if we could get foo to specialize on its input arguments, without having to mark all of fooWith as INLINE. 1. http://gcc.gnu.org/gcc-4.7/changes.html -- Johan

On Thu, Mar 22, 2012 at 5:09 PM, Johan Tibell
Hi all,
While looking at the GCC 4.7 [1] release notes I saw something that's perhaps worth stealing. Taken from the release notes:
The inter-procedural constant propagation pass has been rewritten. It now performs generic function specialization. For example when compiling the following:
void foo(bool flag) { if (flag) ... do something ... else ... do something else ... } void bar (void) { foo (false); foo (true); foo (false); foo (true); foo (false); foo (true); }
GCC will now produce two copies of foo. One with flag being true, while other with flag being false. This leads to performance improvements previously possibly only by inlining all calls. Cloning causes a lot less code size growth.
Wait, I thought this is essentially what constructor specialization does? I suppose we might then keep around the old body. Or will these behave differently in the presence of, say, different constant Int arguments? -Jan-Willem Maessen

On Thu, Mar 22, 2012 at 3:52 PM, Jan-Willem Maessen
Wait, I thought this is essentially what constructor specialization does? I suppose we might then keep around the old body. Or will these behave differently in the presence of, say, different constant Int arguments?
We do want to keep around the old body (but constructor specialization already does that.) We also want to be able to specialize things like 5 :: Int, which I don't think constructor specialization handles. -- Johan

I support a form of this in jhc by allowing specialization of values, not just types. It is actually the same mechanism as type specialization since that is just value specialization where the value being specialized on is the type parameter. foo :: Bool -> Int {-# SPECIALIZE foo True :: Int #-} (I think this is the current syntax, I changed it a couple times in jhc's history) will create a foo_True :: Int foo_True = inline foo True and a {-# RULE foo True = foo_True #-} John

Good for JHC! Indeed; see http://hackage.haskell.org/trac/ghc/ticket/5059 There are two big questions: * When to specialise (a supercompiler specialises on everything) * How to make sure that the arguments are not inlined too early (see the ticket) Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell- | users-bounces@haskell.org] On Behalf Of John Meacham | Sent: 22 March 2012 23:16 | To: Johan Tibell | Cc: glasgow-haskell-users | Subject: Re: Stealing ideas from the latest GCC release | | I support a form of this in jhc by allowing specialization of values, not | just types. | It is actually the same mechanism as type specialization since that is just | value specialization where the value being specialized on is the type | parameter. | | foo :: Bool -> Int | | {-# SPECIALIZE foo True :: Int #-} | (I think this is the current syntax, I changed it a couple times in jhc's | history) | | will create a | | foo_True :: Int | foo_True = inline foo True | | and a | | {-# RULE foo True = foo_True #-} | | John | | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

On 3/22/12 5:09 PM, Johan Tibell wrote:
It'd be nice if we could get foo to specialize on its input arguments, without having to mark all of fooWith as INLINE.
+1 million. I don't recall how many times I've wanted this optimization, even if it has to be specified manually. Unfortunately, I recognize the difficulties inherent in the problem of getting it to work as desired. -- Live well, ~wren
participants (5)
-
Jan-Willem Maessen
-
Johan Tibell
-
John Meacham
-
Simon Peyton-Jones
-
wren ng thornton