Simplifier vs. rules problem

michael.sperber at active-group.de michael.sperber at active-group.de
Fri Sep 11 14:24:05 UTC 2020


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://ghc-compiler-notes.readthedocs.io/en/latest/notes/compiler/simplCore/Simplify.hs.html#note-case-to-let-transformation

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
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: not available
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20200911/2bab8dcb/attachment.ksh>


More information about the ghc-devs mailing list