Gratuitous code bloat due to `postInlineUnconditionally`
Consider this small program:
module Foo where
sORTKind_maybe :: TyCon -> String
sORTKind_maybe tc
-- First, short-cuts for Type and Constraint that do no allocation
| tc_uniq == 1 = "one"
| tc_uniq == 2 = "two"
| tc_uniq == 3 = "three"
| tc_uniq == 4 = "four"
where
tc_uniq = tyConUnique tc
sORTKind_maybe _ = "five"
data TyCon = A Int | B Int | C Int | D Int | E Int | F Int | G Int
tyConUnique (A i) = i
tyConUnique (B i) = i
tyConUnique (C i) = i
tyConUnique (D i) = i
tyConUnique (E i) = i
tyConUnique (F i) = i
tyConUnique (G i) = i
We hope to get code like
sORT_Kind_maybe tc
= case tyConUnique tc of
1# -> "one"
2# -> "two"
3# -> "three"
4# -> "four"
_ -> "five"
But no; we get this giant mess
sORTKind_maybe :: TyCon -> String
[GblId, Arity=1, Str=<SL>, Unf=OtherCon []]
sORTKind_maybe
= \ (tc_aum :: TyCon) ->
join {
$j_sNu [Dmd=1C(1,L)] :: GHC.Prim.Int# -> [Char]
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<1L>, Unf=OtherCon []]
$j_sNu (x_aNj [OS=OneShot] :: GHC.Prim.Int#)
= case x_aNj of {
__DEFAULT ->
join {
$j1_sNs [Dmd=1C(1,L)] :: GHC.Prim.Int# -> [Char]
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<1L>, Unf=OtherCon []]
$j1_sNs (x1_X3 [OS=OneShot] :: GHC.Prim.Int#)
= case x1_X3 of {
__DEFAULT ->
join {
$j2_sNq [Dmd=1C(1,L)] :: GHC.Prim.Int# -> [Char]
[LclId[JoinId(1)(Nothing)], Arity=1, Str=<1L>, Unf=OtherCon []]
$j2_sNq (x2_X6 [OS=OneShot] :: GHC.Prim.Int#)
= case x2_X6 of {
__DEFAULT ->
case tc_aum of {
A i_aG3 ->
case i_aG3 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
B i_aG4 ->
case i_aG4 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
C i_aG5 ->
case i_aG5 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
D i_aG6 ->
case i_aG6 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
E i_aG7 ->
case i_aG7 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
F i_aG8 ->
case i_aG8 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
};
G i_aG9 ->
case i_aG9 of { GHC.Types.I# x3_Xa ->
case x3_Xa of {
__DEFAULT -> lvl1_rNL;
4# -> lvl3_rNN
}
}
};
3# -> lvl5_rNP
} } in
case tc_aum of {
A i_aG3 ->
case i_aG3 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
B i_aG4 ->
case i_aG4 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
C i_aG5 ->
case i_aG5 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
D i_aG6 ->
case i_aG6 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
E i_aG7 ->
case i_aG7 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
F i_aG8 ->
case i_aG8 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 };
G i_aG9 ->
case i_aG9 of { GHC.Types.I# x2_X7 -> jump $j2_sNq x2_X7 }
};
2# -> lvl7_rNR
} } in
case tc_aum of {
A i_aG3 ->
case i_aG3 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
B i_aG4 ->
case i_aG4 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
C i_aG5 ->
case i_aG5 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
D i_aG6 ->
case i_aG6 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
E i_aG7 ->
case i_aG7 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
F i_aG8 ->
case i_aG8 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 };
G i_aG9 ->
case i_aG9 of { GHC.Types.I# x1_X4 -> jump $j1_sNs x1_X4 }
};
1# -> lvl9_rNT
} } in
case tc_aum of {
A i_aG3 ->
case i_aG3 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
B i_aG4 ->
case i_aG4 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
C i_aG5 ->
case i_aG5 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
D i_aG6 ->
case i_aG6 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
E i_aG7 ->
case i_aG7 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
F i_aG8 ->
case i_aG8 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj };
G i_aG9 ->
case i_aG9 of { GHC.Types.I# x_aNj -> jump $j_sNu x_aNj }
}
This is stupid. I think it's because we are too aggressive about
Note [Inline small things to avoid creating a thunk]
in postInlineUnconditionally
in GHC.Core.Opt.Simplify.Utils.