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