Compiler optimizations questions for ghc 6.10...

Tyson Whitehead twhitehead at gmail.com
Tue Feb 17 15:50:44 EST 2009


(compiled with ghc 6.10 with options -O2 -ddump-simpl)

I was wondering why lvl_s1mF is not being inlined into a_s1Gv in the core at 
the bottom of this email as that is the only place it is ever referenced.

It also seems the extra levels of indirection are defeating the strictness 
analyzer on eta_s1CN in a_s1Gv as all code branches either directly force it 
or ultimately pass it to digit_s1l3 as in the included branch.

Also, why isn't digit_s1l3 optimized to take its first parameter unboxed?  It 
is strict in its first argument, and grepping the core shows that it is only 
ever used like in lvl_s1mF (i.e., passed things like lvl_s1mG).

Thanks!  -Tyson

PS:  Is there any way to get better control over the loop breaker choice?  For 
a slightly simpler digit function, it is not chosen, and great code is 
produced.  I've tried using INLINE on digit, but that seems to result in the 
monad bind operator not being inlined, which produces even worse code.

.
.
.
letrec {
  lvl_s1mF :: Control.Monad.State.Strict.StateT
                GHC.Types.Int
                (Control.Monad.State.Strict.StateT
                   GHC.Types.Int
                   (Control.Monad.Error.ErrorT
                      GHC.Base.String Control.Monad.Identity.Identity))
                GHC.Types.Int
  [Str: DmdType {s1l3->C(S)}]
  lvl_s1mF = digit_s1l3 lvl_s1mG;
  .
  .
  .
  a_s1Gv :: GHC.Types.Int
            -> GHC.Types.Int
            -> Control.Monad.Error.ErrorT
                 [GHC.Types.Char]
                 Control.Monad.Identity.Identity
                 ((GHC.Types.Int, GHC.Types.Int), GHC.Types.Int)
  [Arity 2
   Str: DmdType U(L)L {a1hP->U(TTTL) s1ka->U(L)}]
  a_s1Gv =

  a_s1Gv =
    \ (eta_a1px [ALWAYS Just U(L)] :: GHC.Types.Int)
      (eta_s1CN [ALWAYS Just L] :: GHC.Types.Int) ->
    .
    .
    ....
      GHC.Bool.True ->
        (((lvl_s1mF
           `cast` (... ~
                      GHC.Types.Int
                      -> Control.Monad.State.Strict.StateT
                           GHC.Types.Int
                           (Control.Monad.Error.ErrorT
                              GHC.Base.String Control.Monad.Identity.Identity)
                           (GHC.Types.Int, GHC.Types.Int)))
            (GHC.Types.I# (GHC.Prim.+# x_a1tl 1)))
         `cast` (... ~
                    GHC.Types.Int
                    -> Control.Monad.Error.ErrorT
                         GHC.Base.String
                         Control.Monad.Identity.Identity
                         ((GHC.Types.Int, GHC.Types.Int), GHC.Types.Int)))
          eta_s1CN
    ....
    .
    .
  .
  .
  .
  digit_s1l3 [ALWAYS LoopBreaker Nothing]
             :: GHC.Types.Int
                -> Control.Monad.State.Strict.StateT
                     GHC.Types.Int
                     (Control.Monad.State.Strict.StateT
                        GHC.Types.Int
                        (Control.Monad.Error.ErrorT
                           GHC.Base.String
                           Control.Monad.Identity.Identity))
                     GHC.Types.Int
  [Arity 1
   Str: DmdType U(L)]
  digit_s1l3 =
    \ (x_aqR [ALWAYS Just U(L)] ::GHC.Types.Int) ->
      case x_aqR
      of x_XsO [ALWAYS Just A] { GHC.Types.I# ipv_s1bt [ALWAYS Just L] ->
      let {
        .
        .
        .
      } in
      (\ (eta_X1sC [ALWAYS Just L] :: GHC.Types.Int)
         (eta_s1FE [ALWAYS Just U(L)] :: GHC.Types.Int) ->
        .
        .
        . )
      `cast` (... ~
                 Control.Monad.State.Strict.StateT
                   GHC.Types.Int
                   (Control.Monad.State.Strict.StateT
                      GHC.Types.Int
                      (Control.Monad.Error.ErrorT
                         GHC.Base.String Control.Monad.Identity.Identity))
                   GHC.Types.Int)
  .
  .
  .
}
.
.
.
lvl_s1mG :: GHC.Types.Int
[Str: DmdType m]
lvl_s1mG = GHC.Types.I# 0



More information about the Glasgow-haskell-users mailing list