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` * We use a new TcS mode, TcSFullySolve, when simplifying the Wanteds that arise from the specialise expression. The mechanism is explained in Note [TcSFullySolve] in GHC.Tc.Solver.Monad. The reason why we need to do this is explained in Note [Fully solving constraints for specialisation] in GHC.Tc.Gen.Sig. * 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,
Showing
- compiler/GHC/Builtin/Names/TH.hs 11 additions, 3 deletionscompiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Builtin/PrimOps/Ids.hs 1 addition, 0 deletionscompiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/Core/FamInstEnv.hs 1 addition, 0 deletionscompiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs 2 additions, 5 deletionscompiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Make.hs 1 addition, 1 deletioncompiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/CSE.hs 3 additions, 0 deletionscompiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs 10 additions, 10 deletionscompiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs 8 additions, 2 deletionscompiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs 1 addition, 1 deletioncompiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Predicate.hs 125 additions, 1 deletioncompiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/SimpleOpt.hs 23 additions, 7 deletionscompiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs 3 additions, 2 deletionscompiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/TyCo/FVs.hs 0 additions, 106 deletionscompiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs 4 additions, 1 deletioncompiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Tidy.hs 1 addition, 0 deletionscompiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs 0 additions, 26 deletionscompiler/GHC/Core/Type.hs
- compiler/GHC/Core/Type.hs-boot 11 additions, 24 deletionscompiler/GHC/Core/Type.hs-boot
- compiler/GHC/Core/Unify.hs 1 addition, 0 deletionscompiler/GHC/Core/Unify.hs
- compiler/GHC/CoreToIface.hs 1 addition, 1 deletioncompiler/GHC/CoreToIface.hs
- compiler/GHC/Driver/Config.hs 1 addition, 0 deletionscompiler/GHC/Driver/Config.hs
Loading
Please register or sign in to comment