GHC: Ticket Query
http://ghc.haskell.org/trac/ghc/query?status=!closed&cc=~sof&desc=1&order=priority
The Glasgow Haskell Compileren-USGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/query?status=!closed&cc=~sof&desc=1&order=priority
Trac 1.0.1
http://ghc.haskell.org/trac/ghc/ticket/1365
http://ghc.haskell.org/trac/ghc/ticket/1365#1365: -fbyte-code is ignored in a OPTIONS_GHC pragmaSat, 19 May 2007 18:19:08 GMTmnislaih<p>
When loading a bunch of modules in ghci with <em>-fobject-code</em>, it seems reasonable to be expect that individual <em>GHC_OPTIONS -fbyte-code</em> pragmas will have the effect of loading individual modules via the bytecode backend.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1365#changelog
http://ghc.haskell.org/trac/ghc/ticket/4296
http://ghc.haskell.org/trac/ghc/ticket/4296#4296: The dreaded SkolemOccurs problemTue, 07 Sep 2010 13:35:20 GMTsimonpj<p>
The "SkolemOccurs" problem is a celebrated difficulty with combining (a) termination and (b) completeness, in this example:
</p>
<pre class="wiki">type instance F [a] = [F a]
f :: (F [a] ~ a) => ...
</pre><p>
Currently we err on the side of completeness, and lose termination:
</p>
<pre class="wiki">Simple20.hs:9:1:
Context reduction stack overflow; size = 21
Use -fcontext-stack=N to increase stack size to N
co :: F [F (F (F (F (F (F (F (F (F (F a)))))))))]
~
F (F (F (F (F (F (F (F (F (F a)))))))))
co :: F (F (F (F (F (F (F (F (F a))))))))
~
[F (F (F (F (F (F (F (F (F (F a)))))))))]
co :: F [F (F (F (F (F (F (F (F (F a))))))))]
~
F (F (F (F (F (F (F (F (F a))))))))
co :: F (F (F (F (F (F (F (F a)))))))
~
[F (F (F (F (F (F (F (F (F a))))))))]
co :: F [F (F (F (F (F (F (F (F a)))))))]
~
F (F (F (F (F (F (F (F a)))))))
co :: F (F (F (F (F (F (F a))))))
~
[F (F (F (F (F (F (F (F a)))))))]
co :: F [F (F (F (F (F (F (F a))))))] ~ F (F (F (F (F (F (F a))))))
co :: F (F (F (F (F (F a))))) ~ [F (F (F (F (F (F (F a))))))]
co :: F [F (F (F (F (F (F a)))))] ~ F (F (F (F (F (F a)))))
co :: F (F (F (F (F a)))) ~ [F (F (F (F (F (F a)))))]
co :: F [F (F (F (F (F a))))] ~ F (F (F (F (F a))))
co :: F (F (F (F a))) ~ [F (F (F (F (F a))))]
co :: F [F (F (F (F a)))] ~ F (F (F (F a)))
co :: F (F (F a)) ~ [F (F (F (F a)))]
co :: F [F (F (F a))] ~ F (F (F a))
co :: F (F a) ~ [F (F (F a))]
co :: F [F (F a)] ~ F (F a)
co :: F a ~ [F (F a)]
co :: F [F a] ~ F a
co :: a ~ [F a]
co :: F [a] ~ a
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/4296#changelog
http://ghc.haskell.org/trac/ghc/ticket/4329
http://ghc.haskell.org/trac/ghc/ticket/4329#4329: GHC.Conc modifyTVar primitiveTue, 21 Sep 2010 20:18:14 GMTdmbarbour<p>
I would like modifyTVar as a 'write-only' primitive supported by GHC's STM.
</p>
<p>
The semantic definition is:
</p>
<blockquote class="citation">
<p>
modifyTVar :: TVar a -> (a -> a) -> STM ()
modifyTVar v f = readTVar v >>= writeTVar v . f
</p>
</blockquote>
<p>
However, explicitly reading then writing the TVar introduces unnecessary interference between transactions. The value held by the TVar does not affect the behavior of the transaction. modifyTVar should not interfere with other transactions that only writeTVar or modifyTVar.
</p>
<p>
Even if a non-interfering implementation isn't feasible due to the underlying implementation of GHC's STM, providing the function would provide a point for a transparent upgrade in the future.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4329#changelog
http://ghc.haskell.org/trac/ghc/ticket/4479
http://ghc.haskell.org/trac/ghc/ticket/4479#4479: Implement Dot as Postfix Function ApplySat, 06 Nov 2010 19:50:22 GMTgidyn<p>
A request to implement <a class="ext-link" href="https://ghc.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/DotPostfix"><span class="icon"></span>Dot as Postfix Function Apply</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4479#changelog
http://ghc.haskell.org/trac/ghc/ticket/4800
http://ghc.haskell.org/trac/ghc/ticket/4800#4800: Memory Leak when Compiling qtHaskellMon, 29 Nov 2010 08:48:08 GMTgidyn<p>
I get an out-of-memory error about two thirds of the way through building qtHaskell (latest version, 1.1.4). If I start again, the remaining modules are compiled successfully, although GHC's memory usage creeps up to about 1.5Gb by the time it's finished.
</p>
<p>
This is on Win7 x64 with 4Gb RAM.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4800#changelog
http://ghc.haskell.org/trac/ghc/ticket/2189
http://ghc.haskell.org/trac/ghc/ticket/2189#2189: hSetBuffering stdin NoBuffering doesn't work on WindowsMon, 31 Mar 2008 21:22:42 GMTFalconNL<p>
The following program repeats inputted characters until the escape key is pressed.
</p>
<pre class="wiki">import IO
import Monad
import Char
main :: IO ()
main = do hSetBuffering stdin NoBuffering
inputLoop
inputLoop :: IO ()
inputLoop = do i <- getContents
mapM_ putChar $ takeWhile ((/= 27) . ord) i
</pre><p>
Because of the "hSetBuffering stdin NoBuffering" line it should not be necessary to press the enter key between keystrokes. This program works correctly in WinHugs (sep 2006 version). However, GHC 6.8.2 does not repeat the characters until the enter key is pressed. The problem was reproduced with all GHC executables (ghci, ghc, runghc, runhaskell), using both cmd.exe and command.com on Windows XP Professional.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/2189#changelog
http://ghc.haskell.org/trac/ghc/ticket/4259
http://ghc.haskell.org/trac/ghc/ticket/4259#4259: Relax restrictions on type family instance overlapMon, 16 Aug 2010 14:43:56 GMTlilac<p>
The following reduced fragment of some real code is rejected, but could be accepted, by GHC:
</p>
<pre class="wiki">{-# LANGUAGE TypeFamilies, EmptyDataDecls #-}
data True
type family LessEq a b :: *
type instance LessEq a a = True
type instance LessEq (f a) (f b) = LessEq a b
</pre><p>
GHC says:
</p>
<pre class="wiki"> Conflicting family instance declarations:
type instance LessEq a a
-- Defined at /home/richards/.random/tf.hs:5:14-19
type instance LessEq (f a) (f b)
-- Defined at /home/richards/.random/tf.hs:6:14-19
</pre><p>
This is entirely in line with the documentation, which requires the RHS to be structurally equivalent in the case of overlap. However, this rule is too restrictive. In the absence of -XUndecidableInstances, neither termination nor soundness would be sacrificed if the rule were relaxed to require extensional equality /after/ expanding the types as far as possible.
</p>
<p>
In particular (absent -XUndecidableInstances), such an expansion must terminate for the same reason that type families terminate in general. For soundness, suppose the resulting system is unsound, and consider the smallest type family application which has two possible distinct expanded types. We know the RHS of those types are equal after a partial expansion of only smaller (hence sound by minimality) type family applications, resulting in a contradiction.
</p>
<p>
In order to retain soundness in the presence of -XUndecidableInstances, any pair of type instances, where either instance could not be compiled without -XUndecidableInstances, would continue to use the current syntactic equality rule.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4259#changelog
http://ghc.haskell.org/trac/ghc/ticket/4370
http://ghc.haskell.org/trac/ghc/ticket/4370#4370: Bring back monad comprehensionsWed, 06 Oct 2010 07:43:21 GMTsimonpj<p>
George Giorgidze writes: My colleagues and I are working on Haskell <a class="ext-link" href="http://www-db.informatik.uni-tuebingen.de/files/weijers/IFL2010complete.pdf"><span class="icon"></span>embedded DSL for data-intensive and data-parallel applications</a>. The idea is to provide the Haskell list prelude combinators to manipulate database-resident data. The combinators are not executed in Haskell runtime, instead they are compiled down to SQL, executed on relational database systems and the results are marshalled back to Haskell for further in-heap processing or generation of new database-able embedded programs.
</p>
<p>
Although programming with the standard list processing combinators is feasible, the embedded programs are much more concisely formulated using the list comprehension notation, especially, when extended with <a class="ext-link" href="http://research.microsoft.com/en-us/um/people/simonpj/papers/list-comp/"><span class="icon"></span>'order by' and 'group by' constructs</a>.
</p>
<p>
Unfortunately, in Haskell, the list comprehension notation is only available for processing lists.
</p>
<p>
In order to support the list comprehension notation, we have built a quasiquter that desugars the list comprehension notation, but, instead of generating code using the Haskell list prelude combinators the quasiquter generates code that uses list processing combinators from our embedded language.
</p>
<p>
Although the quasiquoting approach worked for us, it has a number of
drawbacks:
</p>
<ul><li>Introduces extra syntactic noise
</li><li>Error messages are hard to understand as they refer to enerated code
</li><li>Needs to be re-implemented for every list-based embedded language
</li></ul><p>
One way to address the aforementioned drawbacks is to define our queries as a monad (similar to list monad) and use the monad comprehension notation. The do notation can be used but it is less suited for query languages.
</p>
<p>
Unfortunately monad comprehensions were removed from Haskell, prior to Haskell 98. However, I think that the notation is extremely useful not only for lists, but for other list like data structures, list-based query languages (see above), maybe even for wider range of EDSLs and monads. I think the feature deserves to be supported at least as a GHC language extension.
</p>
<p>
Thus, I would like to propose to design and implement the monad comprehension notation as a GHC language extension. I am willing to invest some time and contribute to this effort.
</p>
<p>
One can also look at how recently introduced 'order by' and 'group by'
constructs generalise to monad comprehensions. If that works, one could implement even more "stylish" monad comprehension notation.
</p>
<p>
Feedback from GHC users and developers would be very much appreciated.
</p>
<ul><li>Do you think that this is a good idea?
</li></ul><ul><li>Would you use monad comprehensions (if available) for your
library/EDSL/application?
</li></ul><ul><li>Do you think that it would be hard to integrate this extension into
current GHC codebase?
</li></ul><p>
</p>
<ul><li>Have you already thought about how to generalise 'order by' and 'group by' to monad comprehensions?
</li></ul><ul><li>Have you already thought about how to address the original objections to the monad comprehension notation?
</li></ul>Resultshttp://ghc.haskell.org/trac/ghc/ticket/4370#changelog
http://ghc.haskell.org/trac/ghc/ticket/4385
http://ghc.haskell.org/trac/ghc/ticket/4385#4385: Type-level natural numbersMon, 11 Oct 2010 23:22:51 GMTdiatchki<p>
Natural numbers at the type-level have many uses, especially in contexts where programmers need to manipulate data with statically known sizes. A simple form of this feature has been present in many programming languages for a long time (e.g., sub-range types in Pascal, array type in C, etc.). The feature is particularly useful when combined with polymorphism as illustrated by more recent programming languages (e.g., Cyclone, BlueSpec, Cryptol, Habit).
</p>
<p>
Existing features of Haskell's type system---such as polymorphism, kinds, and qualified types---make it particularly suitable for adding support for type level naturals in a natural way!
</p>
<p>
Indeed, there are quite a few Haskell libraries available on Hackage that implement support for type-level numbers in various forms. These libraries are being used by other packages and projects (e.g., the Kansas Lava project, and the type-safe bindings to the LLVM library).
</p>
<p>
Supporting natural number types directly in the compiler would help these projects, and others, by improving on the existing libraries in the following ways:
</p>
<ul><li>a standard implementation,
</li><li>a better notation,
</li><li>better error messages,
</li><li>a more efficient implementation,
</li><li>more complete support for numeric operations.
</li></ul><p>
I have started on an implementation of this feature, and my GHC branch is available in a darcs repository at the following URL:
</p>
<pre class="wiki">http://code.galois.com/darcs/ghc-type-naturals/
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/4385#changelog
http://ghc.haskell.org/trac/ghc/ticket/4894
http://ghc.haskell.org/trac/ghc/ticket/4894#4894: Missing improvement for fun. deps.Mon, 17 Jan 2011 03:16:09 GMTdiatchki<p>
The problem is illustrated by the following example:
</p>
<pre class="wiki">{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class F a b | a -> b
f :: (F a b, F a c) => a -> b -> c
f _ = id
Results in the following error:
Could not deduce (b ~ c)
from the context (F a b, F a c)
bound by the type signature for f :: (F a b, F a c) => a -> b -> c
at bug.hs:6:1-8
`b' is a rigid type variable bound by
the type signature for f :: (F a b, F a c) => a -> b -> c
at bug.hs:6:1
`c' is a rigid type variable bound by
the type signature for f :: (F a b, F a c) => a -> b -> c
at bug.hs:6:1
Expected type: b -> c
Actual type: b -> b
In the expression: id
In an equation for `f': f _ = id
</pre><p>
The issue seems to be related to Note [When improvement happens] in module TcInteract. It states that two "givens" do not interact for the purposes of improvement.
</p>
<p>
As far as I understand, the correct behavior should be to generate a new given equality, justified by the functional dependency on the class.
</p>
<p>
This is also related to bug <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1241" title="bug: Functional dependency Coverage Condition is lifted, and should not be (closed: fixed)">#1241</a>: in order to justify an improvement by functional dependency, we have to check that all instances are consistent with the dependency. Otherwise, the above function would turn into an "unsafe cast" function.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4894#changelog
http://ghc.haskell.org/trac/ghc/ticket/5320
http://ghc.haskell.org/trac/ghc/ticket/5320#5320: check_overlap panic (7.1 regression)Wed, 13 Jul 2011 13:19:00 GMTmikhail.vorozhtsov<p>
The attached program is rightfully rejected by GHC 7.0.4 (with <tt>"Could not deduce (HMapClass f l) ..."</tt>) but makes GHC HEAD panic:
</p>
<pre class="wiki">$ ghc-7.3.20110713 Overlap.hs
[1 of 1] Compiling Overlap ( Overlap.hs, Overlap.o )
ghc: panic! (the 'impossible' happened)
(GHC version 7.3.20110713 for x86_64-unknown-linux):
check_overlap
main:Overlap.HDropClass{tc raS}
main:Overlap.PZero{tc raZ}
(main:Overlap.HMap{tc raN} f{tv adi} [sk] l{tv adk} [sk])
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
</pre><p>
Both versions are built with the devel2 BuildFlavour.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5320#changelog
http://ghc.haskell.org/trac/ghc/ticket/5642
http://ghc.haskell.org/trac/ghc/ticket/5642#5642: Deriving Generic of a big type takes a long time and lots of spaceThu, 17 Nov 2011 01:59:06 GMTbasvandijk<p>
If I load the following module into <tt>ghci</tt> my system will run out of memory after about 15 minutes:
</p>
<pre class="wiki">{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
data BigSum =
C0 | C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9
| C10 | C11 | C12 | C13 | C14 | C15 | C16 | C17 | C18 | C19
| C20 | C21 | C22 | C23 | C24 | C25 | C26 | C27 | C28 | C29
| C30 | C31 | C32 | C33 | C34 | C35 | C36 | C37 | C38 | C39
| C40 | C41 | C42 | C43 | C44 | C45 | C46 | C47 | C48 | C49
| C50 | C51 | C52 | C53 | C54 | C55 | C56 | C57 | C58 | C59
| C60 | C61 | C62 | C63 | C64 | C65 | C66 | C67 | C68 | C69
| C70 | C71 | C72 | C73 | C74 | C75 | C76 | C77 | C78 | C79
| C80 | C81 | C82 | C83 | C84 | C85 | C86 | C87 | C88 | C89
| C90 | C91 | C92 | C93 | C94 | C95 | C96 | C97 | C98 | C99
| C100 | C101 | C102 | C103 | C104 | C105 | C106 | C107 | C108 | C109
| C110 | C111 | C112 | C113 | C114 | C115 | C116 | C117 | C118 | C119
| C120 | C121 | C122 | C123 | C124 | C125 | C126 | C127 | C128 | C129
| C130 | C131 | C132 | C133 | C134 | C135 | C136 | C137 | C138 | C139
| C140 | C141 | C142 | C143 | C144 | C145 | C146 | C147 | C148 | C149
| C150 | C151 | C152 | C153 | C154 | C155 | C156 | C157 | C158 | C159
| C160 | C161 | C162 | C163 | C164 | C165 | C166 | C167 | C168 | C169
| C170 | C171 | C172 | C173 | C174 | C175 | C176 | C177 | C178 | C179
| C180 | C181 | C182 | C183 | C184 | C185 | C186 | C187 | C188 | C189
| C190 | C191 | C192 | C193 | C194 | C195 | C196 | C197 | C198 | C199
| C200 | C201 | C202 | C203 | C204 | C205 | C206 | C207 | C208 | C209
| C210 | C211 | C212 | C213 | C214 | C215 | C216 | C217 | C218 | C219
| C220 | C221 | C222 | C223 | C224 | C225 | C226 | C227 | C228 | C229
| C230 | C231 | C232 | C233 | C234 | C235 | C236 | C237 | C238 | C239
| C240 | C241 | C242 | C243 | C244 | C245 | C246 | C247 | C248 | C249
| C250 | C251 | C252 | C253 | C254 | C255 | C256 | C257 | C258 | C259
| C260 | C261 | C262 | C263 | C264 | C265 | C266 | C267 | C268 | C269
| C270 | C271 | C272 | C273 | C274 | C275 | C276 | C277 | C278 | C279
| C280 | C281 | C282 | C283 | C284 | C285 | C286 | C287 | C288 | C289
| C290 | C291 | C292 | C293 | C294 | C295 | C296 | C297 | C298 | C299
deriving Generic
</pre><p>
Big products have the same problem:
</p>
<pre class="wiki">data BigProduct = C
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
deriving Generic
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/5642#changelog
http://ghc.haskell.org/trac/ghc/ticket/5927
http://ghc.haskell.org/trac/ghc/ticket/5927#5927: A type-level "implies" constraint on ConstraintsSun, 11 Mar 2012 16:55:32 GMTillissius<p>
I have a datatype:
</p>
<pre class="wiki">data Exists c where Exists :: c a => a -> Exists c
</pre><p>
I have an instance for it:
</p>
<pre class="wiki">instance Show (Exists Show) where
show (Exists a) = show a
</pre><p>
And that's alright, as far as it goes: any Exists Show can indeed itself be shown. But I want more. I want to be able to say:
</p>
<pre class="wiki">instance (c `Implies` Show) => Show (Exists c) where
show (Exists a) = show a
</pre><p>
In other words, I want to be able to say that any (Exists c) where the constraint c implies Show can be shown. For example, if Num still had a Show constraint, I wouldn't want to have to write a separate instance Show (Exists Num) to be able to show an Exists Num; I would want to be able to write a single instance (along the lines of the above) which works for both.
</p>
<p>
GHC clearly has this information: it lets me use a function of type <tt>forall a. Eq a => a -> r</tt> as one of type <tt>forall a. Ord a => a -> r</tt>, but not vice versa, so it knows that Ord implies Eq, but not vice versa. I've attached a file which demonstrates this and a couple of other examples.
</p>
<p>
What's not completely clear to me is what would be the appropriate way to be able to ask it about this. An Implies constraint to parallel the (~) constraint would work, but with what syntax? (Just straightforwardly call it Implies?) And what semantics -- what would be the kind of Implies? It's notable that in the above example its arguments aren't of type Constraint, but rather * -> Constraint, and for (* -> *) -> Constraint it could similarly work, and with MPTCs * -> * -> Constraint and (* -> *) -> (* -> *) -> Constraint and * -> (* -> *) -> Constraint and so on probably also make sense... but I have no idea how to formalize this, where the boundaries lie, and whether it makes any kind of sense. I can try to think harder about it if that would help, but hopefully the outlines of the situation are more immediately obvious to someone on the GHC team.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5927#changelog
http://ghc.haskell.org/trac/ghc/ticket/6018
http://ghc.haskell.org/trac/ghc/ticket/6018#6018: Injective type familiesWed, 18 Apr 2012 16:22:24 GMTlunaris<p>
Injective type families have been discussed several times on the mailing list and identified as a potentially useful feature.
</p>
<p>
I've naively attempted a proof-of-concept in GHC. It's almost certainly incorrect and probably breaks the type system, but I thought it best to put it here and see if it can be made workable.
</p>
<p>
In summary, my changes are:
</p>
<ul><li>Add a new keyword, <tt>injective</tt>, which is available only when the <tt>TypeFamilies</tt> extension is enabled. Injective families may then be defined thus:
</li></ul><pre class="wiki"> injective family F a :: *
type instance F Int = Bool
type instance F Bool = Int
injective family G a :: *
type instance G a = a
</pre><blockquote>
<p>
Syntax is of course completely changeable; I've simply picked one of the possible designs. Hopefully this won't be subjected to too much bike-shedding.
</p>
</blockquote>
<ul><li>Add the constructor <tt>InjFamilyTyCon</tt> to <tt>TyConRhs</tt> and the family flavour <tt>InjectiveFamily</tt> to <tt>HsSyn</tt>. Again, I've opted to encode injectivity as a flavour rather than (say) a <tt>Bool</tt> attached to type families. This is a completely arbitrary choice and may be utterly stupid.
</li></ul><ul><li>Altered the definition of decomposable <tt>TyCon</tt>s to include injective families (<tt>isDecomposableTyCon</tt>). This effectively introduces a typing rule that says if we have <tt>(F a ~ F b)</tt> then we can deduce <tt>(a ~ b)</tt> (<tt>TcCanonical</tt>).
</li></ul><ul><li>Modified the unifier so that it will attempt to replace saturated injective families with their left-hand sides where possible (<tt>TcUnify</tt>). This means that in a function such as:
</li></ul><pre class="wiki"> f :: F a -> F a
f = ...
</pre><blockquote>
<p>
The type of <tt>f False</tt> is inferred as <tt>F Int</tt> (i.e., <tt>a</tt> is no longer ambiguous).
</p>
</blockquote>
<p>
Some things work, some things don't. For example, the attached file typechecks, but if I actually try to evaluate <tt>f False</tt> I get nothing (not even a Segmentation fault).
</p>
<p>
See what you think.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/6018#changelog
http://ghc.haskell.org/trac/ghc/ticket/8012
http://ghc.haskell.org/trac/ghc/ticket/8012#8012: Warn when using Enum instance for Float or DoubleTue, 25 Jun 2013 06:43:17 GMTgidyn<p>
The Enum instances for Float and Double have dubious semantics which cause endless confusion, e.g.
<a class="ext-link" href="http://stackoverflow.com/questions/13203471/the-math-behind-1-0999999999999999-in-haskell"><span class="icon"></span>http://stackoverflow.com/questions/13203471/the-math-behind-1-0999999999999999-in-haskell</a>,
<a class="ext-link" href="http://stackoverflow.com/questions/9810002/floating-point-list-generator"><span class="icon"></span>http://stackoverflow.com/questions/9810002/floating-point-list-generator</a>,
<a class="ext-link" href="http://stackoverflow.com/questions/7290438/haskell-ranges-and-floats"><span class="icon"></span>http://stackoverflow.com/questions/7290438/haskell-ranges-and-floats</a>,
<a class="ext-link" href="http://stackoverflow.com/questions/10328435/how-to-solve-floating-point-number-getting-wrong-in-list-haskell"><span class="icon"></span>http://stackoverflow.com/questions/10328435/how-to-solve-floating-point-number-getting-wrong-in-list-haskell</a>,
and many more.
</p>
<p>
It is therefore proposed that the usage of an Enum instance for Float or Double generate a compiler warning, such as "The Enum instance for Float is subject to rounding errors".
</p>
<p>
A discussion of this on <a class="ext-link" href="http://haskell.1045720.n5.nabble.com/Proposal-Warn-when-using-Enum-instance-of-Float-or-Double-td5731620.html"><span class="icon"></span>the libraries list</a> suggested that such a warning would be desired, although the discussion mostly focused on whether the libraries list is an appropriate place for this discussion.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8012#changelog
http://ghc.haskell.org/trac/ghc/ticket/8086
http://ghc.haskell.org/trac/ghc/ticket/8086#8086: Minimal install for GHCTue, 23 Jul 2013 12:42:21 GMTgidyn<p>
Installing GHC on a shared server requires a minimal footprint, without GHCi, profiling, debugging, documentation, or anything else not needed for regular building and installing. And anything stripable should be striped, if it isn't already.
</p>
<p>
It would be great if the configuration script would support a --minimal option.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8086#changelog
http://ghc.haskell.org/trac/ghc/ticket/8244
http://ghc.haskell.org/trac/ghc/ticket/8244#8244: Removing the Cabal dependencyFri, 06 Sep 2013 15:17:10 GMTnh2<p>
GHC depends on cabal, which is so far has been problematic many times, for many reasons.
</p>
<p>
A few discussions include:
</p>
<ul><li><a class="ext-link" href="http://www.haskell.org/pipermail/haskell-cafe/2013-September/108746.html"><span class="icon"></span>http://www.haskell.org/pipermail/haskell-cafe/2013-September/108746.html</a>
</li><li><a class="ext-link" href="http://www.haskell.org/pipermail/ghc-devs/2013-March/000821.html"><span class="icon"></span>http://www.haskell.org/pipermail/ghc-devs/2013-March/000821.html</a>
</li></ul><p>
GHC uses only a very small part of Cabal, in these files:
</p>
<pre class="wiki">./compiler/ghci/Linker.lhs
./compiler/main/Packages.lhs
./compiler/main/PackageConfig.hs
./compiler/main/Finder.lhs
</pre><p>
plus 1 file for ghc-pkg: ./utils/ghc-pkg/Main.hs (see <a class="ext-link" href="http://www.haskell.org/pipermail/haskell-cafe/2013-September/108750.html"><span class="icon"></span>http://www.haskell.org/pipermail/haskell-cafe/2013-September/108750.html</a> for details).
</p>
<p>
It was proposed that either
</p>
<ul><li>the package format could be a plain specification without direct code dependencies
</li><li>the Cabal package could be split off into Cabal-the-build-system and a minimal part to describe the package DB to be shared by Cabal and GHC
</li></ul><p>
The Cabal part that is used is in only a few modules of Distribution.* while the remaining majority of the Cabal-the-library package is not used (e.g. none of Distribution.Simple.*).
</p>
<p>
Decoupling GHC and Cabal seems to be a public desire, yet there are some problems with these approaches. Let us discuss them in this ticket.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8244#changelog
http://ghc.haskell.org/trac/ghc/ticket/8279
http://ghc.haskell.org/trac/ghc/ticket/8279#8279: bad alignment in code gen yields substantial perf issueThu, 12 Sep 2013 20:20:21 GMTcarter<p>
independently, a number of folks have noticed that in various ways, GHC currently has quite a few different memory alignment related performance problems that can have >= 10% perf impact!
</p>
<p>
Nicolas Frisby notes
</p>
<pre class="wiki">On my laptop, a program showed a consistent slowdown with -fdicts-strict
I didn't find any obvious causes in the Core differences, so I turned to Intel's
Performance Counter Monitor for measurements. After trying a few counters, I eventually
saw that there are about an order of magnitude more misaligned memory loads with
-fdicts-strict than without, so I think that may be a significant part of the slowdown.
I'm not sure if these are code or data reads.
Can anyone suggest how to validate this hypothesis about misaligned reads?
A subsequent commit has changed the behavior I was seeing, so I'm not interested
in alternatives means to determine if -fdicts-strict is somehow at fault — I'm just
asking specifically about data/code memory alignment in GHC and how to
diagnose/experiment with it.
</pre><p>
Reid Barton has independently noted
</p>
<pre class="wiki">
so I did a nofib run with llvm libraries, ghc quickbuild
so there's this really simple benchmark tak,
https://github.com/ghc/nofib/blob/master/imaginary/tak/Main.hs
it doesn't use any libraries at all in the main loop because the Ints all get unboxed
but it's still 8% slower with quick-llvm (vs -fasm)
weird right?
[14:36:30] <carter> could you post the asm it generates for that function?
[14:36:49] <rwbarton> well it's identical between the two versions
<rwbarton> but they get linked at different offsets because some llvm sections are different sizes
<rwbarton> if I add a 128-byte symbol to the .text section to move it to the same address... then the llvm libs version is just as fast
<rwbarton> well, apparently 404000 is good and 403f70 is bad
<rwbarton> I guess I can test other alignments easily enough
<rwbarton> I imagine it wants to start on a cache line
<rwbarton> but I don't know if it's just a coincidence that it worked with the ncg libraries
<rwbarton> that it got a good location
<rwbarton> for this program every 32-byte aligned address is 10+% faster than any merely 16-byte aligned address
<rwbarton> and by alignment I mean alignment of the start of the Haskell code section
<carter> haswell, sandybridge, ivy bridge, other?
<rwbarton> dunno
<rwbarton> I have similar results on Intel(R) Core(TM)2 Duo CPU T7300 @ 2.00GHz
<rwbarton> and on Quad-Core AMD Opteron(tm) Processor 2374 HE
<carter> ok
<rwbarton> trying a patch now that aligns all *_entry symbols to 32 bytes
</pre><p>
the key point in there is that on the tak benchmark, better alignment for the code made a 10% perf differnce on TAk on Core2 and opteron cpus!
</p>
<p>
benjamin scarlet and Luite are speculating that this may be further induced by Tables next to code (TNC) accidentally creating bad alignment so theres cache line pollution / conflicts between the L1 Instruction-cache and data-caches.
So one experiment would be to have the TNC transform pad after the table so the function entry point starts on the next cacheline?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8279#changelog
http://ghc.haskell.org/trac/ghc/ticket/8287
http://ghc.haskell.org/trac/ghc/ticket/8287#8287: exploring calling convention changes and related engineering for 7.10Fri, 13 Sep 2013 21:47:50 GMTcarter<p>
I'm creating this as a master ticket for systematically exploring and benchmarking (possibly breaking) changes to the GHC calling convention. This work will initially focus on x86/x86_64, but may have larger scope.
</p>
<p>
Goals:
</p>
<ol><li>if possible, improve performance systematically for code run on recent CPU micro architecture generations (eg sandybridge, haswell, and future extensions like Knights Landing and Skylake), ideally without pessimizing code on other or older x86_64 micro-architectures
</li></ol><ol start="2"><li>Try to bring native and llvm codegens closer to feature parity (or at the very least, do not widen their capability gap)
</li></ol><ol start="3"><li>a few other pieces too, will amend this ticket as ideas / plans clarify
</li></ol>Resultshttp://ghc.haskell.org/trac/ghc/ticket/8287#changelog
http://ghc.haskell.org/trac/ghc/ticket/8731
http://ghc.haskell.org/trac/ghc/ticket/8731#8731: long compilation time for module with large data type and partial record selectorsMon, 03 Feb 2014 23:44:33 GMTcarter<p>
in both ghc 7.6 and 7.8rc, the Constants module in LLVM-General-Pure (and a few other similar modules) have surprisingly long (and noticable!) compilation times.
</p>
<p>
This seems to related to how GHC handles a many constructor data type with overlapping field names.
</p>
<p>
the time is nearly the same for building a static module with O1 and O2
</p>
<pre class="wiki">carter repoScratcher/bad-ast » time ghc Constant.hs -O2 1 ↵
[1 of 1] Compiling Constant ( Constant.hs, Constant.o )
ghc Constant.hs -O2 7.52s user 0.23s system 99% cpu 7.755 total
</pre><pre class="wiki">carter repoScratcher/bad-ast » time ghc Constant.hs -O1
[1 of 1] Compiling Constant ( Constant.hs, Constant.o )
ghc Constant.hs -O1 6.62s user 0.20s system 100% cpu 6.768 total
</pre><p>
heck even with -O0 its slow (though not terrible)
</p>
<pre class="wiki">carter repoScratcher/bad-ast » time ghc Constant.hs -O0
[1 of 1] Compiling Constant ( Constant.hs, Constant.o )
ghc Constant.hs -O0 2.76s user 0.14s system 101% cpu 2.873 total
</pre><p>
Seems like there might something wrong in how we handle data types like this, the complexity need not
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8731#changelog
http://ghc.haskell.org/trac/ghc/ticket/8971
http://ghc.haskell.org/trac/ghc/ticket/8971#8971: Native Code Generator for 7.8 is not as optimized as 7.6.3...Tue, 08 Apr 2014 03:14:36 GMTGordonBGood<p>
The output assembly code is not as optimized for the Windows 32-bit version 7.8.1 RC2 compiler as the Windows 7.6.3 compiler (32-bit) when the option switches are exactly the same although it may not be limited to only the Windows platform; this has a negative impact on execution time for tight loops of about a factor of two times slower.
</p>
<p>
The following code will reproduce the problem:
</p>
<div class="code"><pre><span class="c1">-- GHC_NCG_OptimizationBug.hs</span>
<span class="c1">-- it seems the Haskell GHC 7.8.1 NCG Native Code Generator (NCG) doesn't</span>
<span class="c1">-- optimize as well for (at least) the x86 target as version 7.6.3</span>
<span class="cm">{-# OPTIONS_GHC -O3 -rtsopts -v -dcore-lint -ddump-asm -ddump-to-file -dumpdir . #-}</span> <span class="c1">-- or O2</span>
<span class="kr">import</span> <span class="nn">Data.Bits</span>
<span class="kr">import</span> <span class="nn">Control.Monad.ST</span> <span class="p">(</span><span class="nf">runST</span><span class="p">,</span><span class="kt">ST</span><span class="p">(</span><span class="o">..</span><span class="p">))</span>
<span class="kr">import</span> <span class="nn">Data.Array.Base</span>
<span class="c1">-- Uses a very simple Sieve of Eratosthenes to 2 ^ 18 to prove it.</span>
<span class="nf">accNumPrimes</span> <span class="ow">::</span> <span class="kt">Int</span> <span class="ow">-></span> <span class="kt">Int</span>
<span class="nf">accNumPrimes</span> acc <span class="ow">=</span> acc <span class="p">`</span>seq<span class="p">`</span> runST <span class="o">$</span> <span class="kr">do</span>
<span class="kr">let</span> bfSz <span class="ow">=</span> <span class="p">(</span><span class="mi">256</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">-</span> <span class="mi">3</span><span class="p">)</span> <span class="p">`</span>div<span class="p">`</span> <span class="mi">2</span>
bfLmtWrds <span class="ow">=</span> <span class="p">(</span>bfSz <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">`</span>div<span class="p">`</span> <span class="mi">32</span>
bufw <span class="ow"><-</span> newArray <span class="p">(</span><span class="mi">0</span><span class="p">,</span> bfLmtWrds<span class="p">)</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="ow">::</span> <span class="kt">ST</span> s <span class="p">(</span><span class="kt">STUArray</span> s <span class="kt">Int</span> <span class="kt">Int</span><span class="p">)</span>
<span class="c1">-- to clear the last "uneven" bit(s)</span>
unsafeWrite bufw bfLmtWrds <span class="p">(</span>complement <span class="p">((</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span> <span class="p">`</span>shiftL<span class="p">`</span> <span class="p">(</span>bfSz <span class="o">.&.</span> <span class="mi">31</span><span class="p">)))</span>
bufb <span class="ow"><-</span> <span class="p">(</span>castSTUArray <span class="ow">::</span> <span class="kt">STUArray</span> s <span class="kt">Int</span> <span class="kt">Int</span> <span class="ow">-></span> <span class="kt">ST</span> s <span class="p">(</span><span class="kt">STUArray</span> s <span class="kt">Int</span> <span class="kt">Bool</span><span class="p">))</span> bufw
<span class="kr">let</span> cullp i <span class="ow">=</span>
<span class="kr">let</span> p <span class="ow">=</span> i <span class="o">+</span> i <span class="o">+</span> <span class="mi">3</span> <span class="kr">in</span>
<span class="kr">let</span> s <span class="ow">=</span> <span class="p">(</span>p <span class="o">*</span> p <span class="o">-</span> <span class="mi">3</span><span class="p">)</span> <span class="p">`</span>div<span class="p">`</span> <span class="mi">2</span> <span class="kr">in</span>
<span class="kr">if</span> s <span class="o">></span> bfSz <span class="kr">then</span>
<span class="kr">let</span> count i sm <span class="ow">=</span> <span class="kr">do</span>
sm <span class="p">`</span>seq<span class="p">`</span> <span class="kr">if</span> i <span class="o">></span> bfLmtWrds <span class="kr">then</span> return <span class="p">(</span>acc <span class="o">+</span> sm<span class="p">)</span> <span class="kr">else</span> <span class="kr">do</span>
wd <span class="ow"><-</span> unsafeRead bufw i
count <span class="p">(</span>i <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span>sm <span class="o">+</span> <span class="p">(</span>popCount wd<span class="p">))</span> <span class="kr">in</span>
count <span class="mi">0</span> <span class="mi">1</span> <span class="c1">-- use '1' for the '2' prime not in the array</span>
<span class="kr">else</span> <span class="kr">do</span>
v <span class="ow"><-</span> unsafeRead bufb i
<span class="kr">if</span> v <span class="kr">then</span>
<span class="kr">let</span> cull j <span class="ow">=</span> <span class="kr">do</span> <span class="c1">-- very tight inner loop</span>
<span class="kr">if</span> j <span class="o">></span> bfSz <span class="kr">then</span> cullp <span class="p">(</span>i <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="kr">else</span> <span class="kr">do</span>
unsafeWrite bufb j <span class="kt">False</span>
cull <span class="p">(</span>j <span class="o">+</span> p<span class="p">)</span> <span class="kr">in</span>
cull s
<span class="kr">else</span> cullp <span class="p">(</span>i <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
cullp <span class="mi">0</span>
<span class="nf">main</span> <span class="ow">=</span>
<span class="c1">-- run the program a number of times to get a reasonable time...</span>
<span class="kr">let</span> numloops <span class="ow">=</span> <span class="mi">2000</span> <span class="kr">in</span>
<span class="kr">let</span> loop n acc <span class="ow">=</span>
acc <span class="p">`</span>seq<span class="p">`</span> <span class="kr">if</span> n <span class="o"><=</span> <span class="mi">0</span> <span class="kr">then</span> acc <span class="kr">else</span>
loop <span class="p">(</span>n <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span>accNumPrimes acc<span class="p">)</span> <span class="kr">in</span>
print <span class="o">$</span> loop numloops <span class="mi">0</span>
</pre></div><p>
The above code takes almost twice as long to run when compiled under 7.8.1 RC2 for Windows (32-bit) as it does for the version 7.6.3 compiler (both 32-bit compilers).
</p>
<p>
The -ddump-simpl Core dump is almost identical between the two, which is also evidenced by that using the -fllvm LLVM compiler back end switch for each results in code that runs at about the same speed for each compiler run (which would use the same Core output as used for NCG, right?).
</p>
<p>
Under Windows, the compilation and run for 7.8.1 RC2 goes like this:
</p>
<pre class="wiki">*Main> :! E:\ghc-7.8.0.20140228_32\bin\ghc --make -pgmlo "E:\llvm32\build\Release\bin\opt" -pgmlc "E:\llvm32\build\Release\bin\llc" "GHC_NCG_OptimizationBug.hs"
compile: input file WindowsVsLinuxNCG.hs
Created temporary directory: C:\Users\Gordon\AppData\Local\Temp\ghc15460_0
*** Checking old interface for main:Main:
*** Parser:
*** Renamer/typechecker:
[1 of 1] Compiling Main ( GHC_NCG_OptimizationBug.hs, GHC_NCG_OptimizationBug.o )
*** Desugar:
Result size of Desugar (after optimization)
= {terms: 260, types: 212, coercions: 0}
*** Core Linted result of Desugar (after optimization):
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 213, types: 136, coercions: 52}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 215, types: 148, coercions: 67}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 209, types: 135, coercions: 51}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 209, types: 135, coercions: 42}
*** Core Linted result of Simplifier:
*** Specialise:
Result size of Specialise = {terms: 209, types: 135, coercions: 42}
*** Core Linted result of Specialise:
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = False}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
PAPs = False})
= {terms: 286, types: 185, coercions: 42}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, PAPs = False}):
*** Float inwards:
Result size of Float inwards
= {terms: 286, types: 185, coercions: 42}
*** Core Linted result of Float inwards:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 502, types: 393, coercions: 103}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 428, types: 326, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 420, types: 321, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 420, types: 321, coercions: 29}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 418, types: 318, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 418, types: 318, coercions: 29}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 475, types: 383, coercions: 32}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 444, types: 336, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 444, types: 336, coercions: 9}
*** Core Linted result of Simplifier:
*** Demand analysis:
Result size of Demand analysis
= {terms: 444, types: 336, coercions: 9}
*** Core Linted result of Demand analysis:
*** Worker Wrapper binds:
Result size of Worker Wrapper binds
= {terms: 579, types: 457, coercions: 9}
*** Core Linted result of Worker Wrapper binds:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 510, types: 415, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 420, types: 322, coercions: 9}
*** Core Linted result of Simplifier:
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = True}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
PAPs = True})
= {terms: 426, types: 326, coercions: 9}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, PAPs = True}):
*** Common sub-expression:
Result size of Common sub-expression
= {terms: 424, types: 326, coercions: 9}
*** Core Linted result of Common sub-expression:
*** Float inwards:
Result size of Float inwards
= {terms: 424, types: 326, coercions: 9}
*** Core Linted result of Float inwards:
*** Liberate case:
Result size of Liberate case
= {terms: 1,824, types: 1,259, coercions: 9}
*** Core Linted result of Liberate case:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 608, types: 422, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 604, types: 413, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 604, types: 413, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 604, types: 413, coercions: 9}
*** Core Linted result of Simplifier:
*** SpecConstr:
Result size of SpecConstr = {terms: 708, types: 505, coercions: 9}
*** Core Linted result of SpecConstr:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 702, types: 499, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 608, types: 405, coercions: 9}
*** Core Linted result of Simplifier:
*** Tidy Core:
Result size of Tidy Core = {terms: 608, types: 405, coercions: 9}
*** Core Linted result of Tidy Core:
*** CorePrep:
Result size of CorePrep = {terms: 825, types: 489, coercions: 9}
*** Core Linted result of CorePrep:
*** Stg2Stg:
*** CodeOutput:
*** New CodeGen:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** CPSZ:
*** Assembler:
"E:\ghc-7.8.0.20140228_32\lib/../mingw/bin/gcc.exe" "-U__i686" "-fno-stack-protector" "-DTABLES_NEXT_TO_CODE" "-I." "-x" "assembler-with-cpp" "-c" "C:\Users\Gordon\AppData\Local\Temp\ghc15460_0\ghc15460_2.s" "-o" "GHC_NCG_OptimizationBug.o"
Linking GHC_NCG_OptimizationBug.exe ...
*Main> :! GHC_NCG_OptimizationBug +RTS -s
46000000
32,965,096 bytes allocated in the heap
7,032 bytes copied during GC
41,756 bytes maximum residency (2 sample(s))
19,684 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 61 colls, 0 par 0.00s 0.00s 0.0000s 0.0000s
Gen 1 2 colls, 0 par 0.00s 0.00s 0.0001s 0.0001s
INIT time 0.00s ( 0.00s elapsed)
MUT time 1.73s ( 1.73s elapsed)
GC time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 1.73s ( 1.73s elapsed)
%GC time 0.0% (0.0% elapsed)
Alloc rate 19,006,902 bytes per MUT second
Productivity 100.0% of total user, 100.2% of total elapsed
</pre><p>
whereas under version 7.6.3 goes like this:
</p>
<pre class="wiki">*Main> :! E:\ghc-7.6.3_32\bin\ghc --make -pgmlo "E:\llvm32\build\Release\bin\opt" -pgmlc "E:\llvm32\build\Release\bin\llc" "GHC_NCG_OptimizationBug.hs"
compile: input file GHC_NCG_OptimizationBug.hs
Created temporary directory: C:\Users\Gordon\AppData\Local\Temp\ghc28200_0
*** Checking old interface for main:Main:
*** Parser:
*** Renamer/typechecker:
[1 of 1] Compiling Main ( GHC_NCG_OptimizationBug.hs, GHC_NCG_OptimizationBug.o )
*** Desugar:
Result size of Desugar (after optimization)
= {terms: 247, types: 212, coercions: 0}
*** Core Linted result of Desugar (after optimization):
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 198, types: 132, coercions: 35}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 200, types: 144, coercions: 43}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 194, types: 131, coercions: 57}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 194, types: 131, coercions: 39}
*** Core Linted result of Simplifier:
*** Specialise:
Result size of Specialise = {terms: 194, types: 131, coercions: 39}
*** Core Linted result of Specialise:
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = False}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
PAPs = False})
= {terms: 277, types: 191, coercions: 39}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, PAPs = False}):
*** Float inwards:
Result size of Float inwards
= {terms: 277, types: 191, coercions: 39}
*** Core Linted result of Float inwards:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 514, types: 403, coercions: 103}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 420, types: 317, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 412, types: 312, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 412, types: 312, coercions: 29}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 410, types: 309, coercions: 29}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 410, types: 309, coercions: 29}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 455, types: 364, coercions: 32}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 422, types: 317, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 422, types: 317, coercions: 9}
*** Core Linted result of Simplifier:
*** Demand analysis:
Result size of Demand analysis
= {terms: 422, types: 317, coercions: 9}
*** Core Linted result of Demand analysis:
*** Worker Wrapper binds:
Result size of Worker Wrapper binds
= {terms: 536, types: 427, coercions: 9}
*** Core Linted result of Worker Wrapper binds:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 480, types: 391, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 400, types: 306, coercions: 9}
*** Core Linted result of Simplifier:
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = True}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
PAPs = True})
= {terms: 408, types: 311, coercions: 9}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, PAPs = True}):
*** Common sub-expression:
Result size of Common sub-expression
= {terms: 406, types: 311, coercions: 9}
*** Core Linted result of Common sub-expression:
*** Float inwards:
Result size of Float inwards
= {terms: 406, types: 311, coercions: 9}
*** Core Linted result of Float inwards:
*** Liberate case:
Result size of Liberate case
= {terms: 1,186, types: 824, coercions: 9}
*** Core Linted result of Liberate case:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 585, types: 411, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 569, types: 392, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 569, types: 392, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 569, types: 392, coercions: 9}
*** Core Linted result of Simplifier:
*** SpecConstr:
Result size of SpecConstr = {terms: 746, types: 566, coercions: 9}
*** Core Linted result of SpecConstr:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 739, types: 560, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 762, types: 546, coercions: 9}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 642, types: 402, coercions: 9}
*** Core Linted result of Simplifier:
*** Tidy Core:
Result size of Tidy Core = {terms: 642, types: 402, coercions: 9}
*** Core Linted result of Tidy Core:
writeBinIface: 10 Names
writeBinIface: 34 dict entries
*** CorePrep:
Result size of CorePrep = {terms: 779, types: 483, coercions: 9}
*** Core Linted result of CorePrep:
*** Stg2Stg:
*** CodeOutput:
*** CodeGen:
*** Assembler:
"E:\ghc-7.6.3_32\lib/../mingw/bin/gcc.exe" "-fno-stack-protector" "-Wl,--hash-size=31" "-Wl,--reduce-memory-overheads" "-I." "-c" "C:\Users\Gordon\AppData\Local\Temp\ghc28200_0\ghc28200_0.s" "-o" "GHC_NCG_OptimizationBug.o"
Linking GHC_NCG_OptimizationBug.exe ...
*Main> :! GHC_NCG_OptimizationBug +RTS -s
46000000
32,989,396 bytes allocated in the heap
4,976 bytes copied during GC
41,860 bytes maximum residency (2 sample(s))
19,580 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 61 colls, 0 par 0.00s 0.00s 0.0000s 0.0000s
Gen 1 2 colls, 0 par 0.00s 0.00s 0.0001s 0.0001s
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.64s ( 0.64s elapsed)
GC time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.66s ( 0.64s elapsed)
%GC time 0.0% (0.1% elapsed)
Alloc rate 51,495,642 bytes per MUT second
Productivity 100.0% of total user, 102.3% of total elapsed
</pre><p>
Looking at the ASM dump for the innermost tight culling loop reveals the problem, with 7.8.1 RC2 outputting as follow:
</p>
<pre class="wiki">_n3nx:
movl 76(%esp),%ecx
_c3gf:
cmpl %ecx,%eax
jg _c3jB
_c3jC:
movl %eax,%edx
sarl $5,%edx
movl %ecx,76(%esp)
movl $1,%ecx
movl %ecx,280(%esp)
movl %eax,%ecx
andl $31,%ecx
movl %eax,292(%esp)
movl 280(%esp),%eax
shll %cl,%eax
xorl $-1,%eax
movl 64(%esp),%ecx
addl $8,%ecx
movl (%ecx,%edx,4),%ecx
andl %eax,%ecx
movl 64(%esp),%eax
addl $8,%eax
movl %ecx,(%eax,%edx,4)
movl 292(%esp),%eax
addl $3,%eax
jmp _n3nx
</pre><p>
and 7.6.3 outputting as follows:
</p>
<pre class="wiki">.text
.align 4,0x90
.long 1894
.long 32
s1GZ_info:
_c1YB:
cmpl 16(%ebp),%esi
jg _c1YE
movl %esi,%edx
sarl $5,%edx
movl $1,%eax
movl %esi,%ecx
andl $31,%ecx
shll %cl,%eax
xorl $-1,%eax
movl 12(%ebp),%ecx
movl 8(%ecx,%edx,4),%ecx
andl %eax,%ecx
movl 12(%ebp),%eax
movl %ecx,8(%eax,%edx,4)
addl 4(%ebp),%esi
jmp s1GZ_info
_c1YE:
movl 8(%ebp),%esi
addl $8,%ebp
jmp s1GB_info
</pre><p>
The second code is clearly much more efficient, with the only memory access reading/writing the sieve buffer array and one register reload of the prime value to add to the current position index, whereas the first (7.8.1 RC2) code has three register spills and five register re-loads, almost as if debugging were still turned on.
</p>
<p>
This bug was tested under Windows, but likely applies to other platforms, at least for 32-bit versions but also possibly to others.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8971#changelog
http://ghc.haskell.org/trac/ghc/ticket/9087
http://ghc.haskell.org/trac/ghc/ticket/9087#9087: Executables in the Linux binaries are not strippedWed, 07 May 2014 16:30:54 GMTrefold<p>
The executables inside the GHC binary tarball seem to come with debug information. Stripping it noticeably reduces the binary sizes:
</p>
<pre class="wiki">$ file /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
/path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x6012a4c86cd3f410ca0e59ab4ac872ce740d03c6, not stripped
$ du -sh /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
1,4M /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
$ strip -s /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
$ du -sh /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
1021K /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/ghc
$ du -sh /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/haddock
3,2M /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/haddock
$ strip -s /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/haddock
$ du -sh /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/haddock
2,3M /path/to/ghc-7.8.2/lib/ghc-7.8.2/bin/haddock
</pre><p>
Do we really need to include the debug info for exes?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9087#changelog
http://ghc.haskell.org/trac/ghc/ticket/9113
http://ghc.haskell.org/trac/ghc/ticket/9113#9113: Template Haskell should warn about non-exhaustive pattern matchesThu, 15 May 2014 05:18:50 GMTtvh<p>
When using Typed Template Haskell, There are no warings for non-exhaustive patterns inside the quote.
</p>
<pre class="wiki">{-# LANGUAGE TemplateHaskell #-}
module Foo where
import Language.Haskell.TH.Lib
foo :: Maybe Int -> TExpQ Bool
foo x = [||case x of
Nothing -> False||]
</pre><p>
Instead the warnings appear where the code is spliced.
</p>
<pre class="wiki">{-# LANGUAGE TemplateHaskell #-}
module Bar where
import Foo
x = $$(foo (Just 1))
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9113#changelog
http://ghc.haskell.org/trac/ghc/ticket/9210
http://ghc.haskell.org/trac/ghc/ticket/9210#9210: "overlapping instances" through FunctionalDependenciesMon, 16 Jun 2014 12:52:56 GMTrwbarton<p>
This program prints <tt>("1",2)</tt>, but if you reverse the order of the two instances, it prints <tt>(1,"2")</tt>.
</p>
<pre class="wiki">{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
-- extracted from http://lpaste.net/105656
import Control.Applicative
import Data.Functor.Identity
modify :: ((a -> Identity b) -> s -> Identity t) -> (a -> b) -> (s -> t)
modify l f s = runIdentity (l (Identity . f) s)
class Foo s t a b | a b s -> t where
foo :: Applicative f => (a -> f b) -> s -> f t
instance Foo (x, a) (y, a) x y where
foo f (a,b) = (\fa -> (fa,b)) <$> f a
instance Foo (a, x) (a, y) x y where
foo f (a,b) = (\fb -> (a,fb)) <$> f b
main = print $ modify foo (show :: Int -> String) (1 :: Int, 2 :: Int)
</pre><p>
Note that the two instances involved <tt>Foo (Int, Int) (String, Int) Int String</tt> and <tt>Foo (Int, Int) (Int, String) Int String</tt> are not actually overlapping. But, they have the same <tt>a</tt>, <tt>b</tt>, and <tt>s</tt> fields and it seems that this makes GHC think that either one is equally valid, thanks to the fundep.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9210#changelog
http://ghc.haskell.org/trac/ghc/ticket/9557
http://ghc.haskell.org/trac/ghc/ticket/9557#9557: Deriving instances is slowSat, 06 Sep 2014 13:01:21 GMTFeuerbach<p>
Let's take <a class="ext-link" href="https://raw.githubusercontent.com/haskell-suite/haskell-src-exts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs"><span class="icon"></span>this file</a> (from haskell-src-exts) and build it with -O0. On my machine it takes 55s.
</p>
<p>
If we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.
</p>
<p>
Different classes vary in their compile-time cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.
</p>
<p>
haskell-src-exts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with -O0 by default. It would be nice to get this fixed.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9557#changelog
http://ghc.haskell.org/trac/ghc/ticket/9649
http://ghc.haskell.org/trac/ghc/ticket/9649#9649: symbols should/might be type level lists of charsMon, 29 Sep 2014 17:49:34 GMTibotty<p>
I thought I had seen that feature request in trac but did not find it. Sorry if I am wrong.
</p>
<p>
A simple use case might be a type safe routing framework, e.g.
</p>
<pre class="wiki">get :: Route "/a/:id" $ do
idA <- param :: Param "idA"
...
</pre><p>
I spoke with pedro at hacberlin last weekend and he told me simonp and iavor might tell me where to start looking.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9649#changelog
http://ghc.haskell.org/trac/ghc/ticket/8095
http://ghc.haskell.org/trac/ghc/ticket/8095#8095: TypeFamilies painfully slowSat, 27 Jul 2013 02:54:34 GMTMikeIzbicki<p>
I'm using the TypeFamilies extension to generate types that are quite large. GHC can handle these large types fine when they are created manually, but when type families get involved, GHC's performance dies.
</p>
<p>
Unlike in ticket <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/5321" title="bug: Very slow constraint solving for type families (closed: fixed)">#5321</a>, using tail recursion does not eliminate the problem, and the order of arguments greatly affects compile time.
</p>
<p>
I've attached a file Types.hs that demonstrates the problems. This file generates another Haskell file which has the problems. It takes 3 flags. The first is the size of the type to generate, the second is which type family function to use, and the third is whether to call the type family or just use a manually generated type.
</p>
<p>
Here are my performance results:
</p>
<p>
Using non-tail recursion, I get these results. I have to increase the stack size based on the size of the type I want to generate.
</p>
<pre class="wiki">$ ./Types 200 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m2.973s
$ ./Types 300 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=350
real 0m6.018s
$ ./Types 400 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=450
real 0m9.995s
$ ./Types 500 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=550
real 0m15.645s
</pre><p>
Tail recursion generates much slower compile times for some reason, and I still need to adjust the stack size:
</p>
<pre class="wiki">$ ./Types 200 b a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m16.120s
</pre><p>
Changing the order of arguments to the recursive type family greatly changes the run times:
</p>
<pre class="wiki">$ ./Types 200 c a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m6.095s
</pre><p>
Without the type family, I get MUCH better performance:
</p>
<pre class="wiki">$ ./Types 10000 a d > test.hs && time ghc test.hs > /dev/null
real 0m2.271s
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/8095#changelog
http://ghc.haskell.org/trac/ghc/ticket/8228
http://ghc.haskell.org/trac/ghc/ticket/8228#8228: GHC built under Windows does not generate dyn_hi filesThu, 05 Sep 2013 03:09:12 GMTezyang<p>
I found cabal01 failing with:
</p>
<pre class="wiki">=====> cabal01(normal) 1 of 1 [0, 0, 0]
cd . && $MAKE -s --no-print-directory cabal01 VANILLA=--enable-library-vanilla PROF=--disable-l
ibrary-profiling DYN=--enable-shared </dev/null >cabal01.run.stdout 2>cabal01.run.stderr
Wrong exit code (expected 0 , actual 2 )
Stdout:
Stderr:
Creating library file: dist\build\libHStest-1.0-ghc7.7.20130904.dll.a
setup.exe: Error: Could not find module: A with any suffix: ["dyn_hi"] in the search path: ["dist\\build"]
make[2]: *** [cabal01] Error 1
</pre><p>
but I bet some of the other failures are due to this. Indeed, in dist/build, there are no dyn_hi files
</p>
<p>
When I look more closely at the commands being run, I see:
</p>
<pre class="wiki">bash.exe-3.1$ c:/Users/ezyang/Dev/ghc-validate/inplace/bin/ghc-stage2.exe --make -fbuilding-ca bal-package -O -static -dynamic-too -dynosuf dyn_o -dynhisuf dyn_hi -outputdir dist/build -odi r dist/build -hidir dist/build -stubdir dist/build -i -idist/build -i. -idist/build/autogen -I dist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -package- name test-1.0 -hide-all-packages -no-user-package-db -package-db local.db -package-db dist/pac kage.conf.inplace -package-id base-4.7.0.0-inplace -XHaskell98 -XForeignFunctionInterface A B. A -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db
[1 of 2] Compiling B.A ( B\A.hs, dist\build\B\A.o )
[2 of 2] Compiling A ( A.hs, dist\build\A.o )
</pre><p>
which should result in dyn_hi files but does not. I haven't traced it any further yet.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8228#changelog
http://ghc.haskell.org/trac/ghc/ticket/8736
http://ghc.haskell.org/trac/ghc/ticket/8736#8736: GHCi doesn't load .dyn_o files appropriatelyTue, 04 Feb 2014 23:07:14 GMTthoughtpolice<p>
Now that GHCi generally defaults to dynamic linking, it handles dynamic object files. But it doesn't implicitly handle the <tt>-dynamic-too</tt> case appropriately:
</p>
<pre class="wiki">$ cat Test.hs
main = return ()
$ ./inplace/bin/ghc-stage2 -dynamic Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ ./inplace/bin/ghc-stage2 --interactive Test
GHCi, version 7.8.20140130: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: Main.
Prelude Main> ^D
$ ./inplace/bin/ghc-stage2 -dynamic-too Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ ./inplace/bin/ghc-stage2 --interactive Test
GHCi, version 7.8.20140130: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main>
</pre><p>
Also:
</p>
<pre class="wiki">$ ./inplace/bin/ghc-stage2 --interactive Test.dyn_o
GHCi, version 7.8.20140130: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Warning: ignoring unrecognised input `Test.dyn_o'
Prelude>
</pre><p>
but it does handle the <tt>.o</tt> case. This should all be fixed and merged to 7.8 since it'll likely be very annoying.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8736#changelog