Perhaps ghc-bignum "primitives" should be allowed to inline.
There are various rules for conversions between types that generally work well.
However for a patch of mine the rules failed to fire and I saw things like this expression.
(case GHC.Num.Integer.$wintegerToWord#
(case i_aN8 of { GHC.Types.I# i_a2i7 ->
GHC.Num.Integer.IS i_a2i7
})
If integerToWord would be allowed to inline this would still compile to a no-op.
Now I wonder if we could run into similar situations with user-defined numeric types. Can these cause rules to fail to fire and can we then end up in the same situation?
I don't have code where it does happen (outside of my patch) currently. But I thought @hsyl20 might be able to say if this should be a concern or not without spending too much time on it.
(Edit by @hsyl20)
The idea would be to only keep BigNat# primitives opaque but to allow Integer/Natural primitives to inline.
List of ghc-bignum primitives that are not inlined:
- Natural
-
naturalFromBigNat# - won't do as it uses BigNat# internals -
naturalToBigNat# - need constant folding for bigNatFromWord# -
naturalToWord# - need constant folding for bigNatIndex# -
naturalToWordClamp# - just inline -
naturalGe# - need constant folding for bigNatGe# (or just bigNatCompare?) -
naturalLe# - need constant folding for bigNatLe# (ditto) -
naturalGt# - need constant folding for bigNatGt# (ditto) -
naturalLt# - need constant folding for bigNatLt# (ditto) -
naturalCompare - need constant folding for bigNatCompare -
naturalPopCount# - need constant folding for bigNatPopCount# -
naturalShiftR# - need constant folding for bigNatShiftR# -
naturalShiftL# - need constant folding for bigNatShiftL# (clz# should already be done) -
naturalAdd - need constant folding for addWordC# (not sure if we have it), bigNatFromWord2#, bigNatAddWord# and bigNatAdd -
naturalSub - need constant folding for bigNatSubWordUnsafe#, subWordC#, bigNatSub -
naturalSubThrow - rewrite using naturalSub -
naturalSubUnsafe - c-f for bigNatSubWordUnsafe#, bigNatSub -
naturalMul - put 0/1 tests in new naturalMulWord#, need constant folding for naturalFromWord2# -
naturalMulWord (new) - need constant folding for bigNatMul, bigNatMulWord# -
naturalSignum - just inline -
naturalNegate - just inline -
naturalQuotRem - need constant folding for bigNatQuotRemWord#, bigNatQuotRem# -
naturalQuot - need constant folding for bigNatQuotWord#, bigNatQuot -
naturalRem - need constant folding for bigNatRemWord#, bigNatRem -
naturalAnd - need constant folding for bigNatToWord#, bigNatAnd -
naturalAndNot, naturalOr, naturalXor - similar to naturalAnd -
naturalTestBit# - need constant folding for bigNatTestBit# -
naturalBit# - need constant folding for bigNatBit# -
naturalGcd - need constant folding for gcdWord#, bigNatGcdWord#, bigNatGcd -
naturalLcm - need constant folding for bigNatLcmWordWord#, bigNatLcmWord#, bigNatLcm -
naturalLog2# - need constant folding for bigNatLog2 -
naturalLogBaseWord# - need constant folding for wordLogBase#, bigNatLogBaseWord# -
naturalLogBase# - need constant folding for bigNatLogBase# -
naturalPowMod - need constant folding for powModWord#, bigNatPowModWord#, bigNatPowMod -
naturalSizeInBase# - need constant folding for wordLogBase#, bigNatSizeInBase# -
naturalToAddr# - just inline and make bigNatToAddrLE/BE# NOINLINE -
naturalFromAddr# - just inline and make bigNatFromAddrLE/BE# NOINLINE -
naturalToMutableByteArray# - just inline and make bigNatToMutableByteArrayLE/BE# NOINLINE -
naturalFromByteArray# - just inline and make bigNatFromByteArrayLE/BE# NOINLINE
-
- Integer
-
integerToInt# - need cf bigNatToWord# -
integerFromWord# - need cf for bigNatFromWord# -
integerToWord# - need cf for bigNatToWord# -
integerFromNatural - just inline (relies on integerFromWord#) -
integerToNaturalClamp - need cf for naturalFromBigNat#, naturalFromWord# -
integerToNatural - need cf for naturalFromBigNat#, naturalFromWord# -
integerToNaturalThrow - need cf for naturalFromWord#, naturalFromBigNat# -
integerEq# - need cf for bigNatEq# -
integerNe# - need cf for bigNatNe# -
integerGt#/Le/Lt/Ge - just inline (relies on integerCompare) -
integerCompare - merge integerCompare/Compare', just inline, need cf for bigNatCompare -
integerSub - quite big, maybe split fast/slow path. need cf for bigNatSubWordUnsafe#, bigNatSubUnsafe, bigNatAdd, subIntC#, bigNatCompare, bigNatAddWord#... -
integerAdd - ditto -
integerMul - remove CPP (we always build with stage1 which is >= 8.11). maybe split. need cf for bigNatMul, bigNatMulWord#, timesInt2#... -
integerNegate - need cf for bigNatFromWord#, bigNatEqWord# -
integerAbs - just inline -
integerSignum[#] - just inline -
integerPopCount# - need cf for popCntI#, bigNatPopCount# -
integerBit# - need cf for bigNatBit# -
integerTestBit# - put negative case in a noinline helper. need cf for bigNatTestBit# -
integerShiftR# - need cf for bigNatShiftR#, bigNatShiftRNeg# -
integerShiftL# - need cf for bigNatShiftL#, relies on integerBit# -
integerOr - add helper integerOrInt#, split negative case?. need cf for bigNatOrWord#, bigNatAndNot, bigNatAddWord#, bigNatSub... -
integerXor, integerAnd - ditto -
integerComplement - need cf for bigNatAddWord#, bigNatSubWordUnsafe# -
integerQuotRem# - need cf for bigNatQuotRemWord#, bigNatQuotRem#. Quite big... -
integerQuot, integerRem - similar to integerQuotRem# -
integerDivMod# - just inline, relies on integerSignum#, integerSub, integerAdd, integerQuotRem# -
integerDiv - just inline, relies in integerQuot, integerDivMod# -
integerMod - ditto, relies on integerRem -
integerGcd - add integerGcdInt# helper to remove recursive call. need cf for bigNatGcd, bigNatGcdWord#, gcdWord#. Relies on integerAbs -
integerLcm - inline, relies on integerAbs, integerQuot, integerGcd, integerMul -
integerFromInt64#, integerFromWord64# - need cf for bigNatFromWord64# -
integerToInt64#, integerToWord64# - need cf for bigNatToWord64# -
integerEncodeDouble#, integerEncodeFloat# - why is that even here? put this in base with bigNatEncodeDouble# and intEncodeDouble#.
-