[GHC] #10626: Missed opportunity for SpecConstr

GHC ghc-devs at haskell.org
Tue Feb 7 23:21:51 UTC 2017


#10626: Missed opportunity for SpecConstr
-------------------------------------+-------------------------------------
        Reporter:  simonpj           |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  7.10.1
      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:                    |
-------------------------------------+-------------------------------------
Changes (by dsc):

 * cc: dsc (added)


Comment:

 (Not sure if my problem is different enough from this one to warrant a
 separate ticket.)

 I also have a problem where SpecConstr apparently gets stuck and doesn't
 converge to a fixed point: If I translate the Core back into Haskell and
 compile that again, I get great code with all state constructors
 eliminated.

 The code in question is TH-generated stream fusion code. I suppose that
 only the dump-splices result is relevant here, so I made it compilable and
 attached that (Input.hs).

 The Core (also attached) contains lots of seemingly obvious SpecConstr
 opportunities:
 {{{
 test_$s$wgfold_loop =
   \ (sc
        :: FlattenState
             Int (ParamAndState Int (ConcatState YieldState ()
 YieldState)))
     (sc1 :: Int)
     (sc2 :: Int#) ->
     case sc1 of _ [Occ=Dead] { I# y ->
     case sc of _ [Occ=Dead] {

 [...]

       Flatten_RunningInner so_agux si_aguy ->

 [...]
                 test_$s$wgfold_loop
                   (Flatten_RunningInner
                      so_agux (ParamAndState a_aguz (CS_First
 AfterYielding)))
                   a_aguz
                   (+# (+# sc2 y) 42#);

 [...]

                 test_$s$wgfold_loop
                   (Flatten_RunningInner
                      so_agux (ParamAndState a_aguz (CS_Second ()
 AfterYielding)))
                   a_aguz
                   (+# (+# sc2 y) 42#)

 [...]
 }}}

 This is the second-round Core after retranslating the first Core into
 Haskell (hopefully without changing semantics) and compiling again:

 {{{
 test_$s$wgfold_loop =
   \ (sc :: Int#)
     (sc1 :: Int#)
     (sc2 :: Int#)
     _ [Occ=Dead]
     _ [Occ=Dead] ->
     case tagToEnum# (># sc2 1000000#) of _ [Occ=Dead] {
       False ->
         test_$s$wgfold_loop
           (+# (+# (+# (+# sc sc1) 42#) sc2) 42#) sc2 (+# sc2 1#) sc2 ();
       True -> +# sc sc1
     }
 }}}

 I noticed that in the first core, GHC thinks that `test_$s$wgfold_loop` is
 lazy (`Str=DmdType <L,U><L,U><L,U>`). `-flate-dmd-anal` fixed that but
 doesn't seem to change much else (it unboxes one of the `Int` args, but
 doesn't affect the state type).

 I compiled with
 `stack ghc -- -O2 -ddump-simpl -ddump-to-file -dsuppress-module-prefixes
 -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques
 -dsuppress-unfoldings -fforce-recomp Input.hs` using GHC 8.0.1 (without
 `-dsuppress-uniques` for producing the TH splices).

 I also tried adding `-fmax-simplifier-iterations=999999 -fspec-constr-
 count=999999 -fspec-constr-threshold=999999 -fspec-constr-recursive=999999
 -flate-dmd-anal -funfolding-use-threshold=999999` to no effect (the
 `-fspec-constr` flags are redundant since I'm using the `SPEC` type in the
 loop, correct?).

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


More information about the ghc-tickets mailing list