GHC: Ticket Query
http://ghc.haskell.org/trac/ghc/query?status=!closed&type=task&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&type=task&order=priority
Trac 1.0.1
http://ghc.haskell.org/trac/ghc/ticket/8330
http://ghc.haskell.org/trac/ghc/ticket/8330#8330: Remove ExtsCompat46 module once we bootstrap with GHC 7.8Thu, 19 Sep 2013 10:30:41 GMTjstolarek<p>
Changing type signature of comparison primops from <tt>Bool</tt> to <tt>Int#</tt> in GHC 7.8 (see <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/6135" title="feature request: Unboxed Booleans (closed: fixed)">#6135</a>) caused a problem: type signatures of functions might be different for the bootstrapping compiler (if it is older than 7.8) than they are for the stage1 compiler. In order to solve this problem I introduced a compatibility module <a href="/trac/ghc/browser/ghc/compiler/utils/ExtsCompat46">compiler/utils/ExtsCompat46</a> that provides different definition of primops for older versions of GHC (<tt>__GLASGOW_HASKELL__ <= 706</tt>) and different for newer versions (<tt>__GLASGOW_HASKELL__ > 706</tt>). However, once we set minimal version of GHC required for bootstrapping to be 7.8, we can (and should!) remove that compatibility module and go back to using GHC.Exts. This ticket is a reminder that we should do this after we release GHC 7.10 or 7.12.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8330#changelog
http://ghc.haskell.org/trac/ghc/ticket/8440
http://ghc.haskell.org/trac/ghc/ticket/8440#8440: Get rid of the remaining static flagsSat, 12 Oct 2013 06:18:18 GMTthoughtpolice<p>
On the heels of fixing <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8276" title="bug: Building Haddock documentation panics with perf build on x86_64 Linux (new)">#8276</a>, we should get rid of the remaining static flags. For the remaining cases, there's no real reason they should be static, other than changing them is fairly invasive and will require some refactoring.
</p>
<p>
I'm making this a goal for 7.10, since we only have 5 flags left (and a lot of the changes for them are overlapping, so fixing one will probably go a ways towards fixing the others.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8440#changelog
http://ghc.haskell.org/trac/ghc/ticket/8785
http://ghc.haskell.org/trac/ghc/ticket/8785#8785: Replace hooks API in the RTS with something betterFri, 14 Feb 2014 08:40:25 GMTsimonmar<p>
Hooks rely on static linking behaviour which doesn't always work: we have to disable -Bsymbolic for the RTS on Linux (see <tt>compiler/main/SysTools.lhs</tt>) and it apparently doesn't work at all on Mac (<a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8754" title="bug: :set +s always says space usage is 0 bytes (closed: fixed)">#8754</a>).
</p>
<p>
So instead of hooks we should be passing in information when we initialize the RTS, like we already do for some other things (<tt>-rtsopts</tt> etc.).
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8785#changelog
http://ghc.haskell.org/trac/ghc/ticket/9665
http://ghc.haskell.org/trac/ghc/ticket/9665#9665: Add "since" information to LANGUAGE extensions in GHC user guideSat, 04 Oct 2014 18:08:18 GMTandreas.abel<p>
If one wants to support older versions of GHC, it is hard to find out whether one can use a certain LANGUAGE extension. One has to go to older versions of the GHC manual to find out whether the corresponding documentation was already there, or browse release notes. Requests:
</p>
<ol><li>Document for new LANGUAGE extensions that they are available since version 7.10. For example, by adding "(Since GHC 7.10)" to the heading of the new feature.
</li></ol><ol start="2"><li>Do this also for the previous LANGUAGE extensions, by adding e.g., "(Since GHC 7.6)" etc.
</li></ol>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9665#changelog
http://ghc.haskell.org/trac/ghc/ticket/9832
http://ghc.haskell.org/trac/ghc/ticket/9832#9832: Get rid of PERL dependency of `ghc-split`Mon, 24 Nov 2014 16:50:58 GMThvr<p>
The problem:
</p>
<p>
<tt>ghc-split</tt> is a ~280 SLOC (literate) Perl script and it's needed at runtime by GHC. Which means that we depend on a Perl interpreter, and since Windows usually doesn't have one installed by default, we need to bundle a Perl interpreter w/ the GHC binary Windows distribution for convenience.
</p>
<p>
Obvious solutions:
</p>
<ol><li>Rewrite <tt>ghc-split</tt> tool in Haskell, or
</li></ol><ol start="2"><li>Merge <tt>ghc-split</tt> functionality into GHC proper
</li></ol>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9832#changelog
http://ghc.haskell.org/trac/ghc/ticket/10074
http://ghc.haskell.org/trac/ghc/ticket/10074#10074: Implement the 'Improved LLVM Backend' proposalMon, 09 Feb 2015 21:16:14 GMTthoughtpolice<p>
This is a meta ticket designed to reflect the current implementation status of the 'Improved LLVM Backend' proposal, documented here:
</p>
<p>
<a class="ext-link" href="https://ghc.haskell.org/trac/ghc/wiki/ImprovedLLVMBackend"><span class="icon"></span>https://ghc.haskell.org/trac/ghc/wiki/ImprovedLLVMBackend</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/10074#changelog
http://ghc.haskell.org/trac/ghc/ticket/595
http://ghc.haskell.org/trac/ghc/ticket/595#595: Overhaul GHC's overlapping/non-exhaustive pattern checkingWed, 17 Sep 2003 00:00:00 GMTsimonmar<p>
GHC has a module in the desugarer (Check) which checks whether patterns are overlapping and/or exhaustive, to support the flags -fwarn-overlapping-patterns and -fwarn-non-exhaustive-patterns. The code is old and crufty, and has several outstanding bugs. A rewrite is needed.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/595#changelog
http://ghc.haskell.org/trac/ghc/ticket/599
http://ghc.haskell.org/trac/ghc/ticket/599#599: The Front PanelWed, 12 May 2004 00:00:00 GMTsimonmar<p>
GHC's runtime has a "front panel" which displays graphical representations of parts of the runtime as a program runs. For example, it shows the amount of data in each generation, how many threads there are, the memory layout, etc.
</p>
<p>
This was a quick hack, and there are many ways in which it could be extended to become a generally useful tool.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/599#changelog
http://ghc.haskell.org/trac/ghc/ticket/603
http://ghc.haskell.org/trac/ghc/ticket/603#603: GC-spy connectionThu, 01 Jul 2004 00:00:00 GMTsimonmar<p>
Connect GHC's garbage collector to the <a class="ext-link" href="http://research.sun.com/projects/gcspy/"><span class="icon"></span>GC spy tool</a>, which gives a graphical display of heap characteristics at runtime.
</p>
<p>
(Similar to the Front Panel task: <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/599" title="task: The Front Panel (new)">599</a>.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/603#changelog
http://ghc.haskell.org/trac/ghc/ticket/605
http://ghc.haskell.org/trac/ghc/ticket/605#605: Optimisation: strict enumerationsWed, 06 Oct 2004 00:00:00 GMTsimonmar<p>
Strict enumeration types should be implemented by Int#, both in the strictness analyser and for constructor fields annotated with {-# UNPACK #-}.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/605#changelog
http://ghc.haskell.org/trac/ghc/ticket/609
http://ghc.haskell.org/trac/ghc/ticket/609#609: Useful optimisation for set-cost-centreWed, 02 Feb 2005 00:00:00 GMTsimonpj<p>
If you compile, for example, drvrun014 with -prof -auto-all, you'll see stuff like
</p>
<pre class="wiki"> (scc "c" (dataToTag#)) y
</pre><p>
This generates bad code, because we end up eta-expaning dataToTag, which allocates an extra function closure.
</p>
<p>
We think that in general
</p>
<pre class="wiki"> (scc "c" e) y = scc "c" (e y)
</pre><p>
to within a small constant factor. So maybe the simplifier, or <tt>CorePrep</tt>, or both, should do this transformation.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/609#changelog
http://ghc.haskell.org/trac/ghc/ticket/618
http://ghc.haskell.org/trac/ghc/ticket/618#618: Dependency caching in ghc --makeSat, 05 May 2001 00:00:00 GMTsimonmar<p>
ghc --make should cache dependencies between runs, somehow.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/618#changelog
http://ghc.haskell.org/trac/ghc/ticket/624
http://ghc.haskell.org/trac/ghc/ticket/624#624: Program location for thread error messagesSun, 03 Jun 2001 00:00:00 GMTchak<p>
In programs with a substantial number of threads, the error messages like "indefinitely blocked" are not very helpful, because there is no indication as to which thread blocked. Having the source location of the 'fork' or so, would be much more helpful.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/624#changelog
http://ghc.haskell.org/trac/ghc/ticket/634
http://ghc.haskell.org/trac/ghc/ticket/634#634: Implement a more efficient TArrayThu, 15 Dec 2005 14:06:59 GMTanonymous<p>
<tt>Control.Concurrent.STM.TArray</tt> is implemented as an immutable array of TVars. This gives good parallelism, but isn't very efficient if you don't need that parallelism.
</p>
<p>
See: <a class="ext-link" href="http://www.haskell.org//pipermail/haskell-cafe/2005-December/012909.html"><span class="icon"></span>http://www.haskell.org//pipermail/haskell-cafe/2005-December/012909.html</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/634#changelog
http://ghc.haskell.org/trac/ghc/ticket/701
http://ghc.haskell.org/trac/ghc/ticket/701#701: Better CSE optimisationMon, 20 Feb 2006 13:58:05 GMTsimonmar<p>
GHC's CSE optimisation is pretty weedy. It looks for expressions like this:
</p>
<pre class="wiki"> let x = e1 in e2
</pre><p>
and replaces all occurrences of e1 in e2 with x. This doesn't do full CSE, but it does catch some cases. There have been case where full CSE would be significantly beneficial, though.
</p>
<p>
One possible way forward is to have a separate CSE pass that transformed expressions containing common subexpressions into the let-form above, and let the existing CSE pass do the final replacement.
</p>
<p>
We must be cautious, though: increasing sharing can introduce space leaks. Sometimes we can prove that this cannot happen, for example when the shared object is primitive, or has a bounded size.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/701#changelog
http://ghc.haskell.org/trac/ghc/ticket/855
http://ghc.haskell.org/trac/ghc/ticket/855#855: Improvements to SpecConstrWed, 09 Aug 2006 12:10:07 GMTsimonpj<p>
There are a series of possible improvemnts to <a class="wiki" href="http://ghc.haskell.org/trac/ghc/wiki/SpecConstr">SpecConstr</a>, described in
the source code. <tt>compiler/specialise/SpecConstr</tt>
</p>
<ul><li> Specialising for constant parameters
</li><li>Specialising for lambda parameters
</li><li>Two ideas to do with strictness that look more tricky
</li></ul><p>
Some of them look quite straightforward.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/855#changelog
http://ghc.haskell.org/trac/ghc/ticket/888
http://ghc.haskell.org/trac/ghc/ticket/888#888: Implement the static argument transformationMon, 04 Sep 2006 16:37:57 GMTsimonpj<p>
The Static Argument transformation optimises
</p>
<pre class="wiki"> f x y = ....f x' y...
</pre><p>
into
</p>
<pre class="wiki"> f x y = let g x = ....g x'...
in g x
</pre><p>
Instead of passing <tt>y</tt> along unchanged, we make it into a free variable of a local function definition <tt>g</tt>.
</p>
<p>
Unfortunately, it's not always a win. Andre Santos gives a discussion, and quite a few numbers in <a class="ext-link" href="http://research.microsoft.com/%7Esimonpj/Papers/santos-thesis.ps.gz"><span class="icon"></span>his thesis</a>.
</p>
<p>
But sometimes it is a pretty big win. Here's the example that recently motivated me, which Roman Leshchinskiy showed me. You need the attached file Stream.hs, and then try compiling
</p>
<pre class="wiki"> import Stream
foo :: (a -> b) -> [a] -> [c]
foo f = mapL f
</pre><p>
Thus inspired, I think I have a set of criteria that would make the static arg transformation into a guaranteed win:
</p>
<ul><li>there is only one (external) call to the function
</li><li>OR its RHS is small enough to inline
</li><li>OR it is marked INLINE (?)
</li></ul><p>
So I'd like to try this idea out.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/888#changelog
http://ghc.haskell.org/trac/ghc/ticket/932
http://ghc.haskell.org/trac/ghc/ticket/932#932: Improve inliningWed, 11 Oct 2006 09:10:13 GMTsimonpj<p>
Currently the contruct
</p>
<pre class="wiki"> case (x# ># 0#) of ...
</pre><p>
attracts no argument discount for x#, which is silly.
</p>
<p>
The comment in CoreUnfold says:
</p>
<pre class="wiki"> PrimOpId op -> primOpSize op (valArgCount args)
-- foldr addSize (primOpSize op) (map arg_discount args)
-- At one time I tried giving an arg-discount if a primop
-- is applied to one of the function's arguments, but it's
-- not good. At the moment, any unlifted-type arg gets a
-- 'True' for 'yes I'm evald', so we collect the discount even
-- if we know nothing about it. And just having it in a primop
-- doesn't help at all if we don't know something more.
</pre><p>
But the right thing to do seems to be to fix interestingArg in SimplUtils so that it only thinks a primitive-typed thing is interesting if it knows its value (or some structure).
</p>
<p>
Here's the program that triggered this thought:
</p>
<pre class="wiki">import GHC.Word
import GHC.Base
import GHC.Prim
a `shiftRLT` b | b >=# 32# = int2Word# 0#
| otherwise = a `uncheckedShiftRL#` b
(W32# x#) `shift` (I# i#) =
{- we do an actual case analysis on i# to try to give us a discount -}
case i# of
{- For some bizzare reason removing the `shiftRLT` 0# makes the
inlining fail again -}
0# -> W32# (x# `shiftRLT` 0#)
_ ->
if i# >=# 0# then W32# (narrow32Word# (x# `shiftL#` i#))
else W32# (x# `shiftRLT` negateInt# i#)
x `shiftR` y = x `shift` (-y)
shift7 x = x `shiftR` 7
</pre><p>
roconnor@… initiated the thread
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/932#changelog
http://ghc.haskell.org/trac/ghc/ticket/1009
http://ghc.haskell.org/trac/ghc/ticket/1009#1009: GHC Performance IndexFri, 17 Nov 2006 14:11:40 GMTsimonmar<p>
We want a lightweight way to detect when either (a) the compiler's performance changes, or (b) the performance of compiled code changes. This was triggerred by my noticing that the HEAD nightly builds seem somewhat slower than usual right now.
</p>
<p>
So the idea is pretty simple. We decide on a fixed set of nofib programs --intiially all of them, but we want the set to remain stable in the future -- and as part of the nightly build we time how long it takes to compile this set with a fixed set of flags (probably -O -fasm, to rule out changes in gcc). Then we time how long it takes to run all those programs, maybe 5 times each. Then we keep track of these two figures for every successful nightly build, and plot the results, giving us a nice way to track GHC's performance over time. We can go back and get some historical figures too. Of course the results are specific to a particular machine, so we'd have to keep track of results per nightly build machine or something.
</p>
<p>
So basically: some small changes to nofib to allow "just build everything" (I think even NoFibRuns=0 might do this), and to build a fixed set of programs (the set could be built into the nofib build system, no need to make it dynamic). And some way to collect the results and plot graphs.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1009#changelog
http://ghc.haskell.org/trac/ghc/ticket/1349
http://ghc.haskell.org/trac/ghc/ticket/1349#1349: Generalise the ! and UNPACK mechanism for data types, to unpack function argumentsFri, 11 May 2007 12:51:40 GMTsimonpj<p>
See this thread:
</p>
<blockquote>
<p>
<a class="ext-link" href="http://www.nabble.com/More-speed-please!-t3411977.html"><span class="icon"></span>http://www.nabble.com/More-speed-please!-t3411977.html</a>
</p>
</blockquote>
<p>
Briefly the idea is to allow
</p>
<pre class="wiki"> data T = MkT (!Int -> Bool)
</pre><p>
to make a <tt>MkT</tt> hold strict functions only. Anyone unpacking a <tt>MkT</tt> can assume the function is strict; and anyone building a <tt>MkT</tt> gets a strictness wrapper aound whatever function they supply, so even if they supply a lazy function, it's made strict.
</p>
<p>
Seems like a natural generalisation of the existing strictness and UNPACK mechanism for data types.
</p>
<p>
Lots of details in the thread above.
</p>
<p>
Simon
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1349#changelog
http://ghc.haskell.org/trac/ghc/ticket/1371
http://ghc.haskell.org/trac/ghc/ticket/1371#1371: Add -O3Tue, 22 May 2007 08:16:19 GMTsimonmar<p>
It has been suggested that we should have an -O3 that trades off code size for speed. Things that we could do include bumping the threshold for some optimisations (inlining, <a class="wiki" href="http://ghc.haskell.org/trac/ghc/wiki/SpecConstr">SpecConstr</a>, LiberateCase), and perhaps inlining some operations in the back-end.
</p>
<p>
Of course we should measure the effect of various settings on nofib/nobench and pick a good combination.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1371#changelog
http://ghc.haskell.org/trac/ghc/ticket/1405
http://ghc.haskell.org/trac/ghc/ticket/1405#1405: Make ghc (stage1) be compilable by non-GHCFri, 01 Jun 2007 21:04:04 GMTIsaac Dupree<p>
This depends a bit on the existence of a good-enough non-GHC compiler. Possibility to do recursively dependent modules (I think) presently rules out everything except JHC, which is not entirely working yet. Also pattern guards might need to be implemented in that compiler. Maybe for testing, a ghc that doesn't define <span class="underline">GLASGOW_HASKELL</span> (and doesn't use ghc-specific flags ?? possibly a wrapper script of some sort) could be used too.
</p>
<p>
See <a class="ext-link" href="http://thread.gmane.org/gmane.comp.lang.haskell.cvs.ghc/20962"><span class="icon"></span>http://thread.gmane.org/gmane.comp.lang.haskell.cvs.ghc/20962</a> ... GHC also uses things like IORefs, (unsafeCoerce? only in stage2 I think) that everyone provides, but would still be good to document.
</p>
<p>
I'm working on this now, we'll see how far I get --Isaac
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1405#changelog
http://ghc.haskell.org/trac/ghc/ticket/3024
http://ghc.haskell.org/trac/ghc/ticket/3024#3024: Rewrite hp2ps in HaskellThu, 12 Feb 2009 14:52:16 GMTSamB<p>
Right now, hp2ps is written in rather difficult to modify C, and is quite inflexible. We should rewrite it in Haskell and make it, among other things, more tolerant to incomplete records.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3024#changelog
http://ghc.haskell.org/trac/ghc/ticket/3379
http://ghc.haskell.org/trac/ghc/ticket/3379#3379: GHC should use the standard binary packageFri, 17 Jul 2009 23:11:12 GMTigloo<p>
GHC should use the standard binary package, rather than reimplementing its functionality itself. If the current binary package is slower than GHC's Binary, then we should fix that.
</p>
<p>
There's some discussion about this in <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3041" title="feature request: Arch independent binary representations (closed: fixed)">#3041</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3379#changelog
http://ghc.haskell.org/trac/ghc/ticket/3384
http://ghc.haskell.org/trac/ghc/ticket/3384#3384: Add HsSyn prettyprinter testsSun, 19 Jul 2009 20:00:48 GMTigloo<p>
Add HsSyn prettyprinter tests. See <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1966" title="task: Incorrect Outputable instance for InstDecl (closed: fixed)">#1966</a> for some discussion.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3384#changelog
http://ghc.haskell.org/trac/ghc/ticket/3511
http://ghc.haskell.org/trac/ghc/ticket/3511#3511: port GHC to OpenBSD/sparc64 (unregisterised is fine)Mon, 14 Sep 2009 03:00:44 GMTzooko<p>
Folks:
</p>
<p>
I'm a developer of the Tahoe-LAFS open source project (<a class="ext-link" href="http://allmydata.org"><span class="icon"></span>http://allmydata.org</a> ) and we use darcs, and there is a contributor who would like to help us support Tahoe-LAFS on OpenBSD/sparc64 (note: not OpenBSD/sparc). It would be really nice if that contribute could use darcs to get the latest Tahoe-LAFS source code and to contribute patches. But, GHC isn't ported to OpenBSD/sparc64. This ticket is to request the feature of a port of GHC to OpenBSD/sparc64. An unregisterised port would be fine!
</p>
<p>
Thanks!
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3511#changelog
http://ghc.haskell.org/trac/ghc/ticket/4211
http://ghc.haskell.org/trac/ghc/ticket/4211#4211: LLVM: Stack alignment on OSXFri, 23 Jul 2010 13:08:51 GMTdterei<p>
On OSX the ABI requires that the stack is 16 byte aligned when making function calls. (Although this only really needs to be obeyed when making calls that will go through the dynamic linker, so FFI calls). Since the stack is 16 byte aligned at the site of the call, on entry to a function most compilers (both llvm and gcc) expect the stack to now be aligned to 16n - 4, since 4 bytes should have been pushed for the return address as part of the call instruction. GHC though since it uses jumps everywhere keeps that stack at 16 byte aligned on function entrance. This means that LLVM generates incorrect stack alignment code, always off by 4.
</p>
<p>
For the moment I have handled this by using the LLvm Mangler (which is only needed on OS X already for TNTC) to simply correctly fix up the stack alignment code.
</p>
<p>
E.g Asm generated by LLVM:
</p>
<pre class="wiki">_func:
subl $12, %esp
...
call _sin
...
addl $12, %esp
</pre><p>
The mangler will change this to:
</p>
<pre class="wiki">_func:
subl $16, %esp
...
call _sin
...
addl $16, %esp
</pre><p>
The better solution would be to change GHC to keep the stack at 16n - 4 alignment on function. This will require changing the RTS (StgCRun.hs) to set the stack properly before calling into Stg land and also fixing up the NCG to align code properly. There may also be a problem with the C backend as currently all function prolouge and epilouge code is stripped out, which means all the stack manipulation code generated by GCC is removed. This works fine now since the stack is already 16 byte aligned on entry, but if it is now 16n - 4 byte aligned then some stack manipulation will be required.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4211#changelog
http://ghc.haskell.org/trac/ghc/ticket/4243
http://ghc.haskell.org/trac/ghc/ticket/4243#4243: Make a proper options parser for the RTSThu, 05 Aug 2010 00:27:47 GMTigloo<p>
The RTS options parsing is getting increasingly crufty, and the new <tt>rtsOptsEnabled</tt> options have made it even worse. We should really have a proper options parser.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4243#changelog
http://ghc.haskell.org/trac/ghc/ticket/4374
http://ghc.haskell.org/trac/ghc/ticket/4374#4374: Remove in-tree gmpWed, 06 Oct 2010 15:11:57 GMTigloo<p>
We already have the binary GMP DLL for Windows in the GHC tree. We should add the binary GMP dev stuff too, and then get rid of the in-tree GMP source. That would reduce build times, and simplify the build system.
</p>
<p>
I'm assuming installing GMP on other non-Windows OSes is not painful. We probably want to point to a framework for OS X users to use.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4374#changelog
http://ghc.haskell.org/trac/ghc/ticket/4438
http://ghc.haskell.org/trac/ghc/ticket/4438#4438: Rename and register the "PArr" language extension when it is judged to be readyMon, 25 Oct 2010 18:47:06 GMTduncan<p>
Language extensions used in distributed packages need to be registered in <tt>Language.Haskell.Extension</tt> (which currently lives in the Cabal lib).
</p>
<p>
When the DPH hackers think that the <tt>PArr</tt> extension is ready for public consumption then they should register it. It will need to be renamed to something more descriptive, see the <tt>Language.Haskell.Extension</tt> module for examples. The style is to use full words. Perhaps <tt>ParallelArrays</tt> would be an appropriate choice.
</p>
<p>
Currently the <tt>PArr</tt> extension is the only GHC extension that is deliberately not registered (there are others that are accidentally not registered). It is listed as an exception in the testsuite test that checks for GHC extensions that are accidentally not registered. See ticket <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/4437" title="bug: unregistered language extensions (closed: fixed)">#4437</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4438#changelog
http://ghc.haskell.org/trac/ghc/ticket/4941
http://ghc.haskell.org/trac/ghc/ticket/4941#4941: SpecConstr generates functions that do not use their argumentsTue, 01 Feb 2011 11:30:04 GMTsimonpj<p>
Consider this function:
</p>
<pre class="wiki">f :: Int -> (Bool,Bool) -> Bool -> Bool
f 0 x y = y
f n (p,q) y = f (n-1) (p,q) q
</pre><p>
<tt>SpecConstr</tt> does a reasonable job, but ends up with a function like this:
</p>
<pre class="wiki">T4908a.f_$s$wf =
\ (sc_sp4 :: GHC.Prim.Int#)
(sc1_sp5 :: GHC.Types.Bool)
(sc2_sp6 :: GHC.Types.Bool)
(sc3_sp7 :: GHC.Types.Bool) ->
case sc_sp4 of ds_Xom {
__DEFAULT ->
T4908a.f_$s$wf (GHC.Prim.-# ds_Xom 1) sc1_sp5 sc2_sp6 sc2_sp6;
0 -> sc3_sp7
}
</pre><p>
Note that <tt>sc1_sp5</tt> is passed around the loop but never used.
</p>
<p>
I had a quick go at trying to make <tt>SpecConstr</tt> cleverer, but absence info requires a fixpoint analysis, which the existing <tt>ArgOcc</tt> stuff doesn't do. Nor can we rely on absence analysis from earlier in the compiler, because CSE invalidates it.
</p>
<p>
A possibility would be to run strictness/absence analysis again after <tt>SpecConstr</tt>, which would pick this up. I'm not sure what other consequences this would have.
</p>
<p>
So there's an opportunity here, but I'm not sure how much it matters in practice.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/4941#changelog
http://ghc.haskell.org/trac/ghc/ticket/5143
http://ghc.haskell.org/trac/ghc/ticket/5143#5143: Soft heap limit flagWed, 20 Apr 2011 08:33:32 GMTsimonmar<p>
This came up in discussion on IRC yesterday. The <tt>+RTS -M<size></tt> flag does two things:
</p>
<ul><li>it starts tuning the GC to be more frugal as we get closer to <tt><size></tt>, by enabling in-place compaction and making major GC more frequent (reducing <tt>-F</tt> in effect).
</li></ul><ul><li>it stops the system with an out of memory error if memory usages gets too close to <tt><size></tt>
</li></ul><p>
The problem is often you want the first but not the second, because you'd like to say to the RTS "try to use no more than 2GB, because after that we're into swap space", but you don't want the program to fail if the limit is exceeded.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5143#changelog
http://ghc.haskell.org/trac/ghc/ticket/5567
http://ghc.haskell.org/trac/ghc/ticket/5567#5567: LLVM: Improve alias analysis / performanceTue, 18 Oct 2011 18:21:24 GMTdterei<ul><li>LLVM doesn't generate as good as code as we feel it should in many situations
</li><li>Why?
<ul><li>We've often felt its a alias anlysis issue.
</li><li>I'm a little more doubtful of that than others (I feel its part of the bigger problem, not the whole thing).
</li><li>I think there may be some register allocation / instruction selection / live range splitting issue going on.
</li></ul></li><li>We could also do with looking at what optimisation passes we should run and in what order...
</li></ul><p>
Here is some work Max did on the alias issue, his results for nofib weren't good:
</p>
<p>
<a class="ext-link" href="http://blog.omega-prime.co.uk/?p=135"><span class="icon"></span>http://blog.omega-prime.co.uk/?p=135</a>
</p>
<p>
So this ticket is just a high level ticket about figuring out and improving the performance of LLVM backend.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5567#changelog
http://ghc.haskell.org/trac/ghc/ticket/5757
http://ghc.haskell.org/trac/ghc/ticket/5757#5757: zero unexpected failures on all tier 1 platformsMon, 09 Jan 2012 11:32:40 GMTsimonmar<p>
We're often sloppy about this, so I'm making a ticket to ensure we can tag a testsuite that has zero unexpected failures on all tier 1 platforms at release time.
</p>
<p>
That may mean filing more tickets and marking some tests as expected failures.
</p>
<p>
I'll take {x86_64,x86}/Linux.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5757#changelog
http://ghc.haskell.org/trac/ghc/ticket/5791
http://ghc.haskell.org/trac/ghc/ticket/5791#5791: Defer other kinds of errors until runtime, not just type errorsTue, 17 Jan 2012 16:57:05 GMTsimonmar<p>
In <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/5624" title="feature request: Delay Errors Until Runtime (closed: fixed)">#5624</a> we added <tt>-fdefer-type-errors</tt> to turn type errors into warnings. We can do this for other kinds of errors too, notably out-of-scope errors, and there are plenty more errors that can be deferred by replacing the erroneous subexpression by a call to <tt>error</tt>. See also <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1341" title="feature request: allow loading partially correct modules (closed: duplicate)">#1341</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/5791#changelog
http://ghc.haskell.org/trac/ghc/ticket/5793
http://ghc.haskell.org/trac/ghc/ticket/5793#5793: make nofib awesomeWed, 18 Jan 2012 02:03:19 GMTdterei<p>
Nofib is the standard tool GHC developers use to benchmark changes to the compiler. Its overall design is OK but it's had no love and care for many years and has bittrotted such that it isn't useful in a lot of situations.
</p>
<p>
This task is about making nofib useful again.
</p>
<p>
The breakdown for this is something like:
</p>
<ol><li>Think and maybe fix nofib framework design. It has 'ways' which I think correspond to compilation method but more in the sense of 'dynamic' vs 'static', seems it may not suite being able to use ways for 'fasm' vs 'fllvm'. There is also the concept of 'modes' which corresponds to different benchmark input. So 'normal' and 'slow' for getting different run-times. At moment no easy way to select which benchmark groups to run, so may want to change that. I guess we should just decide, what knobs do we want to be able to easily tweak, and see how well the current design allows that.
</li></ol><p>
<strong>Note</strong> there is a shake build system attached that does a lot of this (done by Neil Mitchell!). An explanation of it can be found here: <a class="ext-link" href="http://neilmitchell.blogspot.com/2013/02/a-nofib-build-system-using-shake.html"><span class="icon"></span>http://neilmitchell.blogspot.com/2013/02/a-nofib-build-system-using-shake.html</a>
</p>
<p>
The design discussion of it is mostly lost as it was done on private email sorry.
</p>
<ol start="2"><li>Fixup the runtimes for benchmarks to be significant. This might be best done by changing the way we run benchmarks and collect results to make sure they are meaningful.
</li></ol><p>
E.g., Lots of great discussion and links to papers on this thread
</p>
<p>
<a class="ext-link" href="http://www.haskell.org/pipermail/ghc-devs/2013-February/000307.html"><span class="icon"></span>http://www.haskell.org/pipermail/ghc-devs/2013-February/000307.html</a>
</p>
<ol start="3"><li>Above task is to fix normal but we may want to fixup slow as well and perhaps add a 'fast' mode where benchmarks run in around 1 second.
</li></ol><ol start="4"><li>Maybe add more benchmarks to the suite (text, bytestring, performance regressions from ghc testsuite, vector....)
</li></ol>Resultshttp://ghc.haskell.org/trac/ghc/ticket/5793#changelog
http://ghc.haskell.org/trac/ghc/ticket/6017
http://ghc.haskell.org/trac/ghc/ticket/6017#6017: Reading ./.ghci files raises security issuesWed, 18 Apr 2012 16:13:03 GMTnomeata<p>
GHCi will execute .ghci files in the current directory, and this can be used to run arbitrary shell commands.
</p>
<p>
It seems to me that most people would not expect that running "ghci" in a directory can cause arbitrary commands to be executed. This could be a security issue, e.g. running ghci in a just downloaded software package with a rouge .ghci file.
</p>
<p>
Also it affects invocations "ghc -e", which conceivably could be used in aliases or scripts for some action unrelated to running a ghci session, as in <a class="ext-link" href="http://www.joachim-breitner.de/blog/archives/156-Haskell-on-the-Command-Line.html"><span class="icon"></span>http://www.joachim-breitner.de/blog/archives/156-Haskell-on-the-Command-Line.html</a>
</p>
<p>
I just noticed that it will not read files in directories not owned by you and warn you about it (e.g. in /tmp), which is a good start. But this does not help against files in packaged repositories.
</p>
<p>
Maybe ghci could keep a white-list of files somewhere in ~/.ghci and ask if it should execute a .ghci file that has not been encountered before.
</p>
<p>
Alternatively (and more work) a safe subset of options (such as inclusion paths) could be identified and only those would be allowed in ./.ghci, while ~/.ghci allows all commands.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/6017#changelog
http://ghc.haskell.org/trac/ghc/ticket/7371
http://ghc.haskell.org/trac/ghc/ticket/7371#7371: Supporting old GHC versions in our librariesFri, 26 Oct 2012 14:28:04 GMTigloo<p>
We plan to support building our libraries, wherever possible (in particular, it will not be possible for the wired-in packages), with the same set of GHC versions that we support building GHC with.
</p>
<p>
We need to:
</p>
<ul><li>Write down our supported GHC version policy for libraries in the appropriate place.
</li></ul><ul><li>Make the nightly builders test building the libraries with the bootstrapping compiler, so that regressions are detected.
</li></ul><ul><li>Add dependencies or other constraints to the libraries so that cabal won't try to use a library with an older compiler.
</li></ul>Resultshttp://ghc.haskell.org/trac/ghc/ticket/7371#changelog
http://ghc.haskell.org/trac/ghc/ticket/7608
http://ghc.haskell.org/trac/ghc/ticket/7608#7608: LLVM only handles a hard-coded list of triples.Sat, 19 Jan 2013 03:58:40 GMTsingpolyma<p>
LLVM simply has a hard-coded list of triples for supported platforms in compiler/llvmGen/LlvmCodeGen/Ppr.hs :: moduleLayout.
</p>
<p>
Apparently this information can potentially be sourced by configure / autotools instead. This may be a better way forward rather than adding code for each platform.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/7608#changelog
http://ghc.haskell.org/trac/ghc/ticket/7790
http://ghc.haskell.org/trac/ghc/ticket/7790#7790: Add dummy undefined symbols to indicate waysSun, 24 Mar 2013 08:25:04 GMTezyang<p>
Currently, "way" information is not recorded into object files; it is only recorded into 'hi' files. This means if you are using, say, rts/Linker.c (say, if you're GHCi or a dynamic plugins package), if you mess up and load an object file compiled the wrong way, you will be very sad.
</p>
<p>
I think a cute trick we could play is to define a bunch of dummy symbols per-way, and add them as undefined symbols to objects, to indicate what way they were compiled, e.g. with the <tt>-u</tt> linker flag. Various RTS's export the symbols of ways they support, and attempting to link an object with an incompatible RTS results in a link error.
</p>
<p>
Are there any problems with this scheme? If not, I'll go ahead and implement it.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/7790#changelog
http://ghc.haskell.org/trac/ghc/ticket/7829
http://ghc.haskell.org/trac/ghc/ticket/7829#7829: make better/more robust loopbreaker choicesThu, 11 Apr 2013 18:41:00 GMTnfrisby<p>
The choice of loopbreaker can severely influence downstream compilation. This task ticket is about making the choice more robust/better/"smarter". This ticket is also empty of concrete suggestions how to do so... think of it like a community <span class="wikiextras phrase todo">TODO</span>.
</p>
<p>
One example feature of the current algorithm that seems a bit fragile is the use of two schemes for breaking ties depending on the max "depth" of 2. Peruse the code and its comments and Notes in OccAnal if you're interested.
</p>
<p>
This also ticket serves to document a small regression incurred by my commit <a class="changeset" href="http://ghc.haskell.org/trac/ghc/changeset/af12cf66d1a416a135cb98b86717aba2cd247e1a/ghc" title="ignore RealWorld in size_expr; flag to keep w/w from creating sharing
...">af12cf66d1a416a135cb98b86717aba2cd247e1a</a>. There's a 4% increase in allocation in nofib/rewrite as a result of my change altering the loopbreaker choice.
</p>
<p>
The actual details aren't relevant, but here's the basic story in order to convey the delicacy of loopbreaker choice. My commit slightly reduces the calculated size of a function in a mutually recursive group, so that it comes in under the "never unfold limit" instead of over. This ultimately causes the looperbreaker chooser to break a tie in a different way (there's two "Plans"). The previous choice was more fortuitous: it enabled a beneficial inlining that "misses its chance" with the new choice of loopbreaker.
</p>
<p>
I don't remember nor ever totally understood the details of this last part of the story. I don't have the cycles at the moment to wade into it -dverbose-core2core -ddump-inlings again. Apologies. If a brave soul is interested, you should be able to recover the more fortuitous loopbreaker choice by setting <tt>CoreUnfolding.sizeExpr.isRealWorldId</tt> to <tt>const False</tt>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/7829#changelog
http://ghc.haskell.org/trac/ghc/ticket/7883
http://ghc.haskell.org/trac/ghc/ticket/7883#7883: enable GHC LLVM backend to use LLVM provided CAS / Atomicity primitives?Thu, 02 May 2013 20:38:14 GMTcarter<p>
LLVM provides a number of atomicity / memory ordering primitives.
</p>
<p>
currently the CAS primops exposed at the CMM level are ffi'd inline assembly fun calls. this means that for certain concurrency primops, we've got fun calls within funcalls that could be easily inlined if we did it in a more llvm direct way. A notable example of this is the implementation of <tt> stg_atomicModifyMutVarzh </tt>
</p>
<p>
relevant basic llmv docs are the following
<a class="ext-link" href="http://llvm.org/docs/LangRef.html#cmpxchg-instruction"><span class="icon"></span>Atomic llvm ops</a>
</p>
<p>
<a class="ext-link" href="http://llvm.org/docs/Atomics.html"><span class="icon"></span>semantics of the various ordering levels</a>
</p>
<p>
relevant locations in the ghc source
<a class="ext-link" href="https://github.com/ghc/ghc/blob/master/includes/stg/SMP.h#L170"><span class="icon"></span>CAS inline assembly</a>
</p>
<p>
<a class="ext-link" href="https://github.com/ghc/ghc/blob/master/rts/PrimOps.cmm#L282"><span class="icon"></span>defn of atomicModifyMutVar cmm code</a>
</p>
<p>
Based upon my reading of the relevant GHC cmm code, and reading the semantics of the LLVM operations, the right level of atomic ordering in the generated bit code would be "SequentiallyConsistent".
</p>
<p>
a first step would be to modify the CMM -> LLVM pass to substitute the cas funcall with the right llvm operation. This <strong> SEEMS </strong> like it'd be very very easy to do and low hanging fruit.
</p>
<p>
Theres a few upsides that <strong> might </strong> come out of this.
</p>
<ol><li> would be easy to augment to also provide a doubleCAS primitive, which would be useful in writing various lock free data structures.
</li><li> would increase the portability / ease of retargeting new platforms / hardware via LLVM. (not needing to worry about the target's memory consistency model / write new cases of inline assembly)
</li><li> (this would need benchmarks) could potentially improve the performance of certain heavy concurrency operations by eliminating a funcall in an otherwise tight loop.
</li><li>Theres probably other interesting possible upside, such as perhaps having more of the rts be nicely writeable in CMM? (esp since theres now native funcall support)
</li><li>Also would make the CMM memory model a bit more explicit perhaps?
</li></ol><p>
</p>
<p>
This seems like a *relatively* managable patch to write. I'm up for spending time on this if, should it work, it'd be likely to be merged in.
</p>
<p>
it'd also be a good warm up for a number of other things I want to do, including <a class="ext-link" href="http://hackage.haskell.org/trac/ghc/ticket/5567#comment:10"><span class="icon"></span>http://hackage.haskell.org/trac/ghc/ticket/5567#comment:10</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/7883#changelog
http://ghc.haskell.org/trac/ghc/ticket/7917
http://ghc.haskell.org/trac/ghc/ticket/7917#7917: update documentation of InstalledPackageInfoFri, 17 May 2013 12:07:28 GMTLemming<p>
When writing a binding to a foreign package that does not support pkg-config, it seems to be essential to know what the fields of InstalledPackageInfo precisely mean. I find the current description in section 4.9.8 of the GHC doc too short.
</p>
<p>
What does extra-ghci-libraries mean? It is undocumented.
In which field I should list shared objects? In which field I should enumerate static link libraries? Which libraries are used when compiling with -dynamic option and which ones are used for static linking? Are the library paths used both for static and dynamic link libraries? Which fields affect compilation of included C files? Which fields affect GHCi and which ones affect GHC?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/7917#changelog
http://ghc.haskell.org/trac/ghc/ticket/8050
http://ghc.haskell.org/trac/ghc/ticket/8050#8050: add a required wrapper around plugin installersWed, 10 Jul 2013 17:41:08 GMTnfrisby<p>
While trying to expand <a href="http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/compiler-plugins.html#writing-compiler-plugins">the CoreMonad.reinitializeGlobals mechanism</a>, I proposed an alternative that SPJ noted could be more generally useful.
</p>
<p>
The nub of the idea is to require plugins to apply a distinguished function to their installation function. Instead of defining the plugin as
</p>
<pre class="wiki">module APlugin (plugin) where
import GhcPlugins
plugin :: Plugin
plugin = defaultPlugin {installCoreToDos = install}
install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
install = …
</pre><p>
plugins would be defined as
</p>
<pre class="wiki">module APlugin (plugin) where
import GhcPlugins
plugin :: Plugin
plugin = defaultPlugin {installCoreToDos = mkPluginInstaller install}
install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
install = install = …
</pre><p>
The new function <tt>mkPluginInstaller</tt> provides a hook for GHC developers to process the plugin, hidden from the plugin author. For example, it could encapsulate the current <tt>reinitializeGlobals</tt> mechanism.
</p>
<p>
I'm not sure if using an abstract type to enforce that this function is called is necessary, but it's an option.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8050#changelog
http://ghc.haskell.org/trac/ghc/ticket/8079
http://ghc.haskell.org/trac/ghc/ticket/8079#8079: Redo T7919 and TH_spliceE5_prof with a cabal fileSat, 20 Jul 2013 22:47:20 GMTezyang<p>
Right now T7919 fails because the new dynamic-by-default GHC means that Template Haskell must be built with dynamic; of course, GHC isn't clever enough to figure this out. If we Cabalize the test, the example should start building again (and if they don't, well, that's a bug!)
</p>
<p>
TH_spliceE5_prof can also use this treatment.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8079#changelog
http://ghc.haskell.org/trac/ghc/ticket/8096
http://ghc.haskell.org/trac/ghc/ticket/8096#8096: Add fudge-factor for performance tests run on non-validate buildsSat, 27 Jul 2013 05:47:44 GMTezyang<p>
Since I'm not going to get around to this immediately, Trac'ifying for posterity:
</p>
<p>
These tests have been doing better than expected in the nightlies
for some while.
</p>
<pre class="wiki"> Unexpected failures:
perf/compiler T3064 [stat too good] (normal)
perf/compiler T3294 [stat too good] (normal)
perf/compiler T5642 [stat too good] (normal)
perf/haddock haddock.Cabal [stat too good] (normal)
perf/haddock haddock.base [stat too good] (normal)
</pre><p>
Unfortunately, fixing them is not a simple matter of shifting
the ranges up, since the tests only exceed expectations on
a /perf/ build, so on a normal build such as 'quick', these
tests all pass normally.
</p>
<p>
I could bump up the upper bounds so that the builder stops bleating
about them; perhaps we could do something more complicated where the
expected performance depends on what level of optimization GHC was built
with (but I don't know how to implement this.)
</p>
<hr />
<p>
The problem with just widening the bounds to cover 2 different types of
build is that it increases the chance that performance changes won't
actually be noticed by thge person responsible.
</p>
<p>
Having different bounds for different build configurations is a pain,
because (a) the testsuite has to work out which set of bounds to use,
and (b) you now have even more wobbly values to keep up-to-date.
</p>
<p>
I think perhaps the best thing would be to add some sort of (per-test?)
fudge factor for non-validate builds. That way validate will still find
performance regressions, like it does today, but other builds are less
likely to give false positives. (Igloo)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8096#changelog
http://ghc.haskell.org/trac/ghc/ticket/8226
http://ghc.haskell.org/trac/ghc/ticket/8226#8226: Remove the old style -- # Haddock comments.Thu, 05 Sep 2013 01:15:45 GMTFuuzetsu<p>
Haddock 0.x supported -- # style comments for Haddock pragma and while this seems to have been long forgotten and not documented, it's still kicking in the lexer. I think this is a good time to get rid of these all together.
</p>
<p>
Relevant Haddock ticket <a class="ext-link" href="http://trac.haskell.org/haddock/ticket/171"><span class="icon"></span>http://trac.haskell.org/haddock/ticket/171</a>
</p>
<p>
I'll hopefully send in patches removing these from the lexer/parser tomorrow, if all goes well (unless anyone feels eager to do it, then please, you're most welcome to do so!).
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8226#changelog
http://ghc.haskell.org/trac/ghc/ticket/8238
http://ghc.haskell.org/trac/ghc/ticket/8238#8238: Implement unloading of shared librariesFri, 06 Sep 2013 08:29:32 GMTsimonmar<p>
In <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8039" title="task: RTS linker: unloadObj() does not actually unload the code (closed: fixed)">#8039</a> we added support for unloading static objects from the runtime linker, with the GC detecting when there are no references left. We could add this functionality for shared libraries too, using <tt>dl_iterate_phdr</tt>.
</p>
<p>
@heisenbug's comment from <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8039" title="task: RTS linker: unloadObj() does not actually unload the code (closed: fixed)">#8039</a> with the relevant pointers:
</p>
<p>
<a class="ext-link" href="http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries"><span class="icon"></span>Eli Bendersky's article</a> suggests to use the <a class="ext-link" href="http://linux.die.net/man/3/dl_iterate_phdr"><span class="icon"></span>dl_iterate_phdr</a> function for finding information about loaded libraries. Seems to be linux only. There is a <a class="ext-link" href="http://stackoverflow.com/questions/10009043/dl-iterate-phdr-equivalent-on-mac"><span class="icon"></span>workaround on OSX</a>, though, on StackOverflow.
</p>
<p>
And here is how Böhm-Demers-Weiser's GC implement a <a class="ext-link" href="https://github.com/ivmai/bdwgc/blob/master/dyn_load.c#L451"><span class="icon"></span>callback function for dl_iterate_phdr</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8238#changelog
http://ghc.haskell.org/trac/ghc/ticket/8272
http://ghc.haskell.org/trac/ghc/ticket/8272#8272: testing if SpLim=$rbp and Sp=$rsp changed performance at allThu, 12 Sep 2013 05:45:51 GMTcarter<p>
testing if SpLim=$rbp and Sp=$rsp changed performance at all
</p>
<blockquote>
<p>
would need a stack check but then push could be used to spill to the stack
</p>
</blockquote>
<p>
Idea via Nathan Howell.
</p>
<p>
At the very least, the x86 PUSH instruction has a more succinct encoding than MOV.
</p>
<p>
worth hacking out to see if this can measurable shift ghc perf on nofib or not.
</p>
<p>
this would be part of a larger effort to explore ways to improve GHC's calling convention for modern hardware
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8272#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/8290
http://ghc.haskell.org/trac/ghc/ticket/8290#8290: lookupSymbol API is unsafeSat, 14 Sep 2013 04:02:14 GMTezyang<p>
lookupSymbol is one of those functions that looks nice and innocuous on the tin, until you realize actually it doesn't actually do what you want, and seduces you into writing code that doesn't work on Mac OS X. Case in point, this recent test suite commit:
</p>
<pre class="wiki">commit 02d4958903e967b78fc3bbceddc2ce8ce33901c0
Author: Edward Z. Yang <ezyang@mit.edu>
Date: Fri Sep 13 20:52:57 2013 -0700
Properly provide leading underscore when necessary.
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
</pre><p>
Yes, the API is "correct" in some sense, but from a portability sense, we really want the function to add the underscore itself.
</p>
<p>
If we change this particular function, we will probably break most dynamic loading code (including GHC's). We could also add a safe variant of the function. We just need to decide something to do.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8290#changelog
http://ghc.haskell.org/trac/ghc/ticket/8308
http://ghc.haskell.org/trac/ghc/ticket/8308#8308: Resurrect ticky code for counting constructor arityMon, 16 Sep 2013 09:37:56 GMTjstolarek<p>
There is a dead piece of ticky profiling code that computes histograms of data constructor arities (including tuples) and size of vector returns. The function responsible is <tt>bumpHistogram</tt> in <a href="/trac/ghc/browser/ghc/compiler/codeGen/StgCmmTicky.hs">compiler/codeGen/StgCmmTicky.hs</a>, which masks the commented out function <tt>bumpHistogramE</tt>. We can improve ticky profiling by resurrecting this dead code. There are following things that need to be done:
</p>
<ol><li>Replace current no-op <tt>bumpHistogram</tt> with <tt>bumpHistogramE</tt>. Note that current implementation of <tt>bumpHistogramE</tt> computes constructor arity at runtime. This is unnecessary because we know arity at compile time so we can avoid runtime check by doing sth like this:
</li></ol><pre class="wiki">bumpHistogram lbl n = do
let offset = n `min` 8
emit (addToMem cLong
(cmmIndexExpr cLongWidth
(CmmLit (CmmLabel (mkRtsDataLabel lbl)))
(CmmReg (CmmInt (fromIntegral offset) cLongWidth)))
1)
</pre><p>
Note that <tt>mkRtsDataLabel</tt> function does not exist anymore but we should be able to replace that call with <tt>mkCmmDataLabel rtsPackageId lbl</tt> (speculation).
</p>
<ol start="2"><li>We need to declare arrays that will store histogram values. Declarations of variables used for storing ticky statistics are in <a href="/trac/ghc/browser/ghc/includes/stg/Ticky.h">includes/stg/Ticky.h</a>. We also need to initialize the declared array to contain only zeros.
</li></ol><ol start="3"><li>Having declared the arrays we need to fix printing of computed arities. This is done in <a href="/trac/ghc/browser/ghc/rts/Ticky.c">rts/Ticky.c</a>. Note that there is a lot of code that is commented out (<tt>/* krc: comment out some of this stuff temporarily */</tt>) or disabled with <tt>#if FALSE</tt> pragma. We need to resurect *some* of it. There is a <tt>PR_HST</tt> macro for printing one histogram entry. This seems bad. We should probably rework the part of code responsible for printing out results of historgams.
</li></ol><ol start="4"><li>Current code counts arities from 0 to 8. Everything above 8 is put into the same bin as 8. This magical 8 is spread all over the code. We should declare a constant that is visible both in Haskell sources (see <tt>bumpHistogram</tt> in 1.) and RTS files and have all code behave properly depending on that constant - we should have loops instead of statically printing 9 elements of histogram array.
</li></ol><ol start="5"><li>Some ticky functions that count arity histograms are not used. For example <tt>tickyReturnNewCon</tt> should probably be called by <tt>cgConApp</tt> like this:
</li></ol><pre class="wiki"> ; emit =<< fcode_init
; tickyReturnNewCon
; emitReturn [idInfoToAmode idinfo] }
</pre><p>
The above is a an outline, which should be fairly accurate, but unexpected things may show up along the way.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8308#changelog
http://ghc.haskell.org/trac/ghc/ticket/8317
http://ghc.haskell.org/trac/ghc/ticket/8317#8317: Optimize tagToEnum# at Core levelTue, 17 Sep 2013 12:31:49 GMTjstolarek<p>
Old comparison primops that returned Bool were implemented by inserting call to <tt>tagToEnum#</tt> in the code generator. This call to <tt>tagToEnum#</tt> was later optimized away by a special case in the code geenrator (see <a href="/trac/ghc/browser/ghc/compiler/codeGen/StgCmmExpr.hs">compiler/codeGen/StgCmmExpr.hs</a>, Note [case on bool])). Now that we have new comparison primops (see <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/6135" title="feature request: Unboxed Booleans (closed: fixed)">#6135</a>) we no longer insert <tt>tagToEnum#</tt> in the code generator - all uses of <tt>tagToEnum#</tt> come from explicit calls in a source program. But we still have that special case in the code generator to optimize away <tt>tagToEnum#</tt>. We should drop that special case in the code generator and handle scrutinizing of <tt>tagToEnum#</tt> at the Core level by:
</p>
<ol><li>removing call to <tt>tagToEnum#</tt> in the scrutinee
</li><li>adding calls to <tt>dataToTag#</tt> in case branches
</li><li>constant-folding inserted <tt>dataToTag#</tt>
</li></ol><p>
Here is an example. This Haskell code:
</p>
<pre class="wiki">if tagToEnum# (a ># b)
then E1
else E2
</pre><p>
will be translated to this Core:
</p>
<pre class="wiki">case tagToEnum# (a ># b) of
True -> E1
False -> E2
</pre><p>
and optimized like this:
</p>
<pre class="wiki">case a ># b of
dataToTag# True -> E1
dataToTag# False -> E2
</pre><p>
====>
</p>
<pre class="wiki">case a ># b of
1 -> E1
0 -> E2
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/8317#changelog
http://ghc.haskell.org/trac/ghc/ticket/8323
http://ghc.haskell.org/trac/ghc/ticket/8323#8323: explore ways to possibly use more tag bits in x86_64 pointersTue, 17 Sep 2013 21:57:30 GMTcarter<p>
on x86_64, pointers only use 48 bits!
currently we use 3bits for tagging / arity etc info on x86_64, we should explore more uses!
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8323#changelog
http://ghc.haskell.org/trac/ghc/ticket/8326
http://ghc.haskell.org/trac/ghc/ticket/8326#8326: Place heap checks common in case alternatives before the caseWed, 18 Sep 2013 11:58:16 GMTjstolarek<p>
We would like to have functions that check whether an <tt>Int#</tt> is a valid tag to represent <tt>Bool</tt> (see Note [Optimizing isTrue#] in ghc-prim):
</p>
<pre class="wiki">isTrue# :: Int# -> Bool
isTrue# 1# = True
isTrue# _ = False
isFalse# :: Int# -> Bool
isFalse# 0# = True
isFalse# _ = False
</pre><p>
We could use them with comparison primops like this:
</p>
<pre class="wiki">f :: Int# -> Int
f x | isTrue# (x ># 0#) = I# x
| otherwise = -(I# x)
</pre><p>
<tt>isTrue#</tt> is optimized away at the Core level:
</p>
<pre class="wiki">A.f =
\ (x_aqM :: GHC.Prim.Int#) ->
case GHC.Prim.># x_aqM 0 of _ {
__DEFAULT -> GHC.Types.I# (GHC.Prim.negateInt# x_aqM);
1 -> GHC.Types.I# x_aqM
}
</pre><p>
but the code genrator produces very bad Cmm code, because it pushes heap checks into case alternatives:
</p>
<pre class="wiki"> {offset
cFd: // stack check
if ((Sp + -16) < SpLim) goto cFr; else goto cFs;
cFr: // not enough place on the stack, call GC
R2 = R2;
R1 = A.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
cFs: // scrutinize (x ># 0#)
_sEU::I64 = R2;
_sEV::I64 = %MO_S_Gt_W64(R2, 0);
if (_sEV::I64 != 1) goto cFg; else goto cFo;
cFg: // False branch
Hp = Hp + 16;
if (Hp > HpLim) goto cFy; else goto cFx;
cFy: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFf;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFf, args: 8, res: 8, upd: 8;
cFf: // re-do the False branch
_sEU::I64 = I64[Sp + 8];
Sp = Sp + 16;
_sEV::I64 = R1;
goto cFg;
cFx: // RHS of False branch
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = -_sEU::I64;
R1 = Hp - 7;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
cFo: // True branch
Hp = Hp + 16;
if (Hp > HpLim) goto cFv; else goto cFu;
cFv: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFn;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFn, args: 8, res: 8, upd: 8;
cFn: // re-do the True branch
_sEU::I64 = I64[Sp + 8];
Sp = Sp + 16;
_sEV::I64 = R1;
goto cFo;
cFu: // RHS of True branch
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = _sEU::I64;
R1 = Hp - 7;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
</pre><p>
This results in average 2.5% increase in binary size. By contrast, if we use <tt>tagToEnum#</tt> instead of <tt>isTrue#</tt> heap check will be placed before <tt>case</tt> expression and the code will be significantly shorter (this is done by a special case-on-bool optimization in the code generator - see <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8317" title="task: Optimize tagToEnum# at Core level (new)">#8317</a>). What we would like to do here is:
</p>
<ol><li>compile case alternatives without placing heap checks inside them
</li><li>each compiled alternative should return amount of heap it needs to allocate
</li><li>code generator inspects amounts of heap needed by each alternative and either adds heap checks in alternatives or puts a single check before the case expression.
</li></ol><p>
Getting this right might be a bit tricky.
</p>
<ol><li>if all branches allocate some heap then we can just put a common heap check before the case. Note that we must allocate the higgest amount required by any of the alternatives and then alternatives that use less heap must retract the heap pointer accordingly.
</li><li>if we have two alternatives, one of which allocates heap and the other does not, we should place the heap check only in the alternative that allocates the stack. This will solve <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1498" title="bug: Optimisation: eliminate unnecessary heap check in recursive function (new)">#1498</a>.
</li><li>it is not clear to me what to do if we have combination of the above (more than one branch that allocates heap and at least one branch that does not). If we place heap check before the <tt>case</tt> expression we lose optimization of recursive functions and face the problem described in <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1498" title="bug: Optimisation: eliminate unnecessary heap check in recursive function (new)">#1498</a>. If we push heap checks into branches that allocate heap then we get code duplication, i.e. the problem that we're addressing in this ticket. I guess the only way to make correct decission here is to try different aproaches and measure their performance.
</li></ol><p>
This ticket is mentioned <a class="ext-link" href="http://ghc.haskell.org/trac/ghc/wiki/PrimBool#Implementationdetails"><span class="icon"></span>on this wiki page</a> and in the source code in Note [Optimizing isTrue#] in ghc-prim. Once this ticket is resolved we need to update these places accordingly.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8326#changelog
http://ghc.haskell.org/trac/ghc/ticket/8335
http://ghc.haskell.org/trac/ghc/ticket/8335#8335: Create more specialized entries to GCFri, 20 Sep 2013 11:24:55 GMTjstolarek<p>
Consider this Cmm code (taken from <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8326" title="task: Place heap checks common in case alternatives before the case (new)">#8326</a>):
</p>
<pre class="wiki"> {offset
cFd: // stack check
if ((Sp + -16) < SpLim) goto cFr; else goto cFs;
cFr: // not enough place on the stack, call GC
R2 = R2;
R1 = A.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
cFs: // scrutinize (x ># 0#)
_sEU::I64 = R2;
_sEV::I64 = %MO_S_Gt_W64(R2, 0);
if (_sEV::I64 != 1) goto cFg; else goto cFo;
cFg: // False branch
Hp = Hp + 16;
if (Hp > HpLim) goto cFy; else goto cFx;
cFy: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFf;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFf, args: 8, res: 8, upd: 8;
cFf: // re-do the False branch
_sEU::I64 = I64[Sp + 8];
Sp = Sp + 16;
_sEV::I64 = R1;
goto cFg;
cFx: // RHS of False branch
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = -_sEU::I64;
R1 = Hp - 7;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
cFo: // True branch
Hp = Hp + 16;
if (Hp > HpLim) goto cFv; else goto cFu;
cFv: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFn;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFn, args: 8, res: 8, upd: 8;
cFn: // re-do the True branch
_sEU::I64 = I64[Sp + 8];
Sp = Sp + 16;
_sEV::I64 = R1;
goto cFo;
cFu: // RHS of True branch
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = _sEU::I64;
R1 = Hp - 7;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
</pre><p>
We perform two different calls to garbage collection here. Calling GC after making initial stack check obviously can't use any stack, so we pass parameter to GC in regsiters:
</p>
<pre class="wiki">R2 = R2;
R1 = A.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
</pre><p>
But in the calls that are made later on inside the function we do put some parameters on the stack, thus increasing stack usage:
</p>
<pre class="wiki">cFv: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFn;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFn, args: 8, res: 8, upd: 8;
</pre><p>
If we had more specialized entries to GC that would allow us to pass parameters in registers (or in some fixed memory location associated with TCO?) then this function would not require any stack at all. Note that there is a separate issue here - <tt>_sEV</tt> variable is in fact dead and should be eliminated (see <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8327" title="bug: Cmm sinking does not eliminate dead code in loops (new)">#8327</a>).
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8335#changelog
http://ghc.haskell.org/trac/ghc/ticket/8396
http://ghc.haskell.org/trac/ghc/ticket/8396#8396: cleanup / refactor native code gensWed, 02 Oct 2013 03:45:16 GMTcarter<p>
the native code gen could use some cleanup / love.
</p>
<ol><li>Catchup with feature parity of the llvm
<ol class="loweralpha"><li>this includes adding SIMD support on applicable native code gen architectures, starting with x86_64
</li></ol></li><li> make it easier to extend / modify experiment with the native code gen
</li><li>make it easier to add new primops (maybe even a magic inline asm primop?!)
</li><li>other things i'm overlooking right now
</li></ol><p>
this also overlaps with a number of related tickets i've been adding to trac.
</p>
<p>
a more ambitious strategic goal that won't be the initial goal, that simon marlow suggested when i chatted with him at ICFP, is to make the native code gen codebase a sort of "mini-llvm". I think thats a bit ambitious for the near term, but maybe thats the point on the horizon we may want to aim towards.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8396#changelog
http://ghc.haskell.org/trac/ghc/ticket/8405
http://ghc.haskell.org/trac/ghc/ticket/8405#8405: experiment with using function-sections for linking (for smaller libs and executables)Thu, 03 Oct 2013 22:33:49 GMTcarter<p>
currently the only support we have for making small (ish) executables using split objects, which
</p>
<ol><li>is not on by default, for various good reasons
</li></ol><ol start="2"><li>can seriously penalize compile times
</li></ol><ol start="3"><li>in tandem, something like strip is often used, but on some platforms/targets (such as the iOS cross compiler), strip will actually break things
</li></ol><p>
might be worth seriously experimenting with function-sections / gc-sections in the object files we generate.
</p>
<p>
example slide deck on this <a class="ext-link" href="http://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf"><span class="icon"></span>http://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8405#changelog
http://ghc.haskell.org/trac/ghc/ticket/8489
http://ghc.haskell.org/trac/ghc/ticket/8489#8489: clean up dependency and usages handling in interface filesWed, 30 Oct 2013 11:13:24 GMTerrge<p>
While reviewing <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1480" title="feature request: Template Haskell should allow reification of modules (closed: fixed)">#1480</a>, it was found that there are corner cases that are not easy to handle.
</p>
<p>
This task is about fixing TH module reification to reify direct import list, not usages. For this we may need to extend the current <tt>ModIface</tt>.
</p>
<p>
This task also includes cleaning up the comments and code in related areas, to quote simonpj: "we need more precise commentary on the fields of <tt>HscTypes.Dependencies</tt>, <tt>TcRnTypes.ImportAvails</tt>, and <tt>mi_usages</tt> of <tt>ModIface</tt>. For example, I wonder whether the <tt>mi_usages</tt> field could be part of the <tt>Dependencies</tt>".
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8489#changelog
http://ghc.haskell.org/trac/ghc/ticket/8578
http://ghc.haskell.org/trac/ghc/ticket/8578#8578: Improvements to SpinLock implementationSat, 30 Nov 2013 01:32:35 GMTparcs<p>
The SpinLock implementation has a number of deficiencies. Here is a pair of patches that improves its implementation. Let me know what you think.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8578#changelog
http://ghc.haskell.org/trac/ghc/ticket/8594
http://ghc.haskell.org/trac/ghc/ticket/8594#8594: sysctl name "hw.ncpu" (HW_NCPU) is deprecated in Mac OS XWed, 04 Dec 2013 05:18:19 GMTkseo<p>
According to the OS X man page for sysctl(<a class="ext-link" href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html"><span class="icon"></span>https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html</a>), HW_NCPU used by the current implementation of getNumberOfProcessors() is deprecated.
</p>
<p>
Instead, Mac OS X provides the following 4 options:
</p>
<ul><li>hw.physicalcpu: The number of physical processors available in the current power management mode.
</li><li>hw.physicalcpu_max: The maximum number of physical processors that could be available this boot.
</li><li>hw.logicalcpu: The number of logical processors available in the current power management mode.
</li><li>hw.logicalcpu_max: The maximum number of logical processors that could be available this boot.
</li></ul><p>
I am not sure which one fits best to GHC runtime. Any idea? sysconf implementation of getNumberOfProcessors() seems to prefer _SC_NPROCESSORS_ONLN to _SC_NPROCESSORS_CONF when both are defined.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8594#changelog
http://ghc.haskell.org/trac/ghc/ticket/8597
http://ghc.haskell.org/trac/ghc/ticket/8597#8597: Git Hook script to prevent large binary blobs being checked inFri, 06 Dec 2013 10:19:45 GMThvr<p>
It has already occurred in the past in <tt>testsuite.git</tt> repo, that executables were checked in by accident, and caused the Git history to get bloated.
</p>
<p>
In order to avoid such accidents in the future a Git hook script in the style of <a class="ext-link" href="http://stackoverflow.com/questions/20226132/is-there-a-git-hook-which-can-prevent-binary-check-ins"><span class="icon"></span>this</a> might be useful, but taking also into account the size, and/or possibly with a magic safeword to be put in the commit message, to override the check for a single commit, if the author really knows what (s)he's doing.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8597#changelog
http://ghc.haskell.org/trac/ghc/ticket/8598
http://ghc.haskell.org/trac/ghc/ticket/8598#8598: IO hack in demand analyzer gets in the way of CPRFri, 06 Dec 2013 10:54:24 GMTnomeata<p>
After a lot of staring at code and comparing unexpected nofib results I found the following:
</p>
<p>
The IO hack in the demand analyzer (see <tt>dmdAnalAlt</tt> in <tt>StrAnal.lhs</tt> and <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1592" title="bug: Unexpected boxing in generated code (closed: invalid)">#1592</a> for a good discussion) prevents CPR in any function that uses a C call. This is a small example, reduced from the <tt>scaleFloat</tt> method for doubles:
</p>
<pre class="wiki">module Float(fun) where
import GHC.Float (Double(..))
import GHC.Integer (decodeDoubleInteger, encodeDoubleInteger)
fun :: Double -> Double
fun x | isFix = x
| otherwise = case x of
(D# x#) -> case decodeDoubleInteger x# of
(# i, j #) -> D# (encodeDoubleInteger i j)
where
isFix = isDoubleFinite x == 0
foreign import ccall unsafe "isDoubleFinite" isDoubleFinite :: Double -> Int
</pre><p>
Here, <tt>fun</tt> does current not get the CPR property, and the work gets type <tt>GHC.Prim.Double# -> GHC.Types.Double</tt>. Why? Because in core, there will be a
</p>
<pre class="wiki"> case {__pkg_ccall main isDoubleFinite GHC.Prim.Double#
-> GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #)}_dQD
ds_dQA GHC.Prim.realWorld#
of _ [Occ=Dead, Dmd=<L,A>]
{ (# ds_dQC [Dmd=<L,A>, OS=OneShot], ds_dQB [Dmd=<S,1*U>] #) ->
...
</pre><p>
where the case body has <tt>DmdType m {dQz-><L,1*U(U)> dQA-><L,U>}</tt>, but <tt>dmdAnalAlt</tt> detects that this is evaluating a possibly exiting function and throws aways the information using <tt>alt_ty </tt>lubDmdType<tt> topDmdType</tt>.
</p>
<p>
Would it be ok to <tt>lub</tt> only the demand on the free variables, but keep the CPR information?
</p>
<p>
In nofib (if I managed to compare the right results) this does nothing for almost all benchmarks, <tt>-9.2%</tt> of allocations for <tt>mandel</tt> and <tt>+4.9%</tt> for reverse-complement (but these numbers are not obtained very cleanly, and all is happening on top of the better-ho-cardinality branch.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8598#changelog
http://ghc.haskell.org/trac/ghc/ticket/8655
http://ghc.haskell.org/trac/ghc/ticket/8655#8655: Evaluate know-to-terminate-soon thunksMon, 06 Jan 2014 15:32:25 GMTnomeata<p>
I guess I’ll better put my interior monologue in a ticket than on ghc-dev...
</p>
<p>
In order to implement nested CPR (<a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1600" title="task: Optimisation: CPR the results of IO (new)">#1600</a>), I had to enrich the CPR type to keep track of whether something, when entered, will converge for sure. My code does not solve the halting problem, but does only simple stuff, so if something is known to converge, is is very likely to be cheap.
</p>
<p>
Simon suggested to measure the effect of evaluating a let-bound thunk with the known-to-terminate property, as if the body was using it strictly. This tickets tracks this suggestion, and reports progress.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8655#changelog
http://ghc.haskell.org/trac/ghc/ticket/8767
http://ghc.haskell.org/trac/ghc/ticket/8767#8767: Add rules involving `coerce` to the librariesTue, 11 Feb 2014 15:44:41 GMTnomeata<p>
With <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/2110" title="feature request: Rules to eliminate casted id's (closed: fixed)">#2110</a> fixed, we can now add rules like
</p>
<pre class="wiki">{-# RULES "map/coerce" [0] map coerce = coerce #-}
</pre><p>
to the standard libraries. But probably this should happen together or after <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8718" title="task: Add role annotations to base (closed: fixed)">#8718</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8767#changelog
http://ghc.haskell.org/trac/ghc/ticket/8793
http://ghc.haskell.org/trac/ghc/ticket/8793#8793: Improve GHC.Event.IntTable performanceSun, 16 Feb 2014 03:00:17 GMTcdk<p>
The performance of <tt>GHC.Event.IntTable</tt> can be improved. I've managed to get some nice increases across the board. Benchmarking using <tt>criterion</tt> shows:
</p>
<p>
function, % faster than current impl.
<tt>insert</tt>: 4%
<tt>lookup</tt>: 26%
<tt>update</tt>: 11%
<tt>delete</tt>: 5%
</p>
<p>
There is one strange thing I noted. In <tt>updateWith</tt>, there is an inner loop that looks like this:
</p>
<pre class="wiki">data Bucket a = Empty | Bucket Int a (Bucket a)
go _ Empty = (False, Nothing, Empty)
go cont (Bucket key val next)
| key == k = case f val of
Nothing -> (True, Just val, cont next)
Just v -> (False, Just val, cont (Bucket key v next))
| otherwise = go (\x -> cont (Bucket key val x)) next
</pre><p>
which returns a tuple that is immediately consumed like so:
</p>
<pre class="wiki">(delete_occurred, old_val, new_bkt) <- go id ...
when (isJust old_val) $ do
<updateIntTable>
when delete_occurred <decIntTableSize>
return old_val
</pre><p>
I expected that inlining the <tt><updateIntTable></tt> and <tt><decIntTableSize></tt> code blocks directly into <tt>go</tt> would result in better code than creating a tuple and then pattern matching on it afterwards. ie.
</p>
<pre class="wiki">go _ Empty = return Nothing
go cont (Bucket key val next)
| key == k = do
case f val of
Nothing -> <updateIntTable> (cont next) >> <decIntTableSize>
Just v -> <updateIntTable> (cont (Bucket key v next)
return (Just val)
| otherwise = go (\x -> cont (Bucket key val x)) next
</pre><p>
which has the exact same semantics. To my suprise, this code is almost 2x slower! The core generated in both cases is exactly what I'd expect; if anything, the second version seems tighter. I'm not sure why the first version is faster, but perhaps the original author, Bryan O'Sullivan, can shed some light as he used the tupled method in the first version.
</p>
<p>
I'll attach my patch, <tt>criterion</tt>'s html output for the benchmarks as well as the benchmarking code, and the core for the oddity I discussed above.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8793#changelog
http://ghc.haskell.org/trac/ghc/ticket/8842
http://ghc.haskell.org/trac/ghc/ticket/8842#8842: Make sure msys2 builds non emulating binariesTue, 04 Mar 2014 06:15:52 GMTschyler<p>
I came across this in my own project.
</p>
<p>
MSys2 doesn't enter #ifdef blocks which test for _WIN32. Instead, it pretends to be Linux and has a set of headers which emulate things like mmap.
</p>
<p>
These emulation functions are really really slow -- in my personal tests about 10x slower than calling the WINAPI -- so this ticket is just a reminder (it may already be done) for someone to check that MSys2 builds things non-emulated in GHC.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8842#changelog
http://ghc.haskell.org/trac/ghc/ticket/8910
http://ghc.haskell.org/trac/ghc/ticket/8910#8910: cross compiling for x86_64 solaris2Wed, 19 Mar 2014 12:06:11 GMTmaeder<p>
using a "gcc -m64" and a working ghc-7.8.0.20140228-i386-unknown-solaris2 I was able to create a 64Bit ghc-stage2 compiler that can compile a simple hello world program but may create binaries from larger sources that seg-fault. In particular "ghc-stage2 --interactive" seg-faults:
</p>
<pre class="wiki">[Thread debugging using libthread_db enabled]
[New Thread 1 (LWP 1)]
[New LWP 2 ]
[New LWP 3 ]
[New LWP 4 ]
GHCi, version 7.8.0.20140228: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-simple ... linking ... done.
Loading package base ... linking ...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x00000000041ea4c0 in ?? ()
(gdb) bt
#0 0x00000000041ea4c0 in ?? ()
#1 0x000000000369cf92 in resolveObjs ()
#2 0x000000000206de99 in cplU_info ()
#3 0x000000000000000c in ?? ()
#4 0x0000000003d0fe09 in base_GHCziEventziManager_zdLr88clvl8_closure ()
#5 0x0000000000000000 in ?? ()
</pre><p>
The content of my mk/build.mk is just
</p>
<pre class="wiki">INTEGER_LIBRARY = integer-simple
</pre><p>
Creating a binary-dist also worked, but unpacking and "gmake install" failed at first because old-time, haskell98 and haskell2010 libraries were missing due to "CrossCompiling" in ghc.mk and the second time with:
</p>
<pre class="wiki">Reading package info from "rts/dist/package.conf.install" ... done.
"utils/ghc-cabal/dist-install/build/tmp/ghc-cabal-bindist" register libraries/ghc-prim dist-install "/local/home/maeder/haskell/ghc-7.8-x64-static/lib/ghc-7.8.0.20140228/bin/ghc" "/local/home/maeder/haskell/ghc-7.8-x64-static/lib/ghc-7.8.0.20140228/bin/ghc-pkg" "/local/home/maeder/haskell/ghc-7.8-x64-static/lib/ghc-7.8.0.20140228" '' '/local/home/maeder/haskell/ghc-7.8-x64-static' '/local/home/maeder/haskell/ghc-7.8-x64-static/lib/ghc-7.8.0.20140228' '/local/home/maeder/haskell/ghc-7.8-x64-static/share/doc/ghc/html/libraries' NO
ghc-cabal: Bad interface file: dist-install/build/GHC/CString.hi
magic number mismatch: old/corrupt interface file? (wanted 129742, got
33214052)
gmake[1]: *** [install_packages] Fehler 1
</pre><p>
What am I doing wrong for cross compiling? There is also <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8378" title="bug: Cross-compiling from x86_64-unknown-linux-gnu to x86_64-sun-solaris2 with ... (new)">#8378</a> using a different build host. <a class="upstream ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8713" title="bug: Avoid libraries if unneeded (librt, libdl, libpthread) (upstream)">#8713</a> also seem to use x86_64 solaris2 libs.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8910#changelog
http://ghc.haskell.org/trac/ghc/ticket/8992
http://ghc.haskell.org/trac/ghc/ticket/8992#8992: Instructions for using gdb with GHC on WindowsSun, 13 Apr 2014 07:57:15 GMTezyang<p>
gdb remains a useful tool for debugging executables on Windows, but getting it setup can be tricky, since modern gdb requires Python, which means you will end up installing MSYS Python alongside native Python. Unfortunately, MSYS Python doesn't work with the test suite, so one is in the delicate situation where you want your path to have MSYS Python if you're running gdb, but Windows Python if you're running the test suite. While one can work around this with modest annoyance (the easiest thing I've found is to just uninstall gdb/python when I'm not using it), it would be better if we removed this friction in some way.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8992#changelog
http://ghc.haskell.org/trac/ghc/ticket/9133
http://ghc.haskell.org/trac/ghc/ticket/9133#9133: Improve parser error reporting in `ghc-pkg`Wed, 21 May 2014 13:29:13 GMThvr<p>
Here's what I was confronted recently due to a broken sandbox environment:
</p>
<pre class="wiki">$ cabal info parsec
cabal: ghc-pkg: Data.Binary.Get.runGet at position 9583: demandInput: not enough bytes
</pre><p>
The main problem is that this message is not very helpful (other than telling that <tt>ghc-pkg</tt> wasn't able to do something). Duncan told me, that the recent <tt>binary</tt> API now provides better facilities for error reporting. That could be used to improve the UI of <tt>ghc-pkg</tt> when reporting errors.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9133#changelog
http://ghc.haskell.org/trac/ghc/ticket/9218
http://ghc.haskell.org/trac/ghc/ticket/9218#9218: Upgrade the version of MinGW shipped with GHCWed, 18 Jun 2014 23:11:20 GMTkomadori<p>
The Windows binary distribution of GHC incorporates a version of MinGW which has not been updated for several releases and is now out-of-date. It should be upgraded. The previous time this was done appears to correlate with ticket <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3390" title="task: Upgrade the Windows build to use gcc 4.4.0 (closed: fixed)">#3390</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9218#changelog
http://ghc.haskell.org/trac/ghc/ticket/9251
http://ghc.haskell.org/trac/ghc/ticket/9251#9251: ghc does not expose branchless max/min operations as primopsMon, 30 Jun 2014 01:41:48 GMTcarter<p>
It was pointed out in <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/9246" title="bug: GHC generates poor code for repeated uses of min/max (new)">#9246</a> that GHC currently does not expose primops for Max and Min on various unlifted types such as Float# and Double# and Int# and Word#, but that on most modern CPU architectures there is instruction level support for these operations. (Eg, Float# and #Double min and max can be provided on any 64bit x86 system pretty easily )
</p>
<p>
This ticket is to track doing that task. I'll probably do it one of the next two weekends to get back in the GHC hacking groove, or maybe this should be used as a "getting started" ticket for a new contributor?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9251#changelog
http://ghc.haskell.org/trac/ghc/ticket/9276
http://ghc.haskell.org/trac/ghc/ticket/9276#9276: audit ghc floating point support for IEEE (non)complianceSun, 06 Jul 2014 19:45:08 GMTcarter<p>
As best I can determine, ghc has never been closely audited for conformance to IEEE-754 (floating point) standard and currently is a bit far from providing a compliant implementation.
</p>
<p>
This impacts both a number of other tasks i wish to do for ghc <strong>and</strong> much of my own use of haskell is in a floating point heavy workloads, I will do a bit of leg work to:
</p>
<blockquote>
<p>
a) improve test suite support for checking for compliance
b) write some patches to provide portable compliant primops for the operations which need compiler support
c) try to determine how to allow ghc optimizer to be a bit more aggressive in a sound way in the presence of floating point.
</p>
</blockquote>
<p>
(this may grow into a few subtickets, we'll see)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9276#changelog
http://ghc.haskell.org/trac/ghc/ticket/9331
http://ghc.haskell.org/trac/ghc/ticket/9331#9331: Release Cabal 1.22 before GHC 7.10 releaseFri, 18 Jul 2014 17:23:28 GMTezyang<p>
Just a tracking bug so we don't forget.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9331#changelog
http://ghc.haskell.org/trac/ghc/ticket/9506
http://ghc.haskell.org/trac/ghc/ticket/9506#9506: Name libraries (dll/so) separately from linker symbolsSat, 23 Aug 2014 00:38:11 GMTezyang<p>
Tracking ticket so I don't forget. Based on feedback on <tt>#ghc</tt>, it sounds like it would be helpful if library names on the file system only had their full package name, e.g. <tt>libHScontainers_HASH.so</tt> as opposed to the abbreviated package name. Additionally, it seems less necessary to provide the abbreviated package name in linker symbols, since the modules often give a pretty good clue (and the package key can be looked up.) So let's do this, and make things better for users.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9506#changelog
http://ghc.haskell.org/trac/ghc/ticket/9534
http://ghc.haskell.org/trac/ghc/ticket/9534#9534: IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCBSun, 31 Aug 2014 23:18:10 GMTjrp<p>
The attached is an implementation of the floating point accuracy test described in <em>The Baleful Influence of Benchmarks</em> section of <a class="ext-link" href="http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF"><span class="icon"></span>http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF</a>
</p>
<pre class="wiki">Results for Float:
r = 4098.0 produces 12.0 and 12.0 sig. bits
r = 4098.25 fails: root 0.99989897 isn't at least 1 <<<<
r = 4097.004 produces 12.0 and 11.999298 sig. bits
:
Worst accuracy is 11.999298 sig. bits
:
Results for Double:
r = 4098.0 produces Infinity and Infinity sig. bits
r = 4098.25 produces Infinity and 53.0 sig. bits
r = 4097.00390625 produces Infinity and 53.451178091541244 sig. bits
r = 1.6777218e7 produces Infinity and Infinity sig. bits
r = 1.677721825e7 produces Infinity and 75.0 sig. bits
r = 1.6777219e7 produces Infinity and 71.0 sig. bits
r = 9.4906267e7 produces 26.499999994288153 and 26.499999986733027 sig. bits
r = 9.490626725e7 fails: root 0.999999995635551 isn't at least 1 <<<
r = 2.684354505e8 produces 28.0 and 27.999999919383132 sig. bits
r = 2.684354515e8 produces 28.0 and 27.99999993013205 sig. bits
r = 2.68435458e8 produces 28.0 and 28.0 sig. bits
r = 2.6843545825e8 produces 28.0 and 28.00000000268723 sig. bits
r = 2.6843545700000006e8 produces 28.0 and 27.999999989251084 sig. bits
r = 4.294967298e9 produces 32.0 and 32.0 sig. bits
r = 4.29496729825e9 produces 32.0 and 32.00000000016795 sig. bits
Worst accuracy is 26.499999986733027 sig. bits
</pre><p>
This seems to be comparable to a clang version, but seems to be fairly poor in comparison to some other machines, back in the day (1997).
</p>
<p>
<strong>The attached could, possibly be turned into a testsuite test, by removing the QuickCheck tests that are included.</strong>
</p>
<p>
Observations:
</p>
<ul><li>There are a couple of failures (could be the implementation of sqrt or log).
</li><li>signum seems incorrect (signum Nan = -1.0)
</li><li>The prelude should have a copysign function
</li><li>min fails to produce the other argument if one argument is NaN
</li><li>The CFloat and CDouble variants seem to produce the same result as the native Float and Double versions
</li><li>The Haskell coding style could be improved to remove some boilerplate, make the code more idiomatic
</li><li>There may be a better way of entering the test values of r to ensure that they are accurate
</li></ul>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9534#changelog
http://ghc.haskell.org/trac/ghc/ticket/9542
http://ghc.haskell.org/trac/ghc/ticket/9542#9542: GHC-IO-Handle-Text.hPutStr' and writeBlocks look like they need refactoringTue, 02 Sep 2014 14:47:53 GMTdfeuer<p>
The boundary between <tt>writeBlocks</tt> and <tt>hPutStr'</tt> looks badly drawn, with pieces of buffering type on either side. I would also speculate that one or more CRLF-related helper functions may be in order.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9542#changelog
http://ghc.haskell.org/trac/ghc/ticket/9543
http://ghc.haskell.org/trac/ghc/ticket/9543#9543: Testsuite driver: replace "extra_clean" by "git clean -X"Wed, 03 Sep 2014 09:11:37 GMTthomie<p>
When adding a new test that creates extra files, one also has to do some bookkeeping:
</p>
<ol><li>Supply an <tt>extra_clean</tt> argument to the test function in <tt>all.T</tt>.
</li><li>Add an entry in <tt>testsuite/.gitignore</tt>
</li></ol><p>
Step number 1 is often forgotten. Currently there are over 200 uncleaned files and directories left behind in the <tt>testsuite</tt>, after running <tt>validate</tt> and then <tt>make clean</tt> (checked with <tt>git clean -X -d -n | wc -l</tt>).
</p>
<p>
I propose to replace the functionality that <tt>extra_clean</tt> provides, namely to remove these extra files when one calls <tt>make clean</tt>, by doing the equivalent of <tt>git clean -X -d</tt>:
</p>
<pre class="wiki"> -X
Remove only files ignored by Git.
-d
Remove untracked directories in addition to untracked files. ...
</pre><p>
That is: use the information from the <tt>.ignore</tt> files to figure out which files to delete on <tt>make clean</tt>.
</p>
<p>
The advantages of making this change are:
</p>
<ol><li>Less manual bookkeeping, less work, less code
</li><li>A more thorough <tt>make clean</tt>
</li></ol><p>
Implementation detail: we can not just call <tt>git clean</tt> directly, since this should also work when we are not in a git directory (for example a build directory created with <a class="wiki" href="http://ghc.haskell.org/trac/ghc/wiki/Building/Using">lndir</a>).
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9543#changelog
http://ghc.haskell.org/trac/ghc/ticket/9588
http://ghc.haskell.org/trac/ghc/ticket/9588#9588: Add `MonadPlus {IO,Either e}` and `Alternative (Either e)` instancesSat, 13 Sep 2014 13:27:56 GMThvr<p>
The following 3 instances are currently Orphans in <tt>transformers</tt> but shall be defined in <tt>base</tt> instead:
</p>
<div class="code"><pre><span class="kr">instance</span> <span class="kt">MonadPlus</span> <span class="kt">IO</span>
<span class="kr">instance</span> <span class="kt">MonadPlus</span> <span class="p">(</span><span class="kt">Either</span> e<span class="p">)</span>
<span class="kr">instance</span> <span class="kt">Alterantive</span> <span class="p">(</span><span class="kt">Either</span> e<span class="p">)</span>
</pre></div><p>
This proposal by SPJ already passed the CLC back in April and only needs implementing. I'll submit a patch shortly to Phab
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9588#changelog
http://ghc.haskell.org/trac/ghc/ticket/9596
http://ghc.haskell.org/trac/ghc/ticket/9596#9596: Create monoidal category framework for arrow desugarerTue, 16 Sep 2014 03:43:38 GMTspacekitteh<p>
I'm going to put it into a GHC namespace (GHC.Arrows.Experimental, perhaps) and put instances for Arrow and such in there as well. In a later ticket I'll work on the desugarer, converting erverything into SMC combinators rather than Arrow combinators.
</p>
<p>
The basic design is <a class="ext-link" href="http://blog.spacekitteh.moe/posts/new-monoidal-cats.html"><span class="icon"></span>here</a>.
</p>
<p>
The current Arrow story is such a mess that makes it nearly unusable. Hopefully, by breaking it apart and making it more general, it will result in clearer code in both GHC and end-user code.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9596#changelog
http://ghc.haskell.org/trac/ghc/ticket/9674
http://ghc.haskell.org/trac/ghc/ticket/9674#9674: Foldable doesn't have any lawsFri, 10 Oct 2014 17:24:45 GMTdfeuer<p>
The documentation for <tt>Foldable</tt> doesn't list any laws. I don't know exactly what its laws may be, but there are, at least, several implicit in the default method definitions.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9674#changelog
http://ghc.haskell.org/trac/ghc/ticket/9682
http://ghc.haskell.org/trac/ghc/ticket/9682#9682: Implement "Add bifunctor related classes to base"-ProposalSun, 12 Oct 2014 14:46:32 GMThvr<p>
See <a class="ext-link" href="http://www.haskell.org/pipermail/libraries/2014-April/022844.html"><span class="icon"></span>original libraries@ proposal</a> for more details
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9682#changelog
http://ghc.haskell.org/trac/ghc/ticket/9706
http://ghc.haskell.org/trac/ghc/ticket/9706#9706: New block-structured heap organization for 64-bitMon, 20 Oct 2014 06:48:02 GMTezyang<p>
I was having some discussion about GHC's block structured heap with Sergio Benitez and Adam Belay, and during the discussion it was suggested that the way GHC manages the block structured heap is suboptimal when we're on 64-bit architectures.
</p>
<p>
At the moment, we allocate memory from the operating system per-megablock, storing metadata in the very first megablock. We have to do this because, on 32-bit, we can't generally be too picky about what address our memory ends up living. On 64-bits, we have a lot more flexibility.
</p>
<p>
Here is the proposal:
</p>
<ol><li>Statically decide on a maximum heap size in a power of two.
</li><li>Next, probe for some appropriately aligned chunk of available virtual address space for this. On POSIX, we can mmap /dev/null using PROT_NONE and MAP_NORESERVE. On Windows, we can use VirtualAlloc with MEM_RESERVE. (There are few other runtimes which do this trick, including GCC Go.)
</li><li>Divide this region into blocks as before. The maximum heap size is now the megablock size, and the block size is still the same as before. Masking to find the block descriptor works as before.
</li><li>To allocate, we keep track of the high-watermark, and mmap in 1MB pages as they are requested. We also keep track of how much metadata we need, and mmap extra pages to store metadata as necessary.
</li></ol><p>
We still want to request memory from the operating system in conveniently sized chunks, but we can now abolish the notion of a megablock and the megablock allocator, and work purely with block coalescing. Additionally, the recorded heap location means that we can check if a pointer is HEAP_ALLOCED using a mask and equality check, solving <a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/8199" title="feature request: Get rid of HEAP_ALLOCED (new)">#8199</a>.
</p>
<p>
What do people think?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9706#changelog
http://ghc.haskell.org/trac/ghc/ticket/9707
http://ghc.haskell.org/trac/ghc/ticket/9707#9707: (Try to) restructure `base` to allow more use of `AutoDeriveTypeable`Mon, 20 Oct 2014 17:10:59 GMThvr<p>
<a class="closed" href="http://ghc.haskell.org/trac/ghc/ticket/9111#comment:16" title="Comment 16 for Ticket #9111">comment:ticket:9111:16</a> explains that import-cycles containing <tt>Data.Typeable.Internal</tt> (which provides the <tt>Typeable</tt> class <tt>AutoDeriveTypeable</tt> needs to be loaded for being able to operate) inside <tt>base</tt> make it difficult to use <tt>AutoDeriveTypeable</tt>, as well as making it more difficult to de-cycle the <tt>base</tt> import-dependency graph (see also <a class="attachment" href="http://ghc.haskell.org/trac/ghc/attachment/ticket/9707/typeable_deps.png" title="Attachment 'typeable_deps.png' in Ticket #9707">attachment:typeable_deps.png</a><a class="trac-rawlink" href="http://ghc.haskell.org/trac/ghc/raw-attachment/ticket/9707/typeable_deps.png" title="Download"></a>)
</p>
<p>
This ticket is about trying to find a way to restructure <tt>base</tt> in order to allow to define the <tt>Typeable</tt> instances directly at the type's definition site (and thus allow the use of <tt>AutoDeriveTypeable</tt>)
</p>
<p>
Removing cycles in <tt>base</tt> is possibly required to make <a class="wiki" href="http://ghc.haskell.org/trac/ghc/wiki/SplitBase">SplitBase</a> easier
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9707#changelog
http://ghc.haskell.org/trac/ghc/ticket/9710
http://ghc.haskell.org/trac/ghc/ticket/9710#9710: Clean up Trac versionsTue, 21 Oct 2014 16:29:59 GMTgoldfire<p>
The "Version" pull-down menu in Trac has no apparent ordering principle. This should be fixed.
</p>
<p>
Even better, scrap many of the very old versions, as they're unsupported, anyway. Thanks!
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9710#changelog
http://ghc.haskell.org/trac/ghc/ticket/9716
http://ghc.haskell.org/trac/ghc/ticket/9716#9716: The list modules need a bit of post-BBP shakingThu, 23 Oct 2014 15:12:08 GMTdfeuer<p>
We currently have an unfortunately named <tt>Data.List.OldList</tt>, and no terribly clear story to explain it. One concept, due in part to me and in part to Carter:
</p>
<ol><li>Move all the basics needed to implement <tt>instance Foldable []</tt> from <tt>Data.OldList</tt> to <tt>Data.List.Base</tt> (or some similar name).
</li></ol><ol start="2"><li>Move all the "extras" like <tt>inits</tt>, <tt>tails</tt>, and <tt>sort</tt> from <tt>Data.OldList</tt> into <tt>Data.List</tt>.
</li></ol><ol start="3"><li>Delete <tt>Data.OldList</tt>.
</li></ol>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9716#changelog
http://ghc.haskell.org/trac/ghc/ticket/9735
http://ghc.haskell.org/trac/ghc/ticket/9735#9735: Template Haskell for cross compilers (port from GHCJS)Tue, 28 Oct 2014 15:27:55 GMTluite<p>
GHCJS supports Template Haskell by running it outside the compiler's process, with a different implementation of the Quasi type class. This can be done for other cross compilers too, if GHC gets an option to serialize Template Haskell requests and pass them to an external process.
</p>
<p>
Someone started the work on this, but I think he stopped. I still have a document with a step by step plan to build an iOS cross compiler, with pointers to the relevant GHC and GHCJS code.
</p>
<p>
<a class="ext-link" href="https://github.com/ghcjs/ghcjs/wiki/Porting-GHCJS-Template-Haskell-to-GHC"><span class="icon"></span>https://github.com/ghcjs/ghcjs/wiki/Porting-GHCJS-Template-Haskell-to-GHC</a>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9735#changelog
http://ghc.haskell.org/trac/ghc/ticket/9766
http://ghc.haskell.org/trac/ghc/ticket/9766#9766: Use TypeLits in the meta-data encoding of GHC.GenericsTue, 04 Nov 2014 09:18:38 GMTdreixel<p>
This ticket serves to track the task of improving the meta-data representation in GHC.Generics as described in the following wiki page:
</p>
<p>
<a class="ext-link" href="https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Amoreconservativefirstapproachtothisproblem"><span class="icon"></span>https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Amoreconservativefirstapproachtothisproblem</a>
</p>
<p>
I'm working on this in branch <tt>wip/GenericsMetaData</tt>, and I intend to have it in 7.10.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9766#changelog
http://ghc.haskell.org/trac/ghc/ticket/9786
http://ghc.haskell.org/trac/ghc/ticket/9786#9786: Make quot/rem/div/mod with known divisors fastMon, 10 Nov 2014 01:06:31 GMTdfeuer<p>
GHC (with NCG) currently optimizes <tt>Int</tt> division by powers of two, but not by other known divisors. The Intel Optimization Manual section 9.2.4 describes a general technique for replacing division by known, sufficiently small, divisors with multiplication. LLVM appears to go further in some fashion. There's no reason we can't do something similar.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9786#changelog
http://ghc.haskell.org/trac/ghc/ticket/9797
http://ghc.haskell.org/trac/ghc/ticket/9797#9797: Investigate rewriting `>>=` to `*>` or `>>` for appropriate typesWed, 12 Nov 2014 17:24:23 GMTdfeuer<p>
When we see <tt>m >>= (\_ -> n)</tt> with a type that admits an optimized <tt>>></tt> or <tt><$</tt>, we should try to take advantage of that. I don't currently know if this applies to any types under "GHC HQ" control.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9797#changelog
http://ghc.haskell.org/trac/ghc/ticket/9805
http://ghc.haskell.org/trac/ghc/ticket/9805#9805: Use TrieMaps to speed up type class instance lookupMon, 17 Nov 2014 02:23:59 GMTezyang<p>
Currently, type class instance resolution is performed by doing a map lookup by type class, and then linearly matching against every instance. This is not great, and for a while, simonpj has been keen on using the TrieMap data structure in GHC, which has been previously used to implement a map from CoreExprs to various things (e.g. for CSE). What makes this a little tricky is that instance lookup isn't intended to be an exact match: we should unify so-called template variables and provide a substitution; furthermore, there may be multiple matches.
</p>
<p>
After some prototyping, I think we should be able to make this work. The primary refactoring we have to do is *maintain the key associated with an entry in a TrieMap*. Unlike the current uses of TrieMaps, where it's acceptable to lose the underlying key associated with an entry in the TrieMap, we need to know the key when doing unification, because it may be reported in the substitution. There are a few knock-on effects of this:
</p>
<ul><li>We should add a method <tt>foldWithKeyTM :: (Key m -> a -> b -> b) -> m a -> b -> b</tt> to the <tt>TrieMap</tt> type class.
</li><li>We need a variant of <tt>UniqFM</tt> which tracks the original key that was used. I propose we name it <tt>UniqKM</tt> (unique key map). A number of implementations of <tt>TrieMap</tt> need to be adjusted to use this instead of <tt>UniqFM</tt>.
</li><li>Why can't we just represent keyed TrieMaps as <tt>TypeMap (Type, a)</tt>? It might be possible. An insurmountable difficulty would be if we need to know the partial key PRIOR to having finished traversing the TrieMap; however, for the parts of the unification algorithm I've implemented, this does not seem to be the case. The primary actual difficulty is that <tt>Type</tt> uses a named representation, whereas <tt>TypeMap</tt> keys are on-the-fly deBruijn numbered. There would at least be some annoying fiddliness.
</li><li>Reversing the deBruijn numbered key into a <tt>Type</tt> is a bit goofy. Essentially, you need the reverse of the current <tt>CmEnv</tt>: a mapping from de Bruijn levels to the <tt>Var</tt> you've decided to allocate. (I've called this <tt>CfEnv</tt> in my prototype)
</li><li>When we represent a TrieMap binder, we have to put the binder map on the OUTSIDE, as opposed to the inside as it is currently. Otherwise, we can't update the <tt>CfEnv</tt> with the new mapping before making the recursive call to fold-with-key.
</li></ul><p>
I'll attach the standalone Haskell file I used to prototype this, wherein I copy-pasted a lot of Haskell from GHC's source and implemented fuzzy map on a simplified version of <tt>Type</tt>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9805#changelog
http://ghc.haskell.org/trac/ghc/ticket/9837
http://ghc.haskell.org/trac/ghc/ticket/9837#9837: Introduce a logging API to GHCWed, 26 Nov 2014 14:14:13 GMTrodlogic<p>
I don't have a lot of mileage with the code base, but I do see that there is no standard logging API that the various components can use (or there is and it just needs to be used??).
</p>
<p>
At least, I would expect to see a standard API to generate log entries with the following minimal parts:
</p>
<ul><li>timestamp
</li><li>Log level - for example, ERROR, WARN, INFO, DEBUG, TRACE (-v<a class="source" href="http://ghc.haskell.org/trac/ghc/log/ghc/?revs=1-3">[1-3]</a> could map to INFO, DEBUG and TRACE. Log levels are inclusive so INFO also means WARN and ERROR.
</li><li>Component name - so we know what is the source of the log message. At least I would expect to see (Desugarer, Typechecker, Parser, etc)
</li><li>the message
</li></ul><p>
It would also mean a single back-end to collect the log messages and dump them to a file, stdout/stderr, etc. There are many other features beyond this point (customize log messages, colors, filtering, etc), but in terms of the API that is used throughout the code base, it should be simple.
</p>
<p>
Was this already discussed in the past? Is there already such an API in the codebase? Is there an existing library that we could use to achieve the same? Any other ideas?
</p>
<p>
This ticket is mostly to spawn a discussion about it.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9837#changelog
http://ghc.haskell.org/trac/ghc/ticket/9943
http://ghc.haskell.org/trac/ghc/ticket/9943#9943: Replace "error" with "errorWithStackTrace" from GHC.Stack in base libsWed, 31 Dec 2014 06:21:42 GMTspacekitteh<p>
It is basically the same as the standard error function but outputs a stack trace if one is available.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9943#changelog
http://ghc.haskell.org/trac/ghc/ticket/10061
http://ghc.haskell.org/trac/ghc/ticket/10061#10061: Remove fun_infix from Funbind, as it is now in MatchMon, 02 Feb 2015 22:01:26 GMTalanz<p>
One of the changes <a class="ext-link" href="https://phabricator.haskell.org/D538" title="D538 in Phab"><span class="icon"></span>Phab:D538</a> introduced is to add m_fun_id_infix to Match
</p>
<div class="code"><pre><span class="kr">data</span> <span class="kt">Match</span> id body
<span class="ow">=</span> <span class="kt">Match</span> <span class="p">{</span>
m_fun_id_infix <span class="ow">::</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="p">(</span><span class="kt">Located</span> id<span class="p">,</span><span class="kt">Bool</span><span class="p">)),</span>
<span class="c1">-- fun_id and fun_infix for functions with multiple equations</span>
<span class="c1">-- only present for a RdrName. See note [fun_id in Match]</span>
m_pats <span class="ow">::</span> <span class="p">[</span><span class="kt">LPat</span> id<span class="p">],</span> <span class="c1">-- The patterns</span>
m_type <span class="ow">::</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="p">(</span><span class="kt">LHsType</span> id<span class="p">)),</span>
<span class="c1">-- A type signature for the result of the match</span>
<span class="c1">-- Nothing after typechecking</span>
m_grhss <span class="ow">::</span> <span class="p">(</span><span class="kt">GRHSs</span> id body<span class="p">)</span>
<span class="p">}</span> <span class="kr">deriving</span> <span class="p">(</span><span class="kt">Typeable</span><span class="p">)</span>
</pre></div><p>
This was done to track the individual locations and fixity of the fun_id for each of the defining equations for a function when there are more than one.
</p>
<p>
For example, the function (&&&) is defined with some prefix and some infix equations below.
</p>
<div class="code"><pre>
<span class="p">(</span><span class="o">&&&</span> <span class="p">)</span> <span class="kt">[]</span> <span class="kt">[]</span> <span class="ow">=</span> <span class="kt">[]</span>
<span class="nf">xs</span> <span class="o">&&&</span> <span class="kt">[]</span> <span class="ow">=</span> xs
<span class="p">(</span> <span class="o">&&&</span> <span class="p">)</span> <span class="kt">[]</span> ys <span class="ow">=</span> ys
</pre></div><p>
This means that the fun_infix is now superfluous in the FunBind. This has not been removed as a potentially risky change just before 7.10 RC2, and so must be done after.
</p>
<p>
This ticket captures that task, which includes processing these fields through the renamer and beyond.
</p>
<p>
Ticket <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/9988" title="task: Remove fun_id, is_infix from FunBind, as they are now in Match (closed: fixed)">#9988</a> introduced these fields into Match through renaming, this ticket it to continue through type checking and then remove it from FunBind completely.
</p>
<p>
The split happened so that <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/9988" title="task: Remove fun_id, is_infix from FunBind, as they are now in Match (closed: fixed)">#9988</a> could land in 7.10
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/10061#changelog
http://ghc.haskell.org/trac/ghc/ticket/597
http://ghc.haskell.org/trac/ghc/ticket/597#597: Various error messages have inaccurate source locationsWed, 12 May 2004 00:00:00 GMTsimonmar<p>
Some error messages lack source location information, or have inaccurate locations. Here are the ones we know about:
</p>
<ul><li>Should point to the import decl:
<pre class="wiki"> ShowFunctions.hs:1:0
Warning: Module `Text.Show.Functions' is imported, but nothing from it is used
</pre></li><li>Should point to the instance header:
<pre class="wiki"> mod41.hs:3:0:
Illegal instance declaration for `Eq (Either a a)'
(The instance type must be of form (T a b c)
</pre></li><li>Should point to 'deriving *Eq*', not the tycon:
<pre class="wiki"> tcfail046.hs:9:8:
No instance for `Eq (Pid -> Time -> Message a -> (MessList a, Continuation a
))'
When deriving the `Eq' instance for type `Continuation'
</pre></li><li>check_tau_type doesn't have location info?
<pre class="wiki"> tcfail100.hs:7:0:
Type synonym `A' should have 1 argument, but has been given 0
In the type synonym declaration for `B'
</pre></li><li>Location in LHsModule from the parser should really span the whole file, rather than a point span at (1,0).
</li></ul><ul><li>read016: should be the lhs only?
</li><li>tcfail044: should be the instance head only.
</li></ul>Resultshttp://ghc.haskell.org/trac/ghc/ticket/597#changelog
http://ghc.haskell.org/trac/ghc/ticket/3462
http://ghc.haskell.org/trac/ghc/ticket/3462#3462: New codegen: allocate large objects using allocateLocal()Tue, 25 Aug 2009 08:48:42 GMTsimonmar<p>
See <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3424" title="bug: Corrupt executable when compiling large do block for List monad (closed: fixed)">#3424</a>.
</p>
<p>
In the new code generator, we should allocate large objects (larger than F * block size, for some suitable fraction F) using the RTS <tt>allocateLocal()</tt> API rather than from the nursery. It works to allocate them from the nursery -- this is what GHC 6.12 does after the fix in <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3424" title="bug: Corrupt executable when compiling large do block for List monad (closed: fixed)">#3424</a> -- but then they will not be treated as large objects and will be copied during GC. Also, the allocation is likely to fail, requiring a trip through the RTS to put a large enough block in the nursery to satisfy the allocation.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3462#changelog
http://ghc.haskell.org/trac/ghc/ticket/3559
http://ghc.haskell.org/trac/ghc/ticket/3559#3559: split ghci modules off into their own packageSat, 03 Oct 2009 00:46:47 GMTigloo<p>
ghci code should be split into bits that are always compiled (and always work), and modules that are in a separate <tt>ghci</tt> package. The current situation means that clients of the GHC API cannot specify whether or not they need the ghci modules (or other code inside <tt>GHCI</tt> ifdefs), and means that clients may accidentally end up using ghci-only interfaces without realising it. This is not just hypothetical: haddock has grown a dependency on ghci code: <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3558" title="task: Make haddock compilable without ghci being enabled (closed: fixed)">#3558</a>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3559#changelog
http://ghc.haskell.org/trac/ghc/ticket/3712
http://ghc.haskell.org/trac/ghc/ticket/3712#3712: Implement -dynamic-lib optionWed, 02 Dec 2009 11:20:48 GMTsimonmar<p>
The proposal is to add a new option <tt>-dynamic-lib</tt>, to be used when building a shared library. It would be both a compile-time and a link-time option, and could be used with <tt>--make</tt> to build a complete shared library in one go. It would avoid the pitfalls caused by there being combinations of <tt>-dynamic</tt> and <tt>-fPIC</tt> don't do what the user expects.
</p>
<p>
Specifically, <tt>-dynanmic-lib</tt> would imply <tt>-dyanamic</tt>, <tt>-fPIC</tt> where necessary, and <tt>-shared</tt> when linking.
</p>
<p>
See <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3705" title="bug: -fPIC without -dynamic silently ignored (closed: wontfix)">#3705</a> for more discussion.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3712#changelog
http://ghc.haskell.org/trac/ghc/ticket/3713
http://ghc.haskell.org/trac/ghc/ticket/3713#3713: Track -dynamic/-fPIC to avoid obscure linker errorsWed, 02 Dec 2009 11:25:19 GMTsimonmar<p>
Using the wrong combination of <tt>-dynamic</tt> and/or <tt>-fPIC</tt> can lead to obscure linker errors, see e.g. <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/3705" title="bug: -fPIC without -dynamic silently ignored (closed: wontfix)">#3705</a>. We should track whether an object file was compiled with <tt>-dynamic</tt> and <tt>-fPIC</tt> so that we can give better error messages before running the linker.
</p>
<p>
<strong>See also</strong>
</p><div><dl class="wiki compact"><dt><a class="new" href="/trac/ghc/ticket/3712" title="Implement -dynamic-lib option">#3712</a></dt><dd>Implement -dynamic-lib option</dd></dl></div><p>
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3713#changelog
http://ghc.haskell.org/trac/ghc/ticket/3755
http://ghc.haskell.org/trac/ghc/ticket/3755#3755: Improve join point inliningTue, 15 Dec 2009 10:57:00 GMTsimonpj<p>
This ticket relates to the paper "Optimising generics is easy" <a class="ext-link" href="http://www.dreixel.net/research/pdf/ogie.pdf"><span class="icon"></span>http://www.dreixel.net/research/pdf/ogie.pdf</a>. Jose writes (about a case where inlining doesn't work well):
</p>
<blockquote>
<p>
I put a minimal source code for this test and resulting Core
(with GHC 6.13.20091115) in <a class="ext-link" href="https://subversion.cs.uu.nl/repos/staff.jpm.public/Inline/"><span class="icon"></span>https://subversion.cs.uu.nl/repos/staff.jpm.public/Inline/</a>.
<tt>UpdateInt</tt> behaves great: in <tt>UpdateInt.core.O1.hs</tt>, there are no traces of
generic representations in testOne, testTwo, testThree and testFour.
</p>
</blockquote>
<blockquote>
<p>
<tt>UpdateString</tt>, however, does not behave so well. In <tt>UpdateString.core.O1.hs</tt>,
<tt>Test.testLogic_updateString</tt> still has loads of generic representations.
</p>
</blockquote>
<p>
It's easy to see what is happening. Compile <tt>UpdateString</tt> (which I've attached to this ticket) with <tt>-ddump-simpl</tt>, and look at the core. You see stuff like
</p>
<pre class="wiki">Rec { $j1_rx32 = \x. <big nested case expression>
; f = \y. ....($j1_rx32 <big constructor expression>)
---($j1_rx32 <big constructor expression)....
}
</pre><p>
So here the <tt>$j</tt> (which is a "join point") isn't inlined because it's big, although if it <em>were</em> inlined there would be much goodness because the case expressions would cancel with the explicit constructors.
</p>
<p>
Why did this happen despite lots of INLINE pragmas? I have not followed all the details, but I'm guessing that if we have, say
</p>
<pre class="wiki"> {-# INLINE from #-}
from = \x. case x of from_alts
{-# INLINE to #-}
to = \x. case x of to_alts
</pre><p>
and we try to optimize this call:
</p>
<pre class="wiki">from (mapT f (to x))
</pre><p>
then after inlining <tt>from</tt>, <tt>mapT</tt>, and <tt>to</tt> we'll get
</p>
<pre class="wiki">case (case (case x of to_alts) of map_alts) of from_alts
</pre><p>
And now the case-of-case transform happens, which creates the join points to avoid duplicating map_alts, from_alts into every branch of to_alts. You may say that we've already said that it's ok to duplicate from (and hence from_alts) but we duplicated it once when we inlined it, and then we forget the origin of the code. And indeed, in the worse case you could get a quadratic blow up; and there are only two functions involved. So I'm not unhappy with that.
</p>
<p>
However, it does make me wonder whether we could not do a better job on the above Rec {..}. Two thoughts occur.
</p>
<ol><li>We could beef up <tt>SpecConstr</tt>. It doesn't fire at the moment for some reason, even with -O2
</li></ol><ol start="2"><li>If we have
<pre class="wiki">f = \x. case x of { C1 x11..x1n -> e1; ... Ck xk1 ... xkm -> ek }
</pre>maybe we should worker-wrapper it to
<pre class="wiki">f1 x1 .. x1n = e1
...
fn xk1 .. xkm = en
f = \x of pi -> fi xi
</pre>and now inline f. The net effect is very similar to the way join points work right now, but it would make it multi-level. In fact, doing this might simplify and generalise the way that join points are currently done, where (rather arbitrarily) we duplicate the outer layer of a single case.
</li></ol><p>
Simon
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3755#changelog