[GHC] #14789: GHCi fails to garbage collect declaration `l = length [1..10^8]` entered at prompt

GHC ghc-devs at haskell.org
Wed May 30 18:13:08 UTC 2018


#14789: GHCi fails to garbage collect declaration `l = length [1..10^8]` entered at
prompt
-------------------------------------+-------------------------------------
        Reporter:  kabuhr            |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  GHCi              |              Version:  8.2.2
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Runtime           |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by bgamari):

 Here is the code produced (from `-ddump-rn -ddump-simpl -ddump-bcos`) by
 the `let l` form,
 {{{
 λ> let l = length [1..10^8]

 ==================== Renamer ====================
 let l_a2bl = length [1 .. 10 ^ 8]


 ==================== Simplified expression ====================
 GHC.Base.returnIO
   @ [()]
   (GHC.Types.:
      @ ()
      ((Data.Foldable.length
          @ []
          Data.Foldable.$fFoldable[]
          @ GHC.Integer.Type.Integer
          (GHC.Enum.enumFromTo
             @ GHC.Integer.Type.Integer
             GHC.Enum.$fEnumInteger
             1
             (GHC.Real.^
                @ GHC.Integer.Type.Integer
                @ GHC.Integer.Type.Integer
                GHC.Num.$fNumInteger
                GHC.Real.$fIntegralInteger
                10
                8)))
       `cast` (UnsafeCo representational GHC.Types.Int ()
               :: (GHC.Types.Int :: *) ~R# (() :: *)))
      (GHC.Types.[] @ ()))



 ==================== Proto-BCOs ====================
 ProtoBCO ExprTopLevel_E0#0 []:
    let sat_s3Wi = ... in ...
    bitmap:  0 []
    ALLOC_AP    0
    PUSH_BCO
      ProtoBCO sat_s3Wi#0 []:
         let sat_s3Wh = ... in ...
         bitmap:  0 []
         ALLOC_AP    0
         PUSH_BCO
           ProtoBCO sat_s3Wh#0 []:
              let sat_s3Wg = ... in ...
              bitmap:  0 []
              ALLOC_AP    0
              PUSH_BCO
                ProtoBCO sat_s3Wg#0 []:
                   let sat_s3Wf = ... in ...
                   bitmap:  0 []
                   PUSH_UBX (1) 8#
                   PACK     GHC.Integer.Type.S# 1
                   PUSH_UBX (1) 10#
                   PACK     GHC.Integer.Type.S# 1
                   PUSH_LL  1 0
                   PUSH_G   GHC.Real.$fIntegralInteger
                   PUSH_G   GHC.Num.$fNumInteger
                   PUSH_APPLY_PPPP
                   PUSH_G   GHC.Real.^
                   SLIDE    6 2
                   ENTER
              MKAP     0 words, 1 stkoff
              PUSH_UBX (1) 1#
              PACK     GHC.Integer.Type.S# 1
              PUSH_LL  1 0
              PUSH_G   GHC.Enum.$fEnumInteger
              PUSH_APPLY_PPP
              PUSH_G   GHC.Enum.enumFromTo
              SLIDE    5 2
              ENTER
         MKAP     0 words, 1 stkoff
         PUSH_L   0
         PUSH_G   Data.Foldable.$fFoldable[]
         PUSH_APPLY_PP
         PUSH_G   Data.Foldable.length
         SLIDE    4 1
         ENTER
    MKAP     0 words, 1 stkoff
    PUSH_G   GHC.Types.[]
    PUSH_L   1
    PACK     : 2
    PUSH_L   0
    PUSH_APPLY_P
    PUSH_G   GHC.Base.returnIO
    SLIDE    3 2
    ENTER
 }}}

 Here is the same output for the `let`-less form,
 {{{
 λ> l = length [1..10^8]

 ==================== Renamer ====================
 interactive:Ghci2.l = length [1 .. 10 ^ 8]


 ==================== Tidy Core ====================
 Result size of Tidy Core
   = {terms: 25, types: 11, coercions: 0, joins: 0/0}

 -- RHS size: {terms: 10, types: 5, coercions: 0, joins: 0/0}
 l :: Int
 [GblId]
 l = length
       @ []
       Data.Foldable.$fFoldable[]
       @ Integer
       (enumFromTo
          @ Integer
          GHC.Enum.$fEnumInteger
          1
          (^ @ Integer
             @ Integer
             GHC.Num.$fNumInteger
             GHC.Real.$fIntegralInteger
             10
             8))

 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
 $trModule1_r3XB :: GHC.Prim.Addr#
 [GblId, Caf=NoCafRefs]
 $trModule1_r3XB = "interactive"#

 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
 $trModule2_r3XM :: GHC.Types.TrName
 [GblId, Caf=NoCafRefs]
 $trModule2_r3XM = GHC.Types.TrNameS $trModule1_r3XB

 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
 $trModule3_r3XN :: GHC.Prim.Addr#
 [GblId, Caf=NoCafRefs]
 $trModule3_r3XN = "Ghci2"#

 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
 $trModule4_r3XO :: GHC.Types.TrName
 [GblId, Caf=NoCafRefs]
 $trModule4_r3XO = GHC.Types.TrNameS $trModule3_r3XN

 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
 interactive:Ghci2.$trModule :: GHC.Types.Module
 [GblId, Caf=NoCafRefs]
 interactive:Ghci2.$trModule
   = GHC.Types.Module $trModule2_r3XM $trModule4_r3XO




 ==================== Proto-BCOs ====================
 ProtoBCO sat_s3XU#0 []:
    let sat_s3XT = ... in ...
    bitmap:  0 []
    ALLOC_AP    0
    PUSH_BCO
      ProtoBCO sat_s3XT#0 []:
         let sat_s3XS = ... in ...
         bitmap:  0 []
         PUSH_UBX (1) 8#
         PACK     GHC.Integer.Type.S# 1
         PUSH_UBX (1) 10#
         PACK     GHC.Integer.Type.S# 1
         PUSH_LL  1 0
         PUSH_G   GHC.Real.$fIntegralInteger
         PUSH_G   GHC.Num.$fNumInteger
         PUSH_APPLY_PPPP
         PUSH_G   GHC.Real.^
         SLIDE    6 2
         ENTER
    MKAP     0 words, 1 stkoff
    PUSH_UBX (1) 1#
    PACK     GHC.Integer.Type.S# 1
    PUSH_LL  1 0
    PUSH_G   GHC.Enum.$fEnumInteger
    PUSH_APPLY_PPP
    PUSH_G   GHC.Enum.enumFromTo
    SLIDE    5 2
    ENTER

 ProtoBCO Ghci2.l#0 []:
    Data.Foldable.length
      @ [] Data.Foldable.$fFoldable[] @ GHC.Integer.Type.Integer sat_s3XU
    bitmap:  0 []
    PUSH_G   sat_s3XU
    PUSH_G   Data.Foldable.$fFoldable[]
    PUSH_APPLY_PP
    PUSH_G   Data.Foldable.length
    ENTER

 ProtoBCO $trModule2_r3XM#0 []:
    GHC.Types.TrNameS $trModule1_r3XB
    bitmap:  0 []
    PUSH_UBX (1) 26770624##
    PACK     GHC.Types.TrNameS 1
    ENTER

 ProtoBCO $trModule4_r3XO#0 []:
    GHC.Types.TrNameS $trModule3_r3XN
    bitmap:  0 []
    PUSH_UBX (1) 26770592##
    PACK     GHC.Types.TrNameS 1
    ENTER

 ProtoBCO Ghci2.$trModule#0 []:
    GHC.Types.Module $trModule2_r3XM $trModule4_r3XO
    bitmap:  0 []
    PUSH_G   $trModule4_r3XO
    PUSH_G   $trModule2_r3XM
    PACK     GHC.Types.Module 2
    ENTER
 }}}

 It looks to me like the BCO pass is somehow floating out the `enumFromTo`
 application, which then gets retained.

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


More information about the ghc-tickets mailing list