Simplifier vs. rules problem
Simon Peyton Jones
simonpj at microsoft.com
Fri Sep 11 20:31:02 UTC 2020
Interesting. I have opened
https://gitlab.haskell.org/ghc/ghc/-/issues/18677
for this.
Simon
| -----Original Message-----
| From: ghc-devs <ghc-devs-bounces at haskell.org> On Behalf Of
| michael.sperber at active-group.de
| Sent: 11 September 2020 15:24
| To: ghc-devs at haskell.org
| Subject: Simplifier vs. rules problem
|
|
| I've been trying to make Conal's ConCat plugin work for polymorphic
| code, and am running into some problems with the ghc doing that, and
| I'd
| very much appreciate help with that.
|
| Background: I'm trying to get -dcore-lint to flag when my actual
| problem
| happens (has to do with dictionary construction, but it fails earlier
| with another problem, which I think comes from the simplifier.
|
| tl;dr: This transformation seems to me problematic:
|
| https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fghc-
| compiler-
| notes.readthedocs.io%2Fen%2Flatest%2Fnotes%2Fcompiler%2FsimplCore%2FSim
| plify.hs.html%23note-case-to-let-
| transformation&data=02%7C01%7Csimonpj%40microsoft.com%7C377b6cd1b01
| 0436a17c508d8567ca96f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6373
| 54441318347955&sdata=vyO%2FXLW3q3xh8gev%2BLLGxRxL4glGMVb61OYcGc7%2B
| tpo%3D&reserved=0
|
| The docs for the transformation say that it makes this replacement:
|
| case a +# b of r -> …r… into let r = a +# b in …r…
|
| But this creates a let binding with an unlifted binder, which the
| linter
| does not like:
|
| <no location info>: warning:
| [RHS of ... :: Int#]
| The type of this binder is unlifted: ...
| Binder's type: Int#
|
| Arguably, this rule might expect the let to be inlined, but we're
| seeing
| that the let stands, and the linter complains.
|
| My immediate concern is getting around this problem somehow so I can
| run
| the linter on later output of the simplifier. Is there any way to do
| this? I.e. don't stop when the linter complains, somehow massage the
| rules to work better - see below. Any help would be much appreciated!
| (I'm using ghc 8.8.3.)
|
| More details:
|
| The ConCat code has this rule:
|
| "rebox2" [~0] (+#) = \ u# v# -> unboxI (addC (boxI u#, boxI v#))
|
| It fires like this:
|
| Rule fired
| Rule: rebox_2
| Module: (ConCat.Rebox)
| Before: GHC.Prim.+# ValArg 10# ValArg 1#
| After: (\ (u#_aM4G :: GHC.Prim.Int#) (v#_aM4H :: GHC.Prim.Int#) ->
| ConCat.Rebox.unboxI
| (ConCat.AltCat.addC
| @ (->)
| @ GHC.Types.Int
| (ConCat.Category.$fNumCat->a @ GHC.Types.Int
| GHC.Num.$fNumInt)
| (ConCat.Rebox.boxI u#_aM4G, ConCat.Rebox.boxI
| v#_aM4H)))
| 10# 1#
| Cont: Stop[BoringCtxt] GHC.Prim.Int#
|
| ... and comes out of the simplifier like this:
|
| let {
| n1_sM4V :: GHC.Prim.Int#
| [LclId,
| Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False,
| WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 110
| 0}]
| n1_sM4V
| = case ConCat.AltCat.addC
| @ (->)
| @ GHC.Types.Int
| (ConCat.Category.$fNumCat->a
| @ GHC.Types.Int GHC.Num.$fNumInt)
| (ConCat.Rebox.boxI 10#, ConCat.Rebox.boxI 1#)
| of
| { GHC.Types.I# i#_aM4S ->
| i#_aM4S
| } } in
| GHC.Types.I#
| (case ConCat.AltCat.addC
| @ (->)
| @ GHC.Types.Int
| (ConCat.Category.$fNumCat->a @ GHC.Types.Int
| GHC.Num.$fNumInt)
| (ConCat.Rebox.boxI 10#, ConCat.Rebox.boxI 1#)
| of
| { GHC.Types.I# i#_aM4S ->
| i#_aM4S
| }) } in ...
|
| Ironically, you can see that the simplifier already *has* inlined, just
| not elided the (now dead) let binding yet, before the linter gets to
| it.
|
| I've also attached a shorter source file with the relevant rules that
| triggers the linter, albeit with a different message.
|
| Richard Eisenberg, Gabor Greif, and Conal helped me get to this point.
| Many thanks to them!
|
| --
| Regards,
| Mike
More information about the ghc-devs
mailing list