我正在尝试使用不同的代码流融合方法
sum (filter even [0..n])
并达到了我期望构造函数专业化(使用-O2
等)的地步,但似乎没有发挥作用。
有了-ddump-simpl
,我得到了以下核心:
Rec {
-- RHS size: {terms: 33, types: 10, coercions: 0}
Main.main_go [Occ=LoopBreaker] :: Int -> RangeToState -> Int
[GblId, Arity=2, Caf=NoCafRefs, Str=DmdType]
Main.main_go =
\ (z_a1Nf :: Int) (s1_a1Ng :: RangeToState) ->
case s1_a1Ng of _ [Occ=Dead] { RangeToState ipv_s7O5 ipv1_s7O6 ->
case z_a1Nf of z1_X1NN { GHC.Types.I# ipv2_s7O9 ->
case GHC.Prim.tagToEnum# @ Bool (GHC.Prim.<# ipv_s7O5 ipv1_s7O6)
of _ [Occ=Dead] {
False -> z1_X1NN;
True ->
Main.main_go
(case GHC.Prim.remInt# ipv_s7O5 2# of _ [Occ=Dead] {
__DEFAULT -> z1_X1NN;
0# -> GHC.Types.I# (GHC.Prim.+# ipv2_s7O9 ipv_s7O5)
})
(Producer.RangeToState (GHC.Prim.+# ipv_s7O5 1#) ipv1_s7O6)
}
}
}
end Rec }
(带有data RangeToState = RangeToState {-# UNPACK #-} !Int {-# UNPACK #-} !Int
。)
我本来希望RangeToState
和I#
被淘汰,并且当我将Core从上面手动转换回基本的Haskell时:
foo2 = \ (z :: Int) (s :: RangeToState) ->
case s of
RangeToState i n -> z `seq` case i < n of
False -> z
True -> foo2 (if even i then i + z else z)
(RangeToState (i+1) n)
确实确实编译成无分配循环:
Rec {
-- RHS size: {terms: 31, types: 6, coercions: 0}
Producer.$wfoo2 [InlPrag=[0], Occ=LoopBreaker]
:: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=3, Caf=NoCafRefs, Str=DmdType <L,U><S,U><S,U>]
Producer.$wfoo2 =
\ (ww_s4gO :: GHC.Prim.Int#)
(ww1_s4gS :: GHC.Prim.Int#)
(ww2_s4gT :: GHC.Prim.Int#) ->
case GHC.Prim.tagToEnum# @ Bool (GHC.Prim.<# ww1_s4gS ww2_s4gT)
of _ [Occ=Dead] {
False -> ww_s4gO;
True ->
case GHC.Prim.remInt# ww1_s4gS 2# of _ [Occ=Dead] {
__DEFAULT ->
Producer.$wfoo2 ww_s4gO (GHC.Prim.+# ww1_s4gS 1#) ww2_s4gT;
0# ->
Producer.$wfoo2
(GHC.Prim.+# ww1_s4gS ww_s4gO) (GHC.Prim.+# ww1_s4gS 1#) ww2_s4gT
}
}
end Rec }
我的编译选项仅为ghc -O2 -fforce-recomp -ddump-simpl
,并且我正在使用GHC 8.0.2。
是什么阻止第一版代码进一步编译为第二版?