[Git][ghc/ghc][wip/T24359] Specialising expressions -- at last

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Mon Dec 23 14:09:17 UTC 2024



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


Commits:
37295516 by Simon Peyton Jones at 2024-12-23T14:08:56+00:00
Specialising expressions -- at last

This MR addresses #24359, which implements the GHC proposal 493 on SPECIALISE pragmas.

* The old code path (using SpecSig and SpecPrag) still exists.
* The new code path (using SpecSigE and SpecPragE) runs alongside it.
* All SPECIALISE pragmas are routed through the new code path, except
  if you give multiple type sigs, when the old code path is still used.
* Main documentation: Note [Handling new-form SPECIALISE pragmas] in
  GHC.Tc.Gen.Sig`

Thanks to @sheaf for helping with this MR.

The Big Thing is to introduce

  {-# SPECIALISE forall x.  f @Int x True #-}

where you can give type arguments and value argument to specialise; and
you can quantify them with forall, just as in Rules.

I thought it was going to be pretty simple, but it was a Long, Long Saga.

Highlights

* Overview Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig
  - New data constructor `SpecSigE` in data type `L.H.S.Binds.Sig`
  - New data construtor `SpecPragE` in data type `GHC.Hs.Binds.TcSpecPrag`
  - Renamer: uses `checkSpecESigShape` to decide which function to assocate the
             SPECIALISE pragma with
  - Some of the action is in `GHC.Tc.Gen.Sig.tcSpecPrag`
  - The rest is in `GHC.HsToCore.Binds.dsSpec`

* All of GHC.Tc.Gen.Rule is moved into GHC.Tc.Gen.Sig, because the code is
  very closely related.

* The forall'd binders for SPECIALISE are the same as those for a RULE, so I
  refactored, introducing data type `L.H.S.Binds.RuleBndrs`, with functions
  to rename, zonk, typecheck it.  I refactored this data type a bit; nicer now.

* On the LHS of RULES, or SPECIALISE, we want to disable the tricky mechanims
  described in Note [Desugaring non-canonical evidence] in GHC.HsToCore.Expr.
  Previously it wasn't fully disabled (just set to the empty set), and that
  didn't quite work in the new regime.

* There are knock-on changes to Template Haskell.

* For the LHS of a RULE and a SPECIALISE expression, I wanted to simplify
  it /without/ inlining the let-bindings for evidence variables.  I added
  a flag `so_inline` to the SimpleOpt optimiser to support this.  The
  entry point is `GHC.Core.SimpleOpt.simpleOptExprNoInline`

* Since forever we have had a hack for type variables on the LHS of
  RULES. I took the opportunity to tidy this up.  The main action is
  in the zonker.  See GHC.Tc.Zonk.Type Note [Free tyvars on rule LHS],
  and especially data construtor `SkolemiseFlexi`
  in data type `GHC.Tc.Zonk.Env.ZonkFlexi`

* Move `scopedSort` from GHC.Core.TyCo.FVs to GHC.Core.Predicate
  Reason: it now works for Ids as well, and I wanted to use isEvVar,
          which is defined in GHC.Core.Predicate
  Avoiding module loops meant that instead of exporting GHC.Core.TyCo.Tidy
  from GHC.Core.Type, modules now import the former directly.

  I also took the opportunity to remove unused exports
  from GHC.Core.Type.hs-boot

* Flag stuff:
  - Add flag `-Wdeprecated-pragmas` and use it to control the warning when
    using old-style SPECIALISE pragmas with multiple type ascriptions,

  - Add flag `-Wuseless-specialisations` and use it to control the warning emitted
    when GHC determines that a SPECIALISE pragma would have no effect. Don't
    want if the SPECIALISE is SPECIALISE INLINE (#4444)

    In response to #25389, we continue to generate these seemingly code for these
    seemingly useless SPECIALISE pragmas

  - Adds deprecations to Template Haskell `pragSpecD` and `pracSpecInlD`,

* Split up old-style SPECIALISE pragmas in GHC.Internal.Float,
  GHC.Internal.Numeric, GHC.Internal.Real

* Remove useless SPECIALISE pragmas in Data.Array (updating the array submodule)

Smaller things:

- Update the Users Guide

- Add mention of the changes to the 9.14 release notes as well as
  the Template Haskell changelog,

- - - - -


30 changed files:

- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Type.hs-boot
- compiler/GHC/Core/Unify.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Driver/Config.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs


The diff was not included because it is too large.


View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/372955161d56dd61ca88da7da02dc1d4648016b3

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/372955161d56dd61ca88da7da02dc1d4648016b3
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/20241223/e4bf8871/attachment.html>


More information about the ghc-commits mailing list