Unnecessary reboxing when using INLINABLE
The intent of the attached library and test harness is to use INLINABLE
to generate a specialized lookup
function at always passes the key as an unboxed Int#
. However, when compiled with
ghc -O2 -fregs-graph -ddump-simpl Test.hs
we can see that there's reboxing (look for allocation of an I#
constructor) going on. I wonder if this is related to the new INLINABLE
specialization. If all INLINABLE
in Data.FullList
are replaced by INLINE
, no reboxing occurs.
Below is a cleaned up version of the Core for the Test
module. The reboxing occurs in $wpoly_go1_rIB
, in the call to $slookup_$slookupL
.
test1 :: Int
test1 = I# 1
$wpoly_go_rIx :: forall v. Int# -> FL.List Int v -> Maybe v
$wpoly_go_rIx =
\ (@ v)
(ww_sHY :: Int#)
(w_sI0 :: FL.List Int v) ->
case w_sI0 of _ {
FL.Nil -> Nothing @ v;
FL.Cons ipv_iGX ipv1_iGY ipv2_iGZ ->
case ipv_iGX of _ { I# y_iHB ->
case ==# ww_sHY y_iHB of _ {
False -> $wpoly_go_rIx @ v ww_sHY ipv2_iGZ;
True -> Just @ v ipv1_iGY
}
}
}
poly_go_rIz :: forall v. Int -> FL.List Int v -> Maybe v
poly_go_rIz =
\ (@ v)
(w_sHW :: Int)
(w1_sI0 :: FL.List Int v) ->
case w_sHW of _ { I# ww_sHY ->
$wpoly_go_rIx @ v ww_sHY w1_sI0
}
$slookup_$slookupL :: forall v. Int -> FL.List Int v -> Maybe v
$slookup_$slookupL = poly_go_rIz
$wpoly_go1_rIB :: forall v. Int# -> Int# -> M.HashMap Int v -> Maybe v
$wpoly_go1_rIB =
\ (@ v)
(ww_sI7 :: Int#)
(ww1_sIb :: Int#)
(w_sId :: M.HashMap Int v) ->
case w_sId of _ {
M.Nil -> Nothing @ v;
M.Tip rb_iFO rb1_iFP rb2_iFW rb3_iFX ->
case ==# ww_sI7 rb_iFO of _ {
False -> Nothing @ v;
True ->
case rb1_iFP of _ { I# y_iHB ->
case ==# ww1_sIb y_iHB of _ {
False -> $slookup_$slookupL @ v (I# ww1_sIb) rb3_iFX;
True -> Just @ v rb2_iFW
}
}
};
M.Bin _ rb1_iGj l_iGk r_iGl ->
case eqWord#
(and#
(int2Word# ww_sI7) (int2Word# rb1_iGj))
__word 0
of _ {
False -> $wpoly_go1_rIB @ v ww_sI7 ww1_sIb r_iGl;
True -> $wpoly_go1_rIB @ v ww_sI7 ww1_sIb l_iGk
}
}
poly_go1_rID :: forall v. M.Hash -> Int -> M.HashMap Int v -> Maybe v
poly_go1_rID =
\ (@ v)
(w_sI5 :: M.Hash)
(w1_sI9 :: Int)
(w2_sId :: M.HashMap Int v) ->
case w_sI5 of _ { I# ww_sI7 ->
case w1_sI9 of _ { I# ww1_sIb ->
$wpoly_go1_rIB @ v ww_sI7 ww1_sIb w2_sId
}
}
$slookup :: forall v. Int -> M.HashMap Int v -> Maybe v
$slookup =
\ (@ v)
(k0_iFA :: Int)
(t_iFB :: M.HashMap Int v) ->
poly_go1_rID @ v k0_iFA k0_iFA t_iFB
test :: M.HashMap Int Int -> Maybe Int
test =
\ (m_aBp :: M.HashMap Int Int) ->
$slookup @ Int test1 m_aBp
------ Local rules for imported ids --------
"SPEC FL.lookupL [Int]" [ALWAYS]
forall {@ v_iGO $dEq_sHl :: Eq Int}
FL.lookupL @ Int @ v_iGO $dEq_sHl
= $slookup_$slookupL @ v_iGO
"SPEC M.lookup [Int]" [ALWAYS]
forall {@ v_iFx
$dEq_sHm :: Eq Int
$dHashable_sHn :: Data.Hashable.Hashable Int}
M.lookup @ Int @ v_iFx $dEq_sHm $dHashable_sHn
= $slookup @ v_iFx
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |