[Git][ghc/ghc][wip/T21286] 15 commits: Add `Eq` and `Ord` instances for `Generically1`

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Tue Sep 27 07:33:08 UTC 2022



Simon Peyton Jones pushed to branch wip/T21286 at Glasgow Haskell Compiler / GHC


Commits:
c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00
Add `Eq` and `Ord` instances for `Generically1`

These are needed so the subsequent commit overhauling the `*1` classes
type-checks.

- - - - -
7beb356e by John Ericson at 2022-09-20T13:11:50-04:00
Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking

This change is approved by the Core Libraries commitee in
https://github.com/haskell/core-libraries-committee/issues/10

The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for
`Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`.
These have the proper flexible contexts that are exactly what the
instance needs:

For example, instead of
```haskell
instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where
  (==) = eq1
```
we do
```haskell
deriving instance Eq (f (g a)) => Eq (Compose f g a)
```

But, that change alone is rather breaking, because until now `Eq (f a)`
and `Eq1 f` (and respectively the other classes and their `*1`
equivalents too) are *incomparable* constraints. This has always been an
annoyance of working with the `*1` classes, and now it would rear it's
head one last time as an pesky migration.

Instead, we give the `*1` classes superclasses, like so:
```haskell
(forall a. Eq a => Eq (f a)) => Eq1 f
```
along with some laws that canonicity is preserved, like:
```haskell
liftEq (==) = (==)
```

and likewise for `*2` classes:
```haskell
(forall a. Eq a => Eq1 (f a)) => Eq2 f
```
and laws:
```haskell
liftEq2 (==) = liftEq1
```

The `*1` classes also have default methods using the `*2` classes where
possible.

What this means, as explained in the docs, is that `*1` classes really
are generations of the regular classes, indicating that the methods can
be split into a canonical lifting combined with a canonical inner, with
the super class "witnessing" the laws[1] in a fashion.

Circling back to the pragmatics of migrating, note that the superclass
means evidence for the old `Sum`, `Product`, and `Compose` instances is
(more than) sufficient, so breakage is less likely --- as long no
instances are "missing", existing polymorphic code will continue to
work.

Breakage can occur when a datatype implements the `*1` class but not the
corresponding regular class, but this is almost certainly an oversight.
For example, containers made that mistake for `Tree` and `Ord`, which I
fixed in https://github.com/haskell/containers/pull/761, but fixing the
issue by adding `Ord1` was extremely *un*controversial.

`Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show`
instances. It is unlikely this would have been caught without
implementing this change.

-----

[1]: In fact, someday, when the laws are part of the language and not
only documentation, we might be able to drop the superclass field of the
dictionary by using the laws to recover the superclass in an
instance-agnostic manner, e.g. with a *non*-overloaded function with
type:

```haskell
DictEq1 f -> DictEq a -> DictEq (f a)
```

But I don't wish to get into optomizations now, just demonstrate the
close relationship between the law and the superclass.

Bump haddock submodule because of test output changing.

- - - - -
6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00
Add notes to ghc-prim Haddocks that users should not import it

- - - - -
ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00
docs: clarify that LLVM codegen is not available in unregisterised mode

The current docs are misleading and suggest that it is possible to use
LLVM codegen from an unregisterised build.  This is not the case;
attempting to pass `-fllvm` to an unregisterised build warns:

```
when making flags consistent: warning:
    Target platform uses unregisterised ABI, so compiling via C
```

and uses the C codegen anyway.

- - - - -
854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00
rts: remove copy-paste error from `cabal.rts.in`

This was, likely accidentally, introduced in 4bf542bf1c.

See: 4bf542bf1cdf2fa468457fc0af21333478293476

- - - - -
c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00
hadrian: Add extra_dependencies edges for all different ways

The hack to add extra dependencies needed by DeriveLift extension missed
the cases for profiles and dynamic ways. For the profiled way this leads
to errors like:

```
GHC error in desugarer lookup in Data.IntSet.Internal:
  Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’
  Perhaps you haven't installed the profiling libraries for package ‘template-haskell’?
  Use -v (or `:set -v` in ghci) to see a list of the files searched for.
ghc: panic! (the 'impossible' happened)
  GHC version 9.5.20220916:
        initDs
```

Therefore the fix is to add these extra edges in.

Fixes #22197

- - - - -
a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00
users-guide: fix incorrect ghcappdata folder for unix and windows

- - - - -
06ccad0d by sheaf at 2022-09-21T08:28:49-04:00
Don't use isUnliftedType in isTagged

The function GHC.Stg.InferTags.Rewrite.isTagged can be given
the Id of a join point, which might be representation polymorphic.
This would cause the call to isUnliftedType to crash. It's better
to use typeLevity_maybe instead.

Fixes #22212

- - - - -
c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00
Add fragmentation statistic to GHC.Stats

Implements #21537

- - - - -
2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00
Rename Solo[constructor] to MkSolo

Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst)

Moves all tuples to GHC.Tuple.Prim
Updates ghc-prim version (and bumps bounds in dependents)

updates haddock submodule
updates deepseq submodule
updates text submodule

- - - - -
9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00
Update filepath to filepath-1.4.100.0

Updates submodule

* Always rely on vendored filepath
* filepath must be built as stage0 dependency because it uses
  template-haskell.

Towards #22098

- - - - -
615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00
Minor refactor around Outputable

* Replace 'text . show' and 'ppr' with 'int'.
* Remove Outputable.hs-boot, no longer needed
* Use pprWithCommas
* Factor out instructions in AArch64 codegen

- - - - -
2a74ad4b by Simon Peyton Jones at 2022-09-27T08:35:10+01:00
Improve aggressive specialisation

This patch fixes #21286, by not unboxing dictionaries in
worker/wrapper (ever). The main payload is tiny:

* In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox
  dictionaries in `get_dmd`.  See Note [Do not unbox class dictionaries]
  in that modules

* I also found that imported wrappers were being fruitlessly
  specialised, so I fixed that too, in canSpecImport.
  See Note [Specialising imported functions] point (2).

In doing due diligence in the testsuite I fixed a number of
other things:

* Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make,
  and Note [Inline specialisations] in GHC.Core.Opt.Specialise,
  and remove duplication between the two. The new Note describes
  how we specialise functions with an INLINABLE pragma.

  And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`.

* Improve Note [Worker/wrapper for INLINABLE functions] in
  GHC.Core.Opt.WorkWrap.

  And (critially) make an actual change which is to propagate the
  user-written pragma from the original function to the wrapper; see
  `mkStrWrapperInlinePrag`.

* Write new Note [Specialising imported functions] in
  GHC.Core.Opt.Specialise

All this has a big effect on some compile times:

Metrics: compile_time/bytes allocated
--------------------------------------------------------
                LargeRecord(normal) ghc/alloc  6,084,071,354  -50.1% GOOD
           ManyConstructors(normal) ghc/alloc  3,928,349,810   +1.7%
MultiLayerModulesTH_OneShot(normal) ghc/alloc  2,523,518,560   +1.2%
                     T12545(normal) ghc/alloc  1,633,149,272   +3.1%
                     T13056(optasm) ghc/alloc    349,532,453   -8.7% GOOD
                     T13253(normal) ghc/alloc    343,592,469   -3.3% GOOD
                     T15164(normal) ghc/alloc  1,304,125,024   -3.4% GOOD
                     T16190(normal) ghc/alloc    278,584,392   -1.5%
                     T16577(normal) ghc/alloc  8,050,423,421   -2.8% GOOD
                     T17836(normal) ghc/alloc    829,913,981   +2.3%
                     T18223(normal) ghc/alloc    734,732,288  -33.3% GOOD
                     T18282(normal) ghc/alloc    150,159,957   -2.9% GOOD
                     T18478(normal) ghc/alloc    498,300,837   +1.2%
                     T19695(normal) ghc/alloc  1,444,571,802   -2.5% GOOD
                      T9630(normal) ghc/alloc  1,523,682,706  -32.8% GOOD
                      WWRec(normal) ghc/alloc    624,174,317   -9.6% GOOD
                     hie002(normal) ghc/alloc  9,020,356,301   +1.8%
-------------------------------------------------------------------------
                          geo. mean                            -1.7%
                          minimum                             -50.1%
                          maximum                              +3.1%

I diligently investigated all these big drops.

* Caused by not doing w/w for dictionaries:
    T13056, T15164, WWRec, T18223

* Caused by not fruitlesslly specialising wrappers
    LargeRecord, T9630

I also got one runtime improvement:
     T9203(normal) run/alloc     105,672,160    -10.7% GOOD
but I did not investigate.

Nofib is a wash:

+===============================++===============+===========+
|                     real/anna ||        -0.13% |      0.0% |
|                      real/fem ||        +0.13% |      0.0% |
|                   real/fulsom ||        -0.16% |      0.0% |
|                   real/gamteb ||        +0.02% |      0.0% |
|                       real/gg ||        +0.01% |      0.0% |
|                     real/lift ||        -1.55% |      0.0% |
|                  real/reptile ||        -0.11% |      0.0% |
|                      real/scs ||        -0.08% |      0.0% |
|                  real/smallpt ||        +0.51% |      0.0% |
|                   real/symalg ||        -0.01% |      0.0% |
|                  real/veritas ||        +0.05% |      0.0% |
|         shootout/binary-trees ||        +0.00% |      0.0% |
|       shootout/fannkuch-redux ||        -0.05% |      0.0% |
|         shootout/k-nucleotide ||        -0.01% |      0.0% |
|               shootout/n-body ||        -0.06% |      0.0% |
|        shootout/spectral-norm ||        +0.01% |      0.0% |
|          spectral/constraints ||        +0.20% |      0.0% |
|               spectral/dom-lt ||        +1.80% |      0.0% |
|               spectral/expert ||        +0.33% |      0.0% |

Metric Decrease:
    LargeRecord
    T13056
    T15164
    T16577
    T18223
    T9630
    WWRec
    T9203

- - - - -
0ba307a4 by Simon Peyton Jones at 2022-09-27T08:35:10+01:00
Refactor UnfoldingSource and IfaceUnfolding

I finally got tired of the way that IfaceUnfolding reflected
a previous structure of unfoldings, not the current one. This
MR refactors UnfoldingSource and IfaceUnfolding to be simpler
and more consistent.

It's largely just a refactor, but in UnfoldingSource (which moves
to GHC.Types.Basic, since it is now used in IfaceSyn too), I
distinguish between /user-specified/ and /system-generated/ stable
unfoldings.

    data UnfoldingSource
      = VanillaSrc
      | StableUserSrc   -- From a user-specified pragma
      | StableSystemSrc -- From a system-generated unfolding
      | CompulsorySrc

This has a minor effect in CSE (see the use of isisStableUserUnfolding
in GHC.Core.Opt.CSE), which I tripped over when working on
specialisation, but it seems like a Good Thing to know anyway.

- - - - -
2a660d02 by Simon Peyton Jones at 2022-09-27T08:35:10+01:00
INLINE/INLINEABLE pragmas in Foreign.Marshal.Array

Foreign.Marshal.Array contains many small functions, all of which are
overloaded, and which are critical for performance. Yet none of them
had pragmas, so it was a fluke whether or not they got inlined.

This patch makes them all either INLINE (small ones) or
INLINEABLE and hence specialisable (larger ones).

See Note [Specialising array operations] in that module.

- - - - -


30 changed files:

- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/DebugBlock.hs
- compiler/GHC/CmmToAsm.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs


The diff was not included because it is too large.


View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dfc17739c62a4f553e7a5912e67ee330d386a6a...2a660d024b1efea4b6fc3460b424bfe993e06e45

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dfc17739c62a4f553e7a5912e67ee330d386a6a...2a660d024b1efea4b6fc3460b424bfe993e06e45
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220927/aa95901a/attachment-0001.html>


More information about the ghc-commits mailing list