[GHC] #14430: lintUnfolding does not allow unfoldings to jump to enclosing join points
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points
-------------------------------------+-------------------------------------
           Reporter:  nomeata        |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  8.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 I am not sure why this does not show up in HEAD but it does show up in my
 loopification branch. It does look like a bug in GHC to me.
 With loopification, I get the following code in the interface of
 `Foreign.C.String`:
 {{{
 d5fd65f7834390bebd0e80edc7b8f627
   withCAStringLen1 ::
     String
     -> (CStringLen -> IO a)
     -> State# RealWorld
     -> (# State# RealWorld, a #)
   {- Arity: 3, HasNoCafRefs,
      Strictness: ,
      Unfolding: (\ @ a
                    (str :: String)
                    (f :: CStringLen -> IO a)
                    (eta :: State# RealWorld) ->
                  case lenAcc @ Char str newCAString2 of wild { I# x ->
                  case newAlignedPinnedByteArray#
                         @ RealWorld
                         x
                         1#
                         eta of ds2 { (#,#) ipv ipv1 ->
                  case unsafeFreezeByteArray#
                         @ RealWorld
                         ipv1
                         ipv of ds3 { (#,#) ipv2 ipv3 ->
                  let {
                    ptr :: Addr# = byteArrayContents# ipv3
                  } in
                  let {
                    $j :: State# RealWorld -> () -> (# State# RealWorld, a
 #)
                      ,
                                  Inline: [~],
                                  Unfolding: InlineRule (3, True, False)
                                             (\ (ds :: [Char])[OneShot]
                                                (n :: Int)[OneShot]
                                                (eta1 :: State#
 RealWorld)[OneShot] ->
                                              letrec {
                                                go :: [Char]
                                                      -> Int
                                                      -> State# RealWorld
                                                      -> (# State#
 RealWorld, a #)
                                                   -}
                        = \ (w :: State# RealWorld)[OneShot] ->
                          case (f (Ptr @ CChar ptr, wild)) `cast` (N:IO[0]
 <a>_R)
                                 w of ds4 { (#,#) ipv4 ipv5 ->
                          case touch#
                                 @ 'UnliftedRep
                                 @ ByteArray#
                                 ipv3
                                 ipv4 of s4 { DEFAULT ->
                          (# s4, ipv5 #) } }
                      } in
                      letrec {
                        $wgo :: [Char]
                                -> Int# -> State# RealWorld -> (# State#
 RealWorld, a #)
                          , Inline: [0] -}
                        = \ (w :: [Char]) (ww2 :: Int#) (w1 :: State#
 RealWorld) ->
                          case w of wild1 {
                            [] -> exit w1
                            : c cs
                            -> case c of wild2 { C# c# ->
                               case writeInt8OffAddr#
                                      @ RealWorld
                                      ptr
                                      ww2
                                      (narrow8Int# (ord# c#))
                                      w1 of s2 { DEFAULT ->
                               $wgo cs (+# ww2 1#) s2 } } }
                      } in
                      $wgo ds ww1 eta1 }
                  } in
                  go str newCAString2 ipv2 } } }) -}
 }}}
 Note how `go` references `j` not only in its RHS, but also in its
 unfolding.
 When loading this interface, I get this error:
 {{{
   HC [stage 1] libraries/base/dist-install/build/System/Posix/Internals.o
 ghc-stage1: panic! (the 'impossible' happened)
   (GHC version 8.3.20171101 for x86_64-unknown-linux):
         Iface Lint failure
   In interface for Foreign.C.String
   Unfolding of go_a6h7
     <no location info>: warning:
         In the expression: jump $j_a6gX eta2_a6hS ()
         Invalid occurrence of a join variable: $j_a6gX
         The binder is either not a join point, or not valid here
   go_a6h7 = \ (ds_a6hM [OS=OneShot] :: [Char])
               (n_a6hN [OS=OneShot] :: Int)
               (eta1_a6hO [OS=OneShot] :: State# RealWorld) ->
               joinrec {
                 go_a6hP
                   :: [Char]
                      -> Int -> State# RealWorld -> (# State# RealWorld,
 a_a6gD #)
                 [LclId[JoinId(3)], Arity=3]
                 go_a6hP (ds1_a6hQ :: [Char])
                         (n1_a6hR :: Int)
                         (eta2_a6hS :: State# RealWorld)
                   = case ds1_a6hQ of wild1_a6hT {
                       [] ->
                         case n1_a6hR of n2_a6hW { I# ipv4_a6hY ->
                         jump $j_a6gX eta2_a6hS ()
                         };
                       : c_a6i1 cs_a6i2 ->
                         case n1_a6hR of wild2_a6i4 { I# i_a6i6 ->
                         case c_a6i1 of wild3_a6i8 { C# c#_a6ia ->
                         case writeInt8OffAddr#
                                @ RealWorld ptr_a6gT i_a6i6 (narrow8Int#
 (ord# c#_a6ia)) eta2_a6hS
                         of s2_a6ic
                         { __DEFAULT ->
                         jump go_a6hP cs_a6i2 (I# (+# i_a6i6 1#)) s2_a6ic
                         }
                         }
                         }
                     }; } in
               jump go_a6hP ds_a6hM n_a6hN eta1_a6hO
   Iface expr = \ (ds :: [Char])[OneShot]
                  (n :: Int)[OneShot]
                  (eta1 :: State# RealWorld)[OneShot] ->
                letrec {
                  go :: [Char]
                        -> Int -> State# RealWorld -> (# State# RealWorld,
 a #)
                    
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): The key idea is this: an unfolding is like an extra RHS for the function. So yes, this is a bug. On inspection, it's caused by `lintUnfolding` being called in the wrong place: * We want `lintUnfolding` to be called, once for all, on the unfolding (if any) of each top-level Id; that is, in the `IfaceId` case of `tc_iface_decl`. * But it isn't! Instead `lintUnfolding` is called by `tcPragExpr`, which is called from `tcUnfolding` which is called for each nested unfolding in the interface-file declaration. * This is inefficient, because the top-level call will re-lint the nested unfoldings; and it's wrong for the reason you point out. In the olden days there were no nested unfoldings in interface0-file definitions, which is why this bug got started. Might you fix, Joachim? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by nomeata): With these pointers, I can give it a shot. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * owner: (none) => nomeata -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D4169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * status: new => patch * differential: => Phab:D4169 Comment: See https://phabricator.haskell.org/D4169 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:  nomeata
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.3
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D4169
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Comment (by Joachim Breitner 
#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D4169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * status: patch => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
- 
                
GHC