How to prevent this optimization?
Here is a simplified snippet:
{-# LANGUAGE UnboxedTuples, MagicHash #-}
module Lib where
import Data.Array.Byte
import GHC.Exts
import GHC.ST
newInherit :: ByteArray -> Int -> ByteArray
newInherit (ByteArray dst#) (I# len#) = runST $ ST $ \s ->
let (# s', newM #) = (case isByteArrayPinned# dst# of
0# -> newByteArray# len# s
_ -> newPinnedByteArray# len# s) in
let (# s'', new #) = unsafeFreezeByteArray# newM s' in
(# s'', ByteArray new #)
I'm very keen to preserve this code structure as is: namely, do not propagate unsafeFreezeByteArray#
into branches of isByteArrayPinned#
. The reason is that in the actual program (https://github.com/Bodigrim/linear-builder/issues/4#issuecomment-1465331108) there is more action other than just freezing, which gets unnecessary duplicated.
However, GHC is very stubborn to emit this:
(\ (s1_aBL :: State# s_aCj) ->
case isByteArrayPinned# dst#_aBJ of ds2_dDh { __DEFAULT ->
case ds2_dDh of {
__DEFAULT ->
case newPinnedByteArray# @s_aCj len#_aBK s1_aBL of
{ (# ipv_sDs, ipv1_sDt #) ->
case unsafeFreezeByteArray# @s_aCj ipv1_sDt ipv_sDs of
{ (# ipv2_sDo, ipv3_sDp #) ->
(# ipv2_sDo, Data.Array.Byte.ByteArray ipv3_sDp #)
}
};
0# ->
case newByteArray# @s_aCj len#_aBK s1_aBL of
{ (# ipv_sDv, ipv1_sDw #) ->
case unsafeFreezeByteArray# @s_aCj ipv1_sDw ipv_sDv of
{ (# ipv2_sDo, ipv3_sDp #) ->
(# ipv2_sDo, Data.Array.Byte.ByteArray ipv3_sDp #)
}
}
}
})
The only way to avoid it seems to pass -fmax-simplifier-iterations=0
obtaining
(\ (s1_aBL :: State# s_aCj) ->
case case isByteArrayPinned# dst#_aBJ of ds2_dDh { __DEFAULT ->
case ds2_dDh of {
__DEFAULT -> newPinnedByteArray# @s_aCj len#_aBK s1_aBL;
0# -> newByteArray# @s_aCj len#_aBK s1_aBL
}
}
of ds2_dDn
{ __DEFAULT ->
case ds2_dDn of { (# s'_aCy, newM_aCz #) ->
case unsafeFreezeByteArray# @s_aCj newM_aCz s'_aCy of ds3_dDg
{ __DEFAULT ->
case ds3_dDg of { (# s''_aCH, new_aCI #) ->
(# s''_aCH, Data.Array.Byte.ByteArray new_aCI #)
}
}
}
})
But in not-so-toy example -fmax-simplifier-iterations=0
is not an option.
Is there anything else I can do? Any trick to explain to GHC what I want?