[GHC] #2110: Rules to eliminate casted id's

GHC ghc-devs at haskell.org
Fri Jan 24 14:32:28 UTC 2014


#2110: Rules to eliminate casted id's
-------------------------------------+------------------------------------
        Reporter:  igloo             |            Owner:
            Type:  feature request   |           Status:  new
        Priority:  lowest            |        Milestone:  7.6.2
       Component:  Compiler          |          Version:  6.8.2
      Resolution:                    |         Keywords:
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  None/Unknown      |       Difficulty:  Unknown
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:
-------------------------------------+------------------------------------

Comment (by nomeata):

 I looked into this and further cleaned up the branch. But I just cannot
 get it to optimize `map unsafeCoerce` away, and the problem seems to be
 not enough eta-expansion in the simplifier.

 So here is the rule as desugared; it has the shape that we want it to have
 {{{
 ------ Local rules for imported ids --------
 "map/coerce" [ALWAYS]
     forall (@ a) (@ b) ($r$dCoercible :: a GHC.Prim.~R# b).
       GHC.Base.map @ a
                    @ b
                    ((\ (tpl :: a) -> tpl)
                     `cast` (<a>_R -> ($r$dCoercible) :: (a -> a) ~# (a ->
 b)))
       = (\ (tpl :: [a]) -> tpl)
         `cast` (<[a]>_R -> [($r$dCoercible)]_R
                 :: ([a] -> [a]) ~# ([a] -> [b]))
 }}}

 And here is the Core that we want it to match:
 {{{
   GHC.Base.map
     @ GHC.Types.Int
     @ Test.Age
     ((Unsafe.Coerce.unsafeCoerce1 @ GHC.Types.Int @ Test.Age)
      `cast` (<GHC.Types.Int>_R
              -> UnivCo representational GHC.Types.Int Test.Age
              :: (GHC.Types.Int -> GHC.Types.Int)
                   ~#
                 (GHC.Types.Int -> Test.Age)))
 }}}

 And for reference, here is the information on `unsafeCoerce1`:
 {{{
   unsafeCoerce1 :: forall a b. a -> a
     {- Arity: 1, HasNoCafRefs, Strictness: <S,1*U>,
        Unfolding: (\ @ a @ b x :: a -> x) -}
 }}}

 When trying to match, the matcher successfully matches the casts and then
 tries to match
 {{{
     \ (tpl{v} [lid] :: a{tv aMF} [tv]) -> tpl{v} [lid]
 }}}
 against
 {{{
     base:Unsafe.Coerce.unsafeCoerce1{v rKi} [gid]
       @ ghc-prim:GHC.Types.Int{(w) tc 3J} @ main:Test.Age{tc rM6}
 }}}

 It eta-expands both sides to match
 {{{
     tpl{v} [lid]
 }}}
 against
 {{{
     base:Unsafe.Coerce.unsafeCoerce1{v rKi} [gid]
       @ ghc-prim:GHC.Types.Int{(w) tc 3J}
       @ main:Test.Age{tc rM6}
       tpl{v} [lid]
 }}}
 and there it fails.

 Possible solutions: If GHC would inline `unsafeCoerce1` even though it is
 undersaturated, we’d be matching
 {{{
   GHC.Base.map
     @ GHC.Types.Int
     @ Test.Age
     ((\ x :: GHC.Types.Int -> x)
      `cast` (<GHC.Types.Int>_R
              -> UnivCo representational GHC.Types.Int Test.Age
              :: (GHC.Types.Int -> GHC.Types.Int)
                   ~#
                 (GHC.Types.Int -> Test.Age)))
 }}}
 which would succeed (this is also the shape we get from `map Age`). But I
 did not manage to define `unsafeCoerce` in a way that this happens.

 Alternatively, the matching code could, after eta-expanding, simplify the
 expression, so that the unfolding would happen here.

 Otherwise, my code is ready for review, see branch `wip/nomeata-T2110`.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/2110#comment:41>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list