RE: Why isn't ($) inlining when I want?
I remember doing some work on the “floating of constant lists” question. First, [1..n] turns into (enumFromTo 1 n), and if enumFromTo was expensive, then sharing it might be a good plan. So GHC would have to know that it was cheap. I did experiment with “cheapBuild” see https://ghc.haskell.org/trac/ghc/ticket/7206, but as you’ll see there, the results were equivocal. By duplicating the [1..n] we were allocating two copies of (I# 4), (I# 5) etc, and that increased allocation and GC time. So it’s unclear, in general, whether in these examples it is better to share the [1..n] between all calls of ‘loop’, or to duplicate it. All that said, Dan’s question of why X fuses and very-similar Y doesn’t was a surprise to me; I’ll look into that. Simon From: John Lato [mailto:jwl...@gmail.com] Sent: 28 August 2014 00:17 To: Dan Doel Cc: Simon Peyton Jones; David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? I sometimes think the solution is to make let-floating apply in fewer cases. I'm not sure we ever want to float out intermediate lists, the cost of creating them is very small relative to the memory consumption if they do happen to get shared. My approach is typically to mark loop INLINE. This very often results in the code I want (with vector, which I use more than lists), but it is a big hammer to apply. John On Thu, Aug 28, 2014 at 5:56 AM, Dan Doel dan.d...@gmail.commailto:dan.d...@gmail.com wrote: I think talking about inlining of $ may not be addressing the crux of the problem here. The issue seems to be about functions like the one in the first message. For instance: loop :: (Int - Int) - Int loop g = sum . map g $ [1..100] Suppose for argument that we have a fusion framework that would handle this. The problem is that this does not actually turn into a loop over integers, because the constant [1..100] gets floated out. It instead builds a list/vector/whatever. By contrast, if we write: loop' :: Int loop' = sum . map (+1) $ [1..100] this does turn into a loop over integers, with no intermediate list. Presumably this is due to there being no work to be saved ever by floating the list out. These are the examples people usually test fusion with. And if loop is small enough to inline, it turns out that the actual code that gets run will be the same as loop', because everything will get inlined and fused. But it is also possible to make loop big enough to not inline, and then the floating will pessimize the overall code. So the core issue is that constant floating blocks some fusion opportunities. It is trying to save the work of building the structure more than once, but fusion can cause the structure to not be built at all. And the floating happens before fusion can reasonably be expected to work. Can anything be done about this? I've verified that this kind of situation also affects vector. And it seems to be an issue even if loop is written: loop g = sum (map g [1..100]) -- Dan On Wed, Aug 27, 2014 at 3:38 PM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: You'll have to do more detective work! In your dump I see Inactive unfolding $. So that's why it's not being inlined. That message comes from CoreUnfold, line 941 or so. The Boolean active_unfolding is passed in to callSiteInline from Simplify, line 1408 or so. It is generated by the function activeUnfolding, defined in SimplUtils. But you have probably change the CompilerPhase data type, so I can't guess what is happening. But if you just follow it through I'm sure you'll find it. Simon | -Original Message- | From: David Feuer [mailto:david.fe...@gmail.commailto:david.fe...@gmail.com] | Sent: 27 August 2014 17:22 | To: Simon Peyton Jones | Cc: ghc-devs | Subject: Re: Why isn't ($) inlining when I want? | | I just ran that (results attached), and as far as I can tell, it | doesn't even *consider* inlining ($) until phase 2. | | On Wed, Aug 27, 2014 at 4:03 AM, Simon Peyton Jones | simo...@microsoft.commailto:simo...@microsoft.com wrote: | It's hard to tell since you are using a modified compiler. Try running | with -ddump-occur-anal -dverbose-core2core -ddump-inlinings. That will | show you every inlining, whether failed or successful. You can see the | attempt to inline ($) and there is some info with the output that may | help to explain why it did or did not work. | | Try that | | Simon | | | -Original Message- | | From: ghc-devs [mailto:ghc-devs-boun...@haskell.orgmailto:ghc-devs-boun...@haskell.org] On Behalf Of | David | | Feuer | | Sent: 27 August 2014 04:50 | | To: ghc-devs; Carter Schonwald | | Subject: Why isn't ($) inlining when I want? | | | | tl;dr I added a simplifier run with inlining enabled between | | specialization and floating out. It seems incapable of inlining | | saturated applications of ($), and I can't figure out why. These are | | inlined later, when
RE: Why isn't ($) inlining when I want?
Oh, now I understand. In loop g = sum . map g $ [1..100] GHC can share [1..10] across all calls to loop, although that nixes fusion. Because each call of loop may have a different g. But in loop' = sum . map (+1) $ [1..100] GHC can share (sum . map (+1) $ [1..1000]) across all calls to loop’, so it can readily fuse the sum, map, and [1..n]. I hope that explains it. Simon From: Dan Doel [mailto:dan.d...@gmail.com] Sent: 27 August 2014 22:57 To: Simon Peyton Jones Cc: David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? I think talking about inlining of $ may not be addressing the crux of the problem here. The issue seems to be about functions like the one in the first message. For instance: loop :: (Int - Int) - Int loop g = sum . map g $ [1..100] Suppose for argument that we have a fusion framework that would handle this. The problem is that this does not actually turn into a loop over integers, because the constant [1..100] gets floated out. It instead builds a list/vector/whatever. By contrast, if we write: loop' :: Int loop' = sum . map (+1) $ [1..100] this does turn into a loop over integers, with no intermediate list. Presumably this is due to there being no work to be saved ever by floating the list out. These are the examples people usually test fusion with. And if loop is small enough to inline, it turns out that the actual code that gets run will be the same as loop', because everything will get inlined and fused. But it is also possible to make loop big enough to not inline, and then the floating will pessimize the overall code. So the core issue is that constant floating blocks some fusion opportunities. It is trying to save the work of building the structure more than once, but fusion can cause the structure to not be built at all. And the floating happens before fusion can reasonably be expected to work. Can anything be done about this? I've verified that this kind of situation also affects vector. And it seems to be an issue even if loop is written: loop g = sum (map g [1..100]) -- Dan On Wed, Aug 27, 2014 at 3:38 PM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: You'll have to do more detective work! In your dump I see Inactive unfolding $. So that's why it's not being inlined. That message comes from CoreUnfold, line 941 or so. The Boolean active_unfolding is passed in to callSiteInline from Simplify, line 1408 or so. It is generated by the function activeUnfolding, defined in SimplUtils. But you have probably change the CompilerPhase data type, so I can't guess what is happening. But if you just follow it through I'm sure you'll find it. Simon | -Original Message- | From: David Feuer [mailto:david.fe...@gmail.commailto:david.fe...@gmail.com] | Sent: 27 August 2014 17:22 | To: Simon Peyton Jones | Cc: ghc-devs | Subject: Re: Why isn't ($) inlining when I want? | | I just ran that (results attached), and as far as I can tell, it | doesn't even *consider* inlining ($) until phase 2. | | On Wed, Aug 27, 2014 at 4:03 AM, Simon Peyton Jones | simo...@microsoft.commailto:simo...@microsoft.com wrote: | It's hard to tell since you are using a modified compiler. Try running | with -ddump-occur-anal -dverbose-core2core -ddump-inlinings. That will | show you every inlining, whether failed or successful. You can see the | attempt to inline ($) and there is some info with the output that may | help to explain why it did or did not work. | | Try that | | Simon | | | -Original Message- | | From: ghc-devs [mailto:ghc-devs-boun...@haskell.orgmailto:ghc-devs-boun...@haskell.org] On Behalf Of | David | | Feuer | | Sent: 27 August 2014 04:50 | | To: ghc-devs; Carter Schonwald | | Subject: Why isn't ($) inlining when I want? | | | | tl;dr I added a simplifier run with inlining enabled between | | specialization and floating out. It seems incapable of inlining | | saturated applications of ($), and I can't figure out why. These are | | inlined later, when phase 2 runs. Am I running the simplifier wrong | or | | something? | | | | | | I'm working on this simple little fusion pipeline: | | | | {-# INLINE takeWhile #-} | | takeWhile p xs = build builder | | where | | builder c n = foldr go n xs | | where | | go x r = if p x then x `c` r else n | | | | foo c n x = foldr c n . takeWhile (/= (1::Int)) $ [-9..10] | | | | There are some issues with the enumFrom definition that break things. | | If I use a fusible unfoldr that produces some numbers instead, that | | issue goes away. Part of that problem (but not all of it) is that the | | simplifier doesn't run to apply rules between specialization and full | | laziness, so there's no opportunity for the specialization of | | enumFromTo to Int to trigger the rewrite to a build form and fusion | | with foldr before full laziness tears things apart. The
Raft of optimiser changes
I've just pushed a bunch of Core-to-Core optimisation changes that have been sitting in my tree for ages. The aggregate effect on nofib is very modest, but they are mostly aimed at corner cases, and consolidation. Program SizeAllocs Runtime Elapsed TotalMem Min -7.2% -3.1% -7.8% -7.8%-14.8% Max +5.6% +1.3%+20.0%+19.7%+50.0% Geometric Mean -0.3% -0.1% +1.7% +1.7% +0.2% The runtime increases are spurious - I checked. A couple of perf/compiler tests (i.e. GHC's own performance) improve significantly, which is a good sign. I have a few more to come but wanted to get this lot out of my hair. Simon a1a400ed * Testsuite wibbles 39ccdf91 * White space only 6c6b001e * Remove dead lookup_dfun_id (merge-o) a0b2897e * Simple refactor of the case-of-case transform bb877266 * Performance changes 082e41b4 * Testsuite wibbles 1122857e * Run float-inwards immediately before the strictness analyser. 86a2ebf8 * Comments only 6d48ce29 * Make tidyProgram discard speculative specialisation rules fa582cc4 * Fix an egregious bug in the NonRec case of bindFreeVars b9e49d3e * Add -fspecialise-aggressively dce70957 * Compiler performance increases -- yay! a3e207f6 * More SPEC rules fire baa3c9a3 * Wibbles to ...plus N others error message about instances in scope 99178c1f * Specialise monad functions, and make them INLINEABLE 2ef997b8 * Slightly improve fusion rules for 'take' 949ad67e * Don't float out (classop dict e1 e2) 34363330 * Move the Enum Word instance into GHC.Enum 4c03791f * Specialise Eq, Ord, Read, Show at Int, Char, String 9cf5906b * Make worker/wrapper work on INLINEABLE things 8f099374 * Make maybeUnfoldingTemplate respond to DFunUnfoldings 3af1adf9 * Kill unused setUnfoldingTemplate 6e0f6ede * Refactor unfoldings e9cd1d5e * Less voluminous output when printing continuations ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
GHC AST Annotations
Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly capturing the missing location information for the syntactic markers. 2. Allow the annotation to be a parameter so that it can be replaced with a different one in tools, for example HaRe would include the tokens for the AST fragment leaves. 3. Aim for some level compatibility with haskell-src-exts so that tools developed for it could be easily ported to GHC, for example exactprint [4]. I would like feedback as to whether this would be acceptable, or if the same goals should be achieved a different way. Regards Alan [1] https://phabricator.haskell.org/D157 [2] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-SrcLoc.html#t:SrcSpanInfo [3] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-Syntax.html#t:Annotated [4] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-ExactPrint.html#v:exactPrint ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
RE: Why isn't ($) inlining when I want?
Actually the CONLIKE thing still allows them to float, but makes RULES continue to work even though they’ve been floated. See the user manual. From: Dan Doel [mailto:dan.d...@gmail.com] Sent: 28 August 2014 16:48 To: Simon Peyton Jones Cc: John Lato; David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? Okay, so marking things as conlike will make GHC avoid floating them? I'm pretty sure that in most vector cases, this is a straight pessimization. There is no way to avoid the extra allocation of integers, because most intermediate vector types are unboxed, so the integer allocation will be performed regardless. Only boxed vectors might be an exception. On Thu, Aug 28, 2014 at 4:14 AM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: I remember doing some work on the “floating of constant lists” question. First, [1..n] turns into (enumFromTo 1 n), and if enumFromTo was expensive, then sharing it might be a good plan. So GHC would have to know that it was cheap. I did experiment with “cheapBuild” see https://ghc.haskell.org/trac/ghc/ticket/7206, but as you’ll see there, the results were equivocal. By duplicating the [1..n] we were allocating two copies of (I# 4), (I# 5) etc, and that increased allocation and GC time. So it’s unclear, in general, whether in these examples it is better to share the [1..n] between all calls of ‘loop’, or to duplicate it. All that said, Dan’s question of why X fuses and very-similar Y doesn’t was a surprise to me; I’ll look into that. Simon From: John Lato [mailto:jwl...@gmail.commailto:jwl...@gmail.com] Sent: 28 August 2014 00:17 To: Dan Doel Cc: Simon Peyton Jones; David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? I sometimes think the solution is to make let-floating apply in fewer cases. I'm not sure we ever want to float out intermediate lists, the cost of creating them is very small relative to the memory consumption if they do happen to get shared. My approach is typically to mark loop INLINE. This very often results in the code I want (with vector, which I use more than lists), but it is a big hammer to apply. John On Thu, Aug 28, 2014 at 5:56 AM, Dan Doel dan.d...@gmail.commailto:dan.d...@gmail.com wrote: I think talking about inlining of $ may not be addressing the crux of the problem here. The issue seems to be about functions like the one in the first message. For instance: loop :: (Int - Int) - Int loop g = sum . map g $ [1..100] Suppose for argument that we have a fusion framework that would handle this. The problem is that this does not actually turn into a loop over integers, because the constant [1..100] gets floated out. It instead builds a list/vector/whatever. By contrast, if we write: loop' :: Int loop' = sum . map (+1) $ [1..100] this does turn into a loop over integers, with no intermediate list. Presumably this is due to there being no work to be saved ever by floating the list out. These are the examples people usually test fusion with. And if loop is small enough to inline, it turns out that the actual code that gets run will be the same as loop', because everything will get inlined and fused. But it is also possible to make loop big enough to not inline, and then the floating will pessimize the overall code. So the core issue is that constant floating blocks some fusion opportunities. It is trying to save the work of building the structure more than once, but fusion can cause the structure to not be built at all. And the floating happens before fusion can reasonably be expected to work. Can anything be done about this? I've verified that this kind of situation also affects vector. And it seems to be an issue even if loop is written: loop g = sum (map g [1..100]) -- Dan On Wed, Aug 27, 2014 at 3:38 PM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: You'll have to do more detective work! In your dump I see Inactive unfolding $. So that's why it's not being inlined. That message comes from CoreUnfold, line 941 or so. The Boolean active_unfolding is passed in to callSiteInline from Simplify, line 1408 or so. It is generated by the function activeUnfolding, defined in SimplUtils. But you have probably change the CompilerPhase data type, so I can't guess what is happening. But if you just follow it through I'm sure you'll find it. Simon | -Original Message- | From: David Feuer [mailto:david.fe...@gmail.commailto:david.fe...@gmail.com] | Sent: 27 August 2014 17:22 | To: Simon Peyton Jones | Cc: ghc-devs | Subject: Re: Why isn't ($) inlining when I want? | | I just ran that (results attached), and as far as I can tell, it | doesn't even *consider* inlining ($) until phase 2. | | On Wed, Aug 27, 2014 at 4:03 AM, Simon Peyton Jones | simo...@microsoft.commailto:simo...@microsoft.com wrote: | It's hard to tell since you are using a modified compiler. Try
RE: GHC AST Annotations
In general I’m fine with this direction of travel. Some specifics: ·You’d have to be careful to document, for every data constructor in HsSyn, what the association between the [SrcSpan] in the SrcSpanInfo and the “sub-entities” ·Many of the sub-entities will have their own SrcSpanInfo wrapped around them, so there’s some unhelpful duplication. Maybe you only want the SrcSpanInfo to list the [SrcSpan]s for the sub-entities (like the syntactic keywords) that do not show up as children in the syntax tree? Anyway do by all means create a GHC Trac wiki page to describe your proposed design, concretely. Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan Kim Zimmerman Sent: 28 August 2014 15:00 To: ghc-devs@haskell.org Subject: GHC AST Annotations Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly capturing the missing location information for the syntactic markers. 2. Allow the annotation to be a parameter so that it can be replaced with a different one in tools, for example HaRe would include the tokens for the AST fragment leaves. 3. Aim for some level compatibility with haskell-src-exts so that tools developed for it could be easily ported to GHC, for example exactprint [4]. I would like feedback as to whether this would be acceptable, or if the same goals should be achieved a different way. Regards Alan [1] https://phabricator.haskell.org/D157 [2] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-SrcLoc.html#t:SrcSpanInfo [3] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-Syntax.html#t:Annotated [4] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-ExactPrint.html#v:exactPrint ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Haddock build fails
Phab that I may have committed something that makes haddock fail to build (will teach me, again, to do a completely clean validate!) I'll look into this . Sorry Simon ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Why isn't (.) CONLIKE?
Speaking of CONLIKE, I'd have expected (.) to be CONLIKE, since it looks much like a constructor. Would that be bad for some reason? Or is it already treated well enough not to need that? On Aug 28, 2014 11:56 AM, Simon Peyton Jones simo...@microsoft.com wrote: Actually the CONLIKE thing still allows them to float, but makes RULES continue to work even though they’ve been floated. See the user manual. *From:* Dan Doel [mailto:dan.d...@gmail.com] *Sent:* 28 August 2014 16:48 *To:* Simon Peyton Jones *Cc:* John Lato; David Feuer; ghc-devs *Subject:* Re: Why isn't ($) inlining when I want? Okay, so marking things as conlike will make GHC avoid floating them? I'm pretty sure that in most vector cases, this is a straight pessimization. There is no way to avoid the extra allocation of integers, because most intermediate vector types are unboxed, so the integer allocation will be performed regardless. Only boxed vectors might be an exception. On Thu, Aug 28, 2014 at 4:14 AM, Simon Peyton Jones simo...@microsoft.com wrote: I remember doing some work on the “floating of constant lists” question. First, [1..n] turns into (enumFromTo 1 n), and if enumFromTo was expensive, then sharing it might be a good plan. So GHC would have to know that it was cheap. I did experiment with “cheapBuild” see https://ghc.haskell.org/trac/ghc/ticket/7206, but as you’ll see there, the results were equivocal. By duplicating the [1..n] we were allocating two copies of (I# 4), (I# 5) etc, and that increased allocation and GC time. So it’s unclear, in general, whether in these examples it is better to share the [1..n] between all calls of ‘loop’, or to duplicate it. All that said, Dan’s question of why X fuses and very-similar Y doesn’t was a surprise to me; I’ll look into that. Simon *From:* John Lato [mailto:jwl...@gmail.com] *Sent:* 28 August 2014 00:17 *To:* Dan Doel *Cc:* Simon Peyton Jones; David Feuer; ghc-devs *Subject:* Re: Why isn't ($) inlining when I want? I sometimes think the solution is to make let-floating apply in fewer cases. I'm not sure we ever want to float out intermediate lists, the cost of creating them is very small relative to the memory consumption if they do happen to get shared. My approach is typically to mark loop INLINE. This very often results in the code I want (with vector, which I use more than lists), but it is a big hammer to apply. John On Thu, Aug 28, 2014 at 5:56 AM, Dan Doel dan.d...@gmail.com wrote: I think talking about inlining of $ may not be addressing the crux of the problem here. The issue seems to be about functions like the one in the first message. For instance: loop :: (Int - Int) - Int loop g = sum . map g $ [1..100] Suppose for argument that we have a fusion framework that would handle this. The problem is that this does not actually turn into a loop over integers, because the constant [1..100] gets floated out. It instead builds a list/vector/whatever. By contrast, if we write: loop' :: Int loop' = sum . map (+1) $ [1..100] this does turn into a loop over integers, with no intermediate list. Presumably this is due to there being no work to be saved ever by floating the list out. These are the examples people usually test fusion with. And if loop is small enough to inline, it turns out that the actual code that gets run will be the same as loop', because everything will get inlined and fused. But it is also possible to make loop big enough to not inline, and then the floating will pessimize the overall code. So the core issue is that constant floating blocks some fusion opportunities. It is trying to save the work of building the structure more than once, but fusion can cause the structure to not be built at all. And the floating happens before fusion can reasonably be expected to work. Can anything be done about this? I've verified that this kind of situation also affects vector. And it seems to be an issue even if loop is written: loop g = sum (map g [1..100]) -- Dan On Wed, Aug 27, 2014 at 3:38 PM, Simon Peyton Jones simo...@microsoft.com wrote: You'll have to do more detective work! In your dump I see Inactive unfolding $. So that's why it's not being inlined. That message comes from CoreUnfold, line 941 or so. The Boolean active_unfolding is passed in to callSiteInline from Simplify, line 1408 or so. It is generated by the function activeUnfolding, defined in SimplUtils. But you have probably change the CompilerPhase data type, so I can't guess what is happening. But if you just follow it through I'm sure you'll find it. Simon | -Original Message- | From: David Feuer [mailto:david.fe...@gmail.com] | Sent: 27 August 2014 17:22 | To: Simon Peyton Jones | Cc: ghc-devs | Subject: Re: Why isn't ($) inlining when I want? | | I just ran that (results attached), and as far as I
RE: Haddock build fails
I've pushed a temporary fix From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Simon Peyton Jones Sent: 28 August 2014 17:35 To: ghc-devs Subject: Haddock build fails Phab that I may have committed something that makes haddock fail to build (will teach me, again, to do a completely clean validate!) I'll look into this . Sorry Simon ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Re: GHC AST Annotations
For what it's worth, my thought is not to use SrcSpanInfo (which, to me, is the wrong way to slice the abstraction) but instead to add SrcSpan fields to the relevant nodes. For example: | HsDoSrcSpan -- of the word do BlockSrcSpans (HsStmtContext Name) -- The parameterisation is unimportant -- because in this context we never use -- the PatGuard or ParStmt variant [ExprLStmt id] -- do:one or more stmts PostTcType -- Type of the whole expression ... data BlockSrcSpans = LayoutBlock Int -- the parameter is the indentation level ... -- stuff to track the appearance of any semicolons | BracesBlock ... -- stuff to track the braces and semicolons The way I understand it, the SrcSpanInfo proposal means that we would have lots of empty SrcSpanInfos, no? Most interior nodes don't need one, I think. Popping up a level, I do support the idea of including this info in the AST. Richard On Aug 28, 2014, at 11:54 AM, Simon Peyton Jones simo...@microsoft.com wrote: In general I’m fine with this direction of travel. Some specifics: ·You’d have to be careful to document, for every data constructor in HsSyn, what the association between the [SrcSpan] in the SrcSpanInfo and the “sub-entities” ·Many of the sub-entities will have their own SrcSpanInfo wrapped around them, so there’s some unhelpful duplication. Maybe you only want the SrcSpanInfo to list the [SrcSpan]s for the sub-entities (like the syntactic keywords) that do not show up as children in the syntax tree? Anyway do by all means create a GHC Trac wiki page to describe your proposed design, concretely. Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan Kim Zimmerman Sent: 28 August 2014 15:00 To: ghc-devs@haskell.org Subject: GHC AST Annotations Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly capturing the missing location information for the syntactic markers. 2. Allow the annotation to be a parameter so that it can be replaced with a different one in tools, for example HaRe would include the tokens for the AST fragment leaves. 3. Aim for some level compatibility with haskell-src-exts so that tools developed for it could be easily ported to GHC, for example exactprint [4]. I would like feedback as to whether this would be acceptable, or if the same goals should be achieved a different way. Regards Alan [1] https://phabricator.haskell.org/D157 [2] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-SrcLoc.html#t:SrcSpanInfo [3] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-Syntax.html#t:Annotated [4] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-Annotated-ExactPrint.html#v:exactPrint ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Re: GHC AST Annotations
This does have the advantage of being explicit. I modelled the initial proposal on HSE as a proven solution, and I think that they were trying to keep it non-invasive, to allow both an annotated and non-annoted AST. I thiink the key question is whether it is acceptable to sprinkle this kind of information throughout the AST. For someone interested in source-to-source conversions (like me) this is great, others may find it intrusive. The other question, which is probably orthogonal to this, is whether we want the annotation to be a parameter to the AST, which allows it to be overridden by various tools for various purposes, or fixed as in Richard's suggestion. A parameterised annotation allows the annotations to be manipulated via something like for HSE: -- |AST nodes are annotated, and this class allows manipulation of the annotations. class Functor ast = Annotated ast where -- |Retrieve the annotation of an AST node. ann :: ast l - l -- |Change the annotation of an AST node. Note that only the annotation of the node itself is affected, and not -- the annotations of any child nodes. if all nodes in the AST tree are to be affected, use fmap. amap :: (l - l) - ast l - ast l Alan On Thu, Aug 28, 2014 at 7:11 PM, Richard Eisenberg e...@cis.upenn.edu wrote: For what it's worth, my thought is not to use SrcSpanInfo (which, to me, is the wrong way to slice the abstraction) but instead to add SrcSpan fields to the relevant nodes. For example: | HsDoSrcSpan -- of the word do BlockSrcSpans (HsStmtContext Name) -- The parameterisation is unimportant -- because in this context we never use -- the PatGuard or ParStmt variant [ExprLStmt id] -- do:one or more stmts PostTcType -- Type of the whole expression ... data BlockSrcSpans = LayoutBlock Int -- the parameter is the indentation level ... -- stuff to track the appearance of any semicolons | BracesBlock ... -- stuff to track the braces and semicolons The way I understand it, the SrcSpanInfo proposal means that we would have lots of empty SrcSpanInfos, no? Most interior nodes don't need one, I think. Popping up a level, I do support the idea of including this info in the AST. Richard On Aug 28, 2014, at 11:54 AM, Simon Peyton Jones simo...@microsoft.com wrote: In general I’m fine with this direction of travel. Some specifics: ·You’d have to be careful to document, for every data constructor in HsSyn, what the association between the [SrcSpan] in the SrcSpanInfo and the “sub-entities” ·Many of the sub-entities will have their own SrcSpanInfo wrapped around them, so there’s some unhelpful duplication. Maybe you only want the SrcSpanInfo to list the [SrcSpan]s for the sub-entities (like the syntactic keywords) that do not show up as children in the syntax tree? Anyway do by all means create a GHC Trac wiki page to describe your proposed design, concretely. Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan Kim Zimmerman Sent: 28 August 2014 15:00 To: ghc-devs@haskell.org Subject: GHC AST Annotations Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly capturing the missing location information for the syntactic markers. 2. Allow the annotation to be a parameter so that it can be replaced with a different one in tools, for example HaRe would include the tokens for the AST fragment leaves. 3. Aim for some level compatibility with haskell-src-exts so that tools developed for it could be easily ported to GHC, for example exactprint [4]. I would like feedback as to whether this would be acceptable, or if the same goals should be achieved a different way. Regards Alan [1] https://phabricator.haskell.org/D157 [2] http://hackage.haskell.org/package/haskell-src-exts-1.15.0.1/docs/Language-Haskell-Exts-SrcLoc.html#t:SrcSpanInfo [3]
Contributing To Haskell talk
Hi list, you might know that was I talked into^W^Wvolunteered to holding the “Contributing to GHC”¹ talk at HIW in 9 days. I’ll do it, but for some of the intended topics, I don’t feel like the best person to do it on my own. In particular, I was wondering if any of the active Phabricator proponents or users would be available to help me there, either during the preparation (which will happen at Göteborg; I’m currently distracted by the Debian Conference in Portland), or by performing a duet. Thanks, Joachim ¹ http://www.haskell.org/haskellwiki/HaskellImplementorsWorkshop/2014#Contributing_to_GHC -- Joachim “nomeata” Breitner m...@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nome...@joachim-breitner.de • GPG-Key: 0xF0FBF51F Debian Developer: nome...@debian.org signature.asc Description: This is a digitally signed message part ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Re: GHC AST Annotations
I have started capturing the discussion here https://ghc.haskell.org/trac/ghc/wiki/GhcAstAnnotations. On Thu, Aug 28, 2014 at 8:34 PM, Alan Kim Zimmerman alan.z...@gmail.com wrote: This does have the advantage of being explicit. I modelled the initial proposal on HSE as a proven solution, and I think that they were trying to keep it non-invasive, to allow both an annotated and non-annoted AST. I thiink the key question is whether it is acceptable to sprinkle this kind of information throughout the AST. For someone interested in source-to-source conversions (like me) this is great, others may find it intrusive. The other question, which is probably orthogonal to this, is whether we want the annotation to be a parameter to the AST, which allows it to be overridden by various tools for various purposes, or fixed as in Richard's suggestion. A parameterised annotation allows the annotations to be manipulated via something like for HSE: -- |AST nodes are annotated, and this class allows manipulation of the annotations. class Functor ast = Annotated ast where -- |Retrieve the annotation of an AST node. ann :: ast l - l -- |Change the annotation of an AST node. Note that only the annotation of the node itself is affected, and not -- the annotations of any child nodes. if all nodes in the AST tree are to be affected, use fmap. amap :: (l - l) - ast l - ast l Alan On Thu, Aug 28, 2014 at 7:11 PM, Richard Eisenberg e...@cis.upenn.edu wrote: For what it's worth, my thought is not to use SrcSpanInfo (which, to me, is the wrong way to slice the abstraction) but instead to add SrcSpan fields to the relevant nodes. For example: | HsDoSrcSpan -- of the word do BlockSrcSpans (HsStmtContext Name) -- The parameterisation is unimportant -- because in this context we never use -- the PatGuard or ParStmt variant [ExprLStmt id] -- do:one or more stmts PostTcType -- Type of the whole expression ... data BlockSrcSpans = LayoutBlock Int -- the parameter is the indentation level ... -- stuff to track the appearance of any semicolons | BracesBlock ... -- stuff to track the braces and semicolons The way I understand it, the SrcSpanInfo proposal means that we would have lots of empty SrcSpanInfos, no? Most interior nodes don't need one, I think. Popping up a level, I do support the idea of including this info in the AST. Richard On Aug 28, 2014, at 11:54 AM, Simon Peyton Jones simo...@microsoft.com wrote: In general I’m fine with this direction of travel. Some specifics: ·You’d have to be careful to document, for every data constructor in HsSyn, what the association between the [SrcSpan] in the SrcSpanInfo and the “sub-entities” ·Many of the sub-entities will have their own SrcSpanInfo wrapped around them, so there’s some unhelpful duplication. Maybe you only want the SrcSpanInfo to list the [SrcSpan]s for the sub-entities (like the syntactic keywords) that do not show up as children in the syntax tree? Anyway do by all means create a GHC Trac wiki page to describe your proposed design, concretely. Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan Kim Zimmerman Sent: 28 August 2014 15:00 To: ghc-devs@haskell.org Subject: GHC AST Annotations Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly capturing the missing location information for the syntactic markers. 2. Allow the annotation to be a parameter so that it can be replaced with a different one in tools, for example HaRe would include the tokens for the AST fragment leaves. 3. Aim for some level compatibility with haskell-src-exts so that tools developed for it could be easily ported to GHC, for example exactprint [4]. I would like feedback as to whether this would be acceptable, or if the same goals should be achieved a different way. Regards Alan [1]
RE: GHC AST Annotations
I thiink the key question is whether it is acceptable to sprinkle this kind of information throughout the AST. For someone interested in source-to-source conversions (like me) this is great, others may find it intrusive. It’s probably not too bad if you use record syntax; thus | HsDo { hsdo_do_loc :: SrcSpan -- of the word do , hsdo_blocks :: BlockSrcSpans , hsdo_ctxt :: HsStmtContext Name , hsdo_stmts :: [ExprLStmt id] , hsdo_type:: PostTcType } Simon From: Alan Kim Zimmerman [mailto:alan.z...@gmail.com] Sent: 28 August 2014 19:35 To: Richard Eisenberg Cc: Simon Peyton Jones; ghc-devs@haskell.org Subject: Re: GHC AST Annotations This does have the advantage of being explicit. I modelled the initial proposal on HSE as a proven solution, and I think that they were trying to keep it non-invasive, to allow both an annotated and non-annoted AST. I thiink the key question is whether it is acceptable to sprinkle this kind of information throughout the AST. For someone interested in source-to-source conversions (like me) this is great, others may find it intrusive. The other question, which is probably orthogonal to this, is whether we want the annotation to be a parameter to the AST, which allows it to be overridden by various tools for various purposes, or fixed as in Richard's suggestion. A parameterised annotation allows the annotations to be manipulated via something like for HSE: -- |AST nodes are annotated, and this class allows manipulation of the annotations. class Functor ast = Annotated ast where -- |Retrieve the annotation of an AST node. ann :: ast l - l -- |Change the annotation of an AST node. Note that only the annotation of the node itself is affected, and not -- the annotations of any child nodes. if all nodes in the AST tree are to be affected, use fmap. amap :: (l - l) - ast l - ast l Alan On Thu, Aug 28, 2014 at 7:11 PM, Richard Eisenberg e...@cis.upenn.edumailto:e...@cis.upenn.edu wrote: For what it's worth, my thought is not to use SrcSpanInfo (which, to me, is the wrong way to slice the abstraction) but instead to add SrcSpan fields to the relevant nodes. For example: | HsDoSrcSpan -- of the word do BlockSrcSpans (HsStmtContext Name) -- The parameterisation is unimportant -- because in this context we never use -- the PatGuard or ParStmt variant [ExprLStmt id] -- do:one or more stmts PostTcType -- Type of the whole expression ... data BlockSrcSpans = LayoutBlock Int -- the parameter is the indentation level ... -- stuff to track the appearance of any semicolons | BracesBlock ... -- stuff to track the braces and semicolons The way I understand it, the SrcSpanInfo proposal means that we would have lots of empty SrcSpanInfos, no? Most interior nodes don't need one, I think. Popping up a level, I do support the idea of including this info in the AST. Richard On Aug 28, 2014, at 11:54 AM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: In general I’m fine with this direction of travel. Some specifics: ·You’d have to be careful to document, for every data constructor in HsSyn, what the association between the [SrcSpan] in the SrcSpanInfo and the “sub-entities” ·Many of the sub-entities will have their own SrcSpanInfo wrapped around them, so there’s some unhelpful duplication. Maybe you only want the SrcSpanInfo to list the [SrcSpan]s for the sub-entities (like the syntactic keywords) that do not show up as children in the syntax tree? Anyway do by all means create a GHC Trac wiki page to describe your proposed design, concretely. Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.orgmailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan Kim Zimmerman Sent: 28 August 2014 15:00 To: ghc-devs@haskell.orgmailto:ghc-devs@haskell.org Subject: GHC AST Annotations Now that the landmines have hopefully been cleared from the AST via [1] I would like to propose changing the location information in the AST. Right now the locations of syntactic markers such as do/let/where/in/of in the source are discarded from the AST, although they are retained in the rich token stream. The haskell-src-exts package deals with this by means of using the SrcSpanInfo data type [2] which contains the SrcSpan as per the current GHC Located type but also has a list of SrcSpan s for the syntactic markers, depending on the particular AST fragment being annotated. In addition, the annotation type is provided as a parameter to the AST, so that it can be changed as required, see [3]. The motivation for this change is then 1. Simplify the roundtripping and modification of source by explicitly
RE: Why isn't (.) CONLIKE?
Maybe. But to use on the LHS of a rule (which would be the motivation, I assume) you’d also need to make sure it was not inlined in phase 2. Perhaps do-able, but you’d need some compelling examples to motivate Simon From: David Feuer [mailto:david.fe...@gmail.com] Sent: 28 August 2014 17:51 To: Simon Peyton Jones Cc: ghc-devs Subject: Why isn't (.) CONLIKE? Speaking of CONLIKE, I'd have expected (.) to be CONLIKE, since it looks much like a constructor. Would that be bad for some reason? Or is it already treated well enough not to need that? On Aug 28, 2014 11:56 AM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: Actually the CONLIKE thing still allows them to float, but makes RULES continue to work even though they’ve been floated. See the user manual. From: Dan Doel [mailto:dan.d...@gmail.commailto:dan.d...@gmail.com] Sent: 28 August 2014 16:48 To: Simon Peyton Jones Cc: John Lato; David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? Okay, so marking things as conlike will make GHC avoid floating them? I'm pretty sure that in most vector cases, this is a straight pessimization. There is no way to avoid the extra allocation of integers, because most intermediate vector types are unboxed, so the integer allocation will be performed regardless. Only boxed vectors might be an exception. On Thu, Aug 28, 2014 at 4:14 AM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: I remember doing some work on the “floating of constant lists” question. First, [1..n] turns into (enumFromTo 1 n), and if enumFromTo was expensive, then sharing it might be a good plan. So GHC would have to know that it was cheap. I did experiment with “cheapBuild” see https://ghc.haskell.org/trac/ghc/ticket/7206, but as you’ll see there, the results were equivocal. By duplicating the [1..n] we were allocating two copies of (I# 4), (I# 5) etc, and that increased allocation and GC time. So it’s unclear, in general, whether in these examples it is better to share the [1..n] between all calls of ‘loop’, or to duplicate it. All that said, Dan’s question of why X fuses and very-similar Y doesn’t was a surprise to me; I’ll look into that. Simon From: John Lato [mailto:jwl...@gmail.commailto:jwl...@gmail.com] Sent: 28 August 2014 00:17 To: Dan Doel Cc: Simon Peyton Jones; David Feuer; ghc-devs Subject: Re: Why isn't ($) inlining when I want? I sometimes think the solution is to make let-floating apply in fewer cases. I'm not sure we ever want to float out intermediate lists, the cost of creating them is very small relative to the memory consumption if they do happen to get shared. My approach is typically to mark loop INLINE. This very often results in the code I want (with vector, which I use more than lists), but it is a big hammer to apply. John On Thu, Aug 28, 2014 at 5:56 AM, Dan Doel dan.d...@gmail.commailto:dan.d...@gmail.com wrote: I think talking about inlining of $ may not be addressing the crux of the problem here. The issue seems to be about functions like the one in the first message. For instance: loop :: (Int - Int) - Int loop g = sum . map g $ [1..100] Suppose for argument that we have a fusion framework that would handle this. The problem is that this does not actually turn into a loop over integers, because the constant [1..100] gets floated out. It instead builds a list/vector/whatever. By contrast, if we write: loop' :: Int loop' = sum . map (+1) $ [1..100] this does turn into a loop over integers, with no intermediate list. Presumably this is due to there being no work to be saved ever by floating the list out. These are the examples people usually test fusion with. And if loop is small enough to inline, it turns out that the actual code that gets run will be the same as loop', because everything will get inlined and fused. But it is also possible to make loop big enough to not inline, and then the floating will pessimize the overall code. So the core issue is that constant floating blocks some fusion opportunities. It is trying to save the work of building the structure more than once, but fusion can cause the structure to not be built at all. And the floating happens before fusion can reasonably be expected to work. Can anything be done about this? I've verified that this kind of situation also affects vector. And it seems to be an issue even if loop is written: loop g = sum (map g [1..100]) -- Dan On Wed, Aug 27, 2014 at 3:38 PM, Simon Peyton Jones simo...@microsoft.commailto:simo...@microsoft.com wrote: You'll have to do more detective work! In your dump I see Inactive unfolding $. So that's why it's not being inlined. That message comes from CoreUnfold, line 941 or so. The Boolean active_unfolding is passed in to callSiteInline from Simplify, line 1408 or so. It is generated by the function activeUnfolding, defined in SimplUtils. But you have
clang warnings with unregisterised
Devs, I have built an UNREGISTERISED GHC, and the C-compiler used behind the scenes is clang. Now I get literally millions of warnings of the below kind: +/var/folders/k9/fj_1d5h17m7c4gbyp2srqrhmgq/T/ghc11601_0/ghc11601_4.hc:688:1: + warning: attribute declaration must precede definition [-Wignored-attributes] +II_(s4Vv_closure); +^ + +/Users/ggreif/ghc-head/includes/Stg.h:213:63: + note: expanded from macro 'II_' +#define II_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) + ^ + +/Users/ggreif/ghc-head/includes/Stg.h:175:42: + note: expanded from macro 'GNU_ATTRIBUTE' +#define GNU_ATTRIBUTE(at) __attribute__((at)) + ^ + +/var/folders/k9/fj_1d5h17m7c4gbyp2srqrhmgq/T/ghc11601_0/ghc11601_4.hc:588:16: + note: previous definition is here +static StgWord s4Vv_closure[] = { + ^ It seems like the II_ and EI_ prototypes *follow* the real thing, and because clang is more picky with attribute placement, we get all those warnings. compiler/cmm/PprC.hs:pprExternDecl is the function that puts together the II_(...) and EI_(...), but where does the static StgWord s4Vv_closure[] = { come from? I just want to flip the order of their occurrence. Thanks, Gabor ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Raft of optimizer changes
On Thu, Aug 28, 2014 at 8:00 AM, simonpj wrote I've just pushed a bunch of Core-to-Core optimisation changes that have been sitting in my tree for ages. The aggregate effect on nofib is very modest, but they are mostly aimed at corner cases, and consolidation. Thanks for trying to do that. Unfortunately, this seems to have introduced some other sort of corner case. Making reverse (and unfoldr, but I'm pretty sure that's unused and hence irrelevant) fusible now makes n-body allocate 1100% more. I haven't looked into why yet. David ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs
Re: clang warnings with unregisterised
On Fri, 29 Aug 2014 02:56:01 +0200 Gabor Greif ggr...@gmail.com wrote: Devs, I have built an UNREGISTERISED GHC, and the C-compiler used behind the scenes is clang. Now I get literally millions of warnings of the below kind: +/var/folders/k9/fj_1d5h17m7c4gbyp2srqrhmgq/T/ghc11601_0/ghc11601_4.hc:688:1: + warning: attribute declaration must precede definition [-Wignored-attributes] +II_(s4Vv_closure); +^ + +/Users/ggreif/ghc-head/includes/Stg.h:213:63: + note: expanded from macro 'II_' +#define II_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) + ^ + +/Users/ggreif/ghc-head/includes/Stg.h:175:42: + note: expanded from macro 'GNU_ATTRIBUTE' +#define GNU_ATTRIBUTE(at) __attribute__((at)) + ^ + +/var/folders/k9/fj_1d5h17m7c4gbyp2srqrhmgq/T/ghc11601_0/ghc11601_4.hc:588:16: + note: previous definition is here +static StgWord s4Vv_closure[] = { + ^ It seems like the II_ and EI_ prototypes *follow* the real thing, and because clang is more picky with attribute placement, we get all those warnings. They just occur many times in the source, thus not only before but also after definition. compiler/cmm/PprC.hs:pprExternDecl is the function that puts together the II_(...) and EI_(...), but where does the static StgWord s4Vv_closure[] = { come from? pprWordArray :: CLabel - [CmmStatic] - SDoc I just want to flip the order of their occurrence. I think it would be a good thing to split .hc file lifting all external and local declarations up (and print only unique ones). It should shrink .hc file size a bit and make it nicer to read. -- Sergei signature.asc Description: PGP signature ___ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs