[GHC] #11731: Demand analysis: Thunk wrongly determined single-entry
GHC
ghc-devs at haskell.org
Mon Mar 21 08:27:16 UTC 2016
#11731: Demand analysis: Thunk wrongly determined single-entry
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.1
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):
{{{
Entries Alloc Alloc'd #Alloc Single Multiple Non-
void Arguments STG Name
4096 0 65536 2048 0 2048 0
sat_s2vw{v} (main at main:GamtebMain) (thk,se) in r2uq
}}}
The relevant `-ddump-prep` code is this:
{{{
let {
sat_s2vw [Occ=Once,
Dmd=<L,1*U(U)>] :: GamtebType.Random
[LclId, Str=DmdType] =
\s srt:SRT:[r4K :->
Utils.$wgenRand] []
case Utils.$wgenRand
w_s2ux of _ [Occ=Dead] {
(#,#) ww5_s2vu
[Occ=Once] _ [Occ=Dead] ->
ww5_s2vu;
};
} in
TransPort.$wtransPort
lvl2_r2ut
lvl2_r2ut
lvl2_r2ut
lvl2_r2ut
lvl1_r2us
lvl2_r2ut
lvl1_r2us
w1_s2uz
ww2_s2vk
lvl_r2ur
sat_s2vw
ww17_s2vn
ww19_s2vp
ww22_s2vs;
}}}
The relevant code for `$wtransPort` ist
{{{
TransPort.$wtransPort [InlPrag=[0], Occ=LoopBreaker]
:: GamtebType.Coord
-> GamtebType.Coord
-> GamtebType.Coord
-> GamtebType.Coord
-> GamtebType.Coord
-> GamtebType.Coord
-> GamtebType.Weight
-> GamtebType.Energy
-> GamtebType.Indx
-> GHC.Types.Int
-> GamtebType.Random
-> GamtebType.Prob
-> GamtebType.Prob
-> GHC.Prim.Double#
-> (# [GamtebType.Result], [GamtebType.Stat] #)
[GblId,
Arity=14,
Str=DmdType
<L,U(U)><L,U(U)><L,U(U)><L,U(U)><L,U(U)><L,U(U)><L,U(U)><L,U(U)><L,U><L,U(U)><L,1*U(U)><L,U(U)><L,U(U)><S,U>,
Unf=OtherCon []] =
\r srt:SRT:[r4K :-> Utils.$wgenRand, r5x :-> Compton.$wcompton,
r5O :-> Pair.$wpair, r3Df :-> TransPort.$wtransPort,
r3Dr :-> lvl11_r3Dr] [ww_s3Dy
ww1_s3Dz
ww2_s3DA
ww3_s3DB
ww4_s3DC
ww5_s3DD
ww6_s3DE
ww7_s3DF
ww8_s3DG
ww9_s3DH
ww10_s3DI
ww11_s3DJ
ww12_s3DK
ww13_s3DL]
case Utils.$wgenRand ww10_s3DI of _ [Occ=Dead] {
(#,#) ww15_s3DN [Occ=Once!] ww16_s3DO ->
}}}
Note how the strictness signature say that the `Random` argument is used
at most once (`1*U(U)`). The call to `$wgenRand` is indeed the only use of
`ww10_s3DI`. So here is the code of `$wgenRand`:
{{{
Utils.$wgenRand [InlPrag=[0]]
:: GamtebType.Random -> (# GamtebType.Random, GamtebType.Random #)
[GblId, Arity=1, Str=DmdType <L,U(U)>, Unf=OtherCon []] =
\r srt:SRT:[015 :-> GHC.Integer.Type.timesInteger,
017 :-> GHC.Integer.Type.negateInteger,
01j :-> GHC.Integer.Type.divInteger,
01x :-> GHC.Integer.Type.shiftLInteger] [w_s3BX]
let {
sat_s3CT [Occ=Once] :: GamtebType.Random
[LclId, Str=DmdType] =
\u srt:SRT:[015 :-> GHC.Integer.Type.timesInteger,
017 :-> GHC.Integer.Type.negateInteger,
01j :-> GHC.Integer.Type.divInteger,
01x :-> GHC.Integer.Type.shiftLInteger] []
case w_s3BX of _ [Occ=Dead] {
GHC.Types.D# y_s3Cs [Occ=Once] ->
...
}; } in
let {
sat_s3Cq [Occ=Once] :: GamtebType.Random
[LclId, Str=DmdType] =
\u srt:SRT:[015 :-> GHC.Integer.Type.timesInteger,
017 :-> GHC.Integer.Type.negateInteger,
01j :-> GHC.Integer.Type.divInteger,
01x :-> GHC.Integer.Type.shiftLInteger] []
case w_s3BX of _ [Occ=Dead] {
GHC.Types.D# y_s3BZ [Occ=Once] ->
...
};
} in (#,#) [sat_s3Cq sat_s3CT];
}}}
So `$wgenRand` may evaluate its argument more than once (as its strictness
signature says). On what grounds does `$wtransPort` then claim the
argument is used at most once?
Now if the argument to `$wgenRand` were a complex expression, this would
be valid reasoning, as it would be let-bound and then shared. But trivial
expressions, when passed as arguments, are _not_ shared at this point, so
the information that the argument may be used multiple times should be
propagated out.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11731#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list