Skip to content

bytestring Builder performance regressions after 9.2.3

While testing the performance characteristics of a bytestring patch meant to mitigate withForeignPtr-related performance regressions, it was noticed that several of our Builder-related benchmarks have also regressed seriously for unrelated reasons. The worst offender is byteStringHex, which on my machine runs about 10 times slower and allocates 21 times as much when using ghc-9.2.4 or ghc-9.4.2 as it did when using ghc-9.2.3. Here's a small program that can demonstrate this slowdown:

Click to expand
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Builder as B

str :: S.ByteString
str = S.replicate 100000000 32

main :: IO ()
main = print $ L.length $ B.toLazyByteString $ B.byteStringHex str

Looking at the simplified Core generated while compiling Data.ByteString.Builder.ASCII, it is clear that the culprit for this particular example is the local function go in Data.ByteString.Builder.Prim.primMapByteStringBounded. With 9.2.3, it is extracted as a join point of type $wgo :: Addr# -> Addr# -> State# RealWorld -> (# State# RealWorld, BuildSignal r #), while with 9.2.4, it keeps the type $wgo :: Addr# -> Addr# -> IO (BuildSignal r). Seemingly as a result, its recursive call in 9.2.4 lives in a lambda that ends up being allocated as a function closure after each byte processed. With ghc-9.2.4, every call site of $wgo_s6Gq has two arguments, a cast, and one more argument. Why isn't it being eta-expanded?

9.2.3 simplified Core for byteStringHex
-- RHS size: {terms: 276, types: 242, coercions: 10, joins: 4/10}
Data.ByteString.Builder.ASCII.$wbyteStringHex [InlPrag=NOINLINE]
  :: GHC.Prim.Addr#
     -> GHC.ForeignPtr.ForeignPtrContents
     -> GHC.Prim.Int#
     -> forall {r}.
        Data.ByteString.Builder.Internal.BuildStep r
        -> GHC.Prim.Addr#
        -> GHC.Prim.Addr#
        -> GHC.Prim.State# GHC.Prim.RealWorld
        -> (# GHC.Prim.State# GHC.Prim.RealWorld,
              Data.ByteString.Builder.Internal.BuildSignal r #)
[GblId,
 Arity=7,
 Str=<L><L><L><1CL(C1(L))><L><L><L>,
 Unf=OtherCon []]
Data.ByteString.Builder.ASCII.$wbyteStringHex
  = \ (ww_s6H2 :: GHC.Prim.Addr#)
      (ww1_s6H3 :: GHC.ForeignPtr.ForeignPtrContents)
      (ww2_s6H4 :: GHC.Prim.Int#)
      (@r_s6GW)
      (w_s6GX :: Data.ByteString.Builder.Internal.BuildStep r_s6GW)
      (ww3_s6H8 :: GHC.Prim.Addr#)
      (ww4_s6H9 :: GHC.Prim.Addr#)
      (w1_s6GZ :: GHC.Prim.State# GHC.Prim.RealWorld) ->
      case w_s6GX of k_i6el { __DEFAULT ->
      let {
        ipe_s6CI :: GHC.Prim.Addr#
        [LclId]
        ipe_s6CI = GHC.Prim.plusAddr# ww_s6H2 ww2_s6H4 } in
      letrec {
        $wgoBS_s6GU [InlPrag=[2], Occ=LoopBreaker, Dmd=SCS(C1(C1(C1(L))))]
          :: GHC.Prim.Addr#
             -> GHC.Prim.Addr#
             -> GHC.Prim.Addr#
             -> GHC.Prim.State# GHC.Prim.RealWorld
             -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                   Data.ByteString.Builder.Internal.BuildSignal r_s6GW #)
        [LclId, Arity=4, Str=<L><L><L><L>, Unf=OtherCon []]
        $wgoBS_s6GU
          = \ (ww5_s6GN :: GHC.Prim.Addr#)
              (ww6_s6GR :: GHC.Prim.Addr#)
              (ww7_s6GS :: GHC.Prim.Addr#)
              (w2_s6GK :: GHC.Prim.State# GHC.Prim.RealWorld) ->
              case GHC.Prim.ltAddr# ww5_s6GN ipe_s6CI of {
                __DEFAULT ->
                  case GHC.Prim.touch#
                         @GHC.Types.LiftedRep
                         @GHC.ForeignPtr.ForeignPtrContents
                         ww1_s6H3
                         w2_s6GK
                  of s'_i6eA
                  { __DEFAULT ->
                  ((k_i6el
                      (Data.ByteString.Builder.Internal.BufferRange ww6_s6GR ww7_s6GS))
                   `cast` (GHC.Types.N:IO[0]
                               <Data.ByteString.Builder.Internal.BuildSignal r_s6GW>_R
                           :: IO (Data.ByteString.Builder.Internal.BuildSignal r_s6GW)
                              ~R# (GHC.Prim.State# GHC.Prim.RealWorld
                                   -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                         Data.ByteString.Builder.Internal.BuildSignal r_s6GW #))))
                    s'_i6eA
                  };
                1# ->
                  case GHC.Prim.ltAddr# ww7_s6GS (GHC.Prim.plusAddr# ww6_s6GR 2#)
                  of {
                    __DEFAULT ->
                      let {
                        x1_i6eI :: GHC.Prim.Int#
                        [LclId]
                        x1_i6eI
                          = GHC.Prim.uncheckedIShiftRA#
                              (GHC.Prim.minusAddr# ww7_s6GS ww6_s6GR) 1# } in
                      let {
                        y1_s6CM :: GHC.Prim.Int#
                        [LclId]
                        y1_s6CM = GHC.Prim.minusAddr# ipe_s6CI ww5_s6GN } in
                      case GHC.Prim.<=# x1_i6eI y1_s6CM of {
                        __DEFAULT ->
                          let {
                            ipeTmp_s6CQ :: GHC.Prim.Addr#
                            [LclId]
                            ipeTmp_s6CQ = GHC.Prim.plusAddr# ww5_s6GN y1_s6CM } in
                          join {
                            exit_X0 [Dmd=SCS(C1(C1(L)))]
                              :: GHC.Prim.Addr#
                                 -> GHC.Prim.Addr#
                                 -> GHC.Prim.State# GHC.Prim.RealWorld
                                 -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                       Data.ByteString.Builder.Internal.BuildSignal r_s6GW #)
                            [LclId[JoinId(3)], Arity=3, Str=<L><L><L>]
                            exit_X0 (ww8_s6GA [OS=OneShot] :: GHC.Prim.Addr#)
                                    (ww9_s6GE [OS=OneShot] :: GHC.Prim.Addr#)
                                    (w3_s6Gx [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld)
                              = $wgoBS_s6GU ww8_s6GA ww9_s6GE ww7_s6GS w3_s6Gx } in
                          case GHC.Prim.ltAddr# ww5_s6GN ipeTmp_s6CQ of {
                            __DEFAULT -> jump exit_X0 ww5_s6GN ww6_s6GR w2_s6GK;
                            1# ->
                              case GHC.Prim.readWord8OffAddr#
                                     @GHC.Prim.RealWorld ww5_s6GN 0# w2_s6GK
                              of
                              { (# ipv3_i6eZ, ipv4_i6f0 #) ->
                              case Data.ByteString.Builder.Prim.Internal.Base16.lowerTable of
                              { Data.ByteString.Builder.Prim.Internal.Base16.EncodingTable table_i6dI ->
                              case GHC.Prim.readWord16OffAddr#
                                     @GHC.Prim.RealWorld
                                     table_i6dI
                                     (GHC.Prim.word2Int# (GHC.Prim.word8ToWord# ipv4_i6f0))
                                     ipv3_i6eZ
                              of
                              { (# ipv_i6dO, ipv1_i6dP #) ->
                              case GHC.Prim.writeWord16OffAddr#
                                     @GHC.Prim.RealWorld ww6_s6GR 0# ipv1_i6dP ipv_i6dO
                              of s2_i6dU
                              { __DEFAULT ->
                              joinrec {
                                $wgo_s6GG [InlPrag=[2], Occ=LoopBreaker, Dmd=SCS(C1(C1(L)))]
                                  :: GHC.Prim.Addr#
                                     -> GHC.Prim.Addr#
                                     -> GHC.Prim.State# GHC.Prim.RealWorld
                                     -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                           Data.ByteString.Builder.Internal.BuildSignal r_s6GW #)
                                [LclId[JoinId(3)], Arity=3, Str=<L><L><L>, Unf=OtherCon []]
                                $wgo_s6GG (ww8_X1 :: GHC.Prim.Addr#)
                                          (ww9_X2 :: GHC.Prim.Addr#)
                                          (w3_X3 :: GHC.Prim.State# GHC.Prim.RealWorld)
                                  = case GHC.Prim.ltAddr# ww8_X1 ipeTmp_s6CQ of {
                                      __DEFAULT -> jump exit_X0 ww8_X1 ww9_X2 w3_X3;
                                      1# ->
                                        case GHC.Prim.readWord8OffAddr#
                                               @GHC.Prim.RealWorld ww8_X1 0# w3_X3
                                        of
                                        { (# ipv2_X6, ipv6_X7 #) ->
                                        case GHC.Prim.readWord16OffAddr#
                                               @GHC.Prim.RealWorld
                                               table_i6dI
                                               (GHC.Prim.word2Int# (GHC.Prim.word8ToWord# ipv6_X7))
                                               ipv2_X6
                                        of
                                        { (# ipv7_Xa, ipv8_Xb #) ->
                                        case GHC.Prim.writeWord16OffAddr#
                                               @GHC.Prim.RealWorld ww9_X2 0# ipv8_Xb ipv7_Xa
                                        of s1_Xc
                                        { __DEFAULT ->
                                        jump $wgo_s6GG
                                          (GHC.Prim.plusAddr# ww8_X1 1#)
                                          (GHC.Prim.plusAddr# ww9_X2 2#)
                                          s1_Xc
                                        }
                                        }
                                        }
                                    }; } in
                              jump $wgo_s6GG
                                (GHC.Prim.plusAddr# ww5_s6GN 1#)
                                (GHC.Prim.plusAddr# ww6_s6GR 2#)
                                s2_i6dU
                              }
                              }
                              }
                              }
                          };
                        1# ->
                          let {
                            ipeTmp_s6CQ :: GHC.Prim.Addr#
                            [LclId]
                            ipeTmp_s6CQ = GHC.Prim.plusAddr# ww5_s6GN x1_i6eI } in
                          join {
                            exit_X0 [Dmd=SCS(C1(C1(L)))]
                              :: GHC.Prim.Addr#
                                 -> GHC.Prim.Addr#
                                 -> GHC.Prim.State# GHC.Prim.RealWorld
                                 -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                       Data.ByteString.Builder.Internal.BuildSignal r_s6GW #)
                            [LclId[JoinId(3)], Arity=3, Str=<L><L><L>]
                            exit_X0 (ww8_s6GA [OS=OneShot] :: GHC.Prim.Addr#)
                                    (ww9_s6GE [OS=OneShot] :: GHC.Prim.Addr#)
                                    (w3_s6Gx [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld)
                              = $wgoBS_s6GU ww8_s6GA ww9_s6GE ww7_s6GS w3_s6Gx } in
                          case GHC.Prim.ltAddr# ww5_s6GN ipeTmp_s6CQ of {
                            __DEFAULT -> jump exit_X0 ww5_s6GN ww6_s6GR w2_s6GK;
                            1# ->
                              case GHC.Prim.readWord8OffAddr#
                                     @GHC.Prim.RealWorld ww5_s6GN 0# w2_s6GK
                              of
                              { (# ipv3_i6eZ, ipv4_i6f0 #) ->
                              case Data.ByteString.Builder.Prim.Internal.Base16.lowerTable of
                              { Data.ByteString.Builder.Prim.Internal.Base16.EncodingTable table_i6dI ->
                              case GHC.Prim.readWord16OffAddr#
                                     @GHC.Prim.RealWorld
                                     table_i6dI
                                     (GHC.Prim.word2Int# (GHC.Prim.word8ToWord# ipv4_i6f0))
                                     ipv3_i6eZ
                              of
                              { (# ipv_i6dO, ipv1_i6dP #) ->
                              case GHC.Prim.writeWord16OffAddr#
                                     @GHC.Prim.RealWorld ww6_s6GR 0# ipv1_i6dP ipv_i6dO
                              of s2_i6dU
                              { __DEFAULT ->
                              joinrec {
                                $wgo_s6GG [InlPrag=[2], Occ=LoopBreaker, Dmd=SCS(C1(C1(L)))]
                                  :: GHC.Prim.Addr#
                                     -> GHC.Prim.Addr#
                                     -> GHC.Prim.State# GHC.Prim.RealWorld
                                     -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                           Data.ByteString.Builder.Internal.BuildSignal r_s6GW #)
                                [LclId[JoinId(3)], Arity=3, Str=<L><L><L>, Unf=OtherCon []]
                                $wgo_s6GG (ww8_X1 :: GHC.Prim.Addr#)
                                          (ww9_X2 :: GHC.Prim.Addr#)
                                          (w3_X3 :: GHC.Prim.State# GHC.Prim.RealWorld)
                                  = case GHC.Prim.ltAddr# ww8_X1 ipeTmp_s6CQ of {
                                      __DEFAULT -> jump exit_X0 ww8_X1 ww9_X2 w3_X3;
                                      1# ->
                                        case GHC.Prim.readWord8OffAddr#
                                               @GHC.Prim.RealWorld ww8_X1 0# w3_X3
                                        of
                                        { (# ipv2_X6, ipv6_X7 #) ->
                                        case GHC.Prim.readWord16OffAddr#
                                               @GHC.Prim.RealWorld
                                               table_i6dI
                                               (GHC.Prim.word2Int# (GHC.Prim.word8ToWord# ipv6_X7))
                                               ipv2_X6
                                        of
                                        { (# ipv7_Xa, ipv8_Xb #) ->
                                        case GHC.Prim.writeWord16OffAddr#
                                               @GHC.Prim.RealWorld ww9_X2 0# ipv8_Xb ipv7_Xa
                                        of s1_Xc
                                        { __DEFAULT ->
                                        jump $wgo_s6GG
                                          (GHC.Prim.plusAddr# ww8_X1 1#)
                                          (GHC.Prim.plusAddr# ww9_X2 2#)
                                          s1_Xc
                                        }
                                        }
                                        }
                                    }; } in
                              jump $wgo_s6GG
                                (GHC.Prim.plusAddr# ww5_s6GN 1#)
                                (GHC.Prim.plusAddr# ww6_s6GR 2#)
                                s2_i6dU
                              }
                              }
                              }
                              }
                          }
                      };
                    1# ->
                      (# w2_s6GK,
                         Data.ByteString.Builder.Internal.BufferFull
                           @r_s6GW
                           2#
                           ww6_s6GR
                           ((\ (w3_s6GJ :: Data.ByteString.Builder.Internal.BufferRange)
                               (w4_X1 :: GHC.Prim.State# GHC.Prim.RealWorld) ->
                               case w3_s6GJ of
                               { Data.ByteString.Builder.Internal.BufferRange ww9_X3 ww10_X4 ->
                               $wgoBS_s6GU ww5_s6GN ww9_X3 ww10_X4 w4_X1
                               })
                            `cast` (<Data.ByteString.Builder.Internal.BufferRange>_R
                                    %<'Many>_N ->_R Sym (GHC.Types.N:IO[0]
                                                             <Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GW>_R)
                                    :: (Data.ByteString.Builder.Internal.BufferRange
                                        -> GHC.Prim.State# GHC.Prim.RealWorld
                                        -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                              Data.ByteString.Builder.Internal.BuildSignal
                                                r_s6GW #))
                                       ~R# (Data.ByteString.Builder.Internal.BufferRange
                                            -> IO
                                                 (Data.ByteString.Builder.Internal.BuildSignal
                                                    r_s6GW)))) #)
                  }
              }; } in
      $wgoBS_s6GU ww_s6H2 ww3_s6H8 ww4_s6H9 w1_s6GZ
      }

-- RHS size: {terms: 19, types: 15, coercions: 0, joins: 0/0}
Data.ByteString.Builder.ASCII.byteStringHex1 [InlPrag=[final]]
  :: S.ByteString
     -> forall {r}.
        Data.ByteString.Builder.Internal.BuildStep (r |> <*>_N)
        -> Data.ByteString.Builder.Internal.BufferRange
        -> GHC.Prim.State# GHC.Prim.RealWorld
        -> (# GHC.Prim.State# GHC.Prim.RealWorld,
              Data.ByteString.Builder.Internal.BuildSignal (r |> <*>_N) #)
[GblId,
 Arity=4,
 Str=<1P(L,L,L)><1CL(C1(L))><1P(L,L)><L>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=4,unsat_ok=True,boring_ok=False)
         Tmpl= \ (w_s6GV [Occ=Once1!] :: S.ByteString)
                 (@r_s6GW)
                 (w1_s6GX [Occ=Once1]
                    :: Data.ByteString.Builder.Internal.BuildStep r_s6GW)
                 (w2_s6GY [Occ=Once1!]
                    :: Data.ByteString.Builder.Internal.BufferRange)
                 (w3_s6GZ [Occ=Once1] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
                 case w_s6GV of
                 { Data.ByteString.Internal.Type.BS ww1_s6H2 [Occ=Once1]
                                                    ww2_s6H3 [Occ=Once1] ww3_s6H4 [Occ=Once1] ->
                 case w2_s6GY of
                 { Data.ByteString.Builder.Internal.BufferRange ww5_s6H8 [Occ=Once1]
                                                                ww6_s6H9 [Occ=Once1] ->
                 Data.ByteString.Builder.ASCII.$wbyteStringHex
                   ww1_s6H2
                   ww2_s6H3
                   ww3_s6H4
                   @r_s6GW
                   w1_s6GX
                   ww5_s6H8
                   ww6_s6H9
                   w3_s6GZ
                 }
                 }}]
Data.ByteString.Builder.ASCII.byteStringHex1
  = \ (w_s6GV :: S.ByteString)
      (@r_s6GW)
      (w1_s6GX [OS=OneShot]
         :: Data.ByteString.Builder.Internal.BuildStep r_s6GW)
      (w2_s6GY [OS=OneShot]
         :: Data.ByteString.Builder.Internal.BufferRange)
      (w3_s6GZ [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
      case w_s6GV of
      { Data.ByteString.Internal.Type.BS ww1_s6H2 ww2_s6H3 ww3_s6H4 ->
      case w2_s6GY of
      { Data.ByteString.Builder.Internal.BufferRange ww5_s6H8 ww6_s6H9 ->
      Data.ByteString.Builder.ASCII.$wbyteStringHex
        ww1_s6H2
        ww2_s6H3
        ww3_s6H4
        @r_s6GW
        w1_s6GX
        ww5_s6H8
        ww6_s6H9
        w3_s6GZ
      }
      }

-- RHS size: {terms: 1, types: 0, coercions: 21, joins: 0/0}
byteStringHex [InlPrag=[final]] :: S.ByteString -> Builder
[GblId,
 Arity=4,
 Str=<1P(L,L,L)><1CL(C1(L))><1P(L,L)><L>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)
         Tmpl= Data.ByteString.Builder.ASCII.byteStringHex1
               `cast` (<S.ByteString>_R
                       %<'Many>_N ->_R forall (r :: <*>_N).
                                       <Data.ByteString.Builder.Internal.BuildStep (r |> <*>_N)>_R
                                       %<'Many>_N ->_R <Data.ByteString.Builder.Internal.BufferRange>_R
                                       %<'Many>_N ->_R Sym (GHC.Types.N:IO[0]
                                                                <Data.ByteString.Builder.Internal.BuildSignal
                                                                   (r |> <*>_N)>_R)
                                       ; Sym (Data.ByteString.Builder.Internal.N:Builder[0])
                       :: (S.ByteString
                           -> forall {r}.
                              Data.ByteString.Builder.Internal.BuildStep (r |> <*>_N)
                              -> Data.ByteString.Builder.Internal.BufferRange
                              -> GHC.Prim.State# GHC.Prim.RealWorld
                              -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                    Data.ByteString.Builder.Internal.BuildSignal (r |> <*>_N) #))
                          ~R# (S.ByteString -> Builder))}]
byteStringHex
  = Data.ByteString.Builder.ASCII.byteStringHex1
    `cast` (<S.ByteString>_R
            %<'Many>_N ->_R forall (r :: <*>_N).
                            <Data.ByteString.Builder.Internal.BuildStep (r |> <*>_N)>_R
                            %<'Many>_N ->_R <Data.ByteString.Builder.Internal.BufferRange>_R
                            %<'Many>_N ->_R Sym (GHC.Types.N:IO[0]
                                                     <Data.ByteString.Builder.Internal.BuildSignal
                                                        (r |> <*>_N)>_R)
                            ; Sym (Data.ByteString.Builder.Internal.N:Builder[0])
            :: (S.ByteString
                -> forall {r}.
                   Data.ByteString.Builder.Internal.BuildStep (r |> <*>_N)
                   -> Data.ByteString.Builder.Internal.BufferRange
                   -> GHC.Prim.State# GHC.Prim.RealWorld
                   -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                         Data.ByteString.Builder.Internal.BuildSignal (r |> <*>_N) #))
               ~R# (S.ByteString -> Builder))
9.2.4 simplified Core for byteStringHex
-- RHS size: {terms: 172, types: 131, coercions: 25, joins: 1/7}
Data.ByteString.Builder.ASCII.$wbyteStringHex [InlPrag=NOINLINE]
  :: GHC.Prim.Addr#
     -> GHC.ForeignPtr.ForeignPtrContents
     -> GHC.Prim.Int#
     -> forall {r}.
        Data.ByteString.Builder.Internal.BuildStep r
        -> GHC.Prim.Addr#
        -> GHC.Prim.Addr#
        -> IO (Data.ByteString.Builder.Internal.BuildSignal r)
[GblId, Arity=6, Str=<L><L><L><1CL(C1(L))><L><L>, Unf=OtherCon []]
Data.ByteString.Builder.ASCII.$wbyteStringHex
  = \ (ww_s6GK :: GHC.Prim.Addr#)
      (ww1_s6GL :: GHC.ForeignPtr.ForeignPtrContents)
      (ww2_s6GM :: GHC.Prim.Int#)
      (@r_s6GF)
      (w_s6GG :: Data.ByteString.Builder.Internal.BuildStep r_s6GF)
      (ww3_s6GQ :: GHC.Prim.Addr#)
      (ww4_s6GR :: GHC.Prim.Addr#) ->
      case w_s6GG of k_i6ei { __DEFAULT ->
      let {
        ipe_s6Cw :: GHC.Prim.Addr#
        [LclId]
        ipe_s6Cw = GHC.Prim.plusAddr# ww_s6GK ww2_s6GM } in
      letrec {
        $wgoBS_s6I9 [InlPrag=[2], Occ=LoopBreaker, Dmd=SCS(C1(C1(L)))]
          :: GHC.Prim.Addr#
             -> GHC.Prim.Addr#
             -> GHC.Prim.Addr#
             -> GHC.Prim.State# GHC.Prim.RealWorld
             -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                   Data.ByteString.Builder.Internal.BuildSignal r_s6GF #)
        [LclId, Arity=4, Str=<L><L><L><L>, Unf=OtherCon []]
        $wgoBS_s6I9
          = \ (ww5_s6Gw :: GHC.Prim.Addr#)
              (ww6_s6GA :: GHC.Prim.Addr#)
              (ww7_s6GB :: GHC.Prim.Addr#)
              (eta_B0 [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
              case GHC.Prim.ltAddr# ww5_s6Gw ipe_s6Cw of {
                __DEFAULT ->
                  case GHC.Prim.touch#
                         @GHC.Types.LiftedRep
                         @GHC.ForeignPtr.ForeignPtrContents
                         ww1_s6GL
                         eta_B0
                  of s'_i6ex
                  { __DEFAULT ->
                  ((k_i6ei
                      (Data.ByteString.Builder.Internal.BufferRange ww6_s6GA ww7_s6GB))
                   `cast` (GHC.Types.N:IO[0]
                               <Data.ByteString.Builder.Internal.BuildSignal r_s6GF>_R
                           :: IO (Data.ByteString.Builder.Internal.BuildSignal r_s6GF)
                              ~R# (GHC.Prim.State# GHC.Prim.RealWorld
                                   -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                         Data.ByteString.Builder.Internal.BuildSignal r_s6GF #))))
                    s'_i6ex
                  };
                1# ->
                  case GHC.Prim.ltAddr# ww7_s6GB (GHC.Prim.plusAddr# ww6_s6GA 2#)
                  of {
                    __DEFAULT ->
                      let {
                        x1_i6eF :: GHC.Prim.Int#
                        [LclId]
                        x1_i6eF
                          = GHC.Prim.uncheckedIShiftRA#
                              (GHC.Prim.minusAddr# ww7_s6GB ww6_s6GA) 1# } in
                      let {
                        y1_s6CA :: GHC.Prim.Int#
                        [LclId]
                        y1_s6CA = GHC.Prim.minusAddr# ipe_s6Cw ww5_s6Gw } in
                      join {
                        $j_s6Cz [Dmd=1C1(L)]
                          :: GHC.Prim.Int#
                             -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                   Data.ByteString.Builder.Internal.BuildSignal r_s6GF #)
                        [LclId[JoinId(1)], Arity=1, Str=<L>, Unf=OtherCon []]
                        $j_s6Cz (d_i6eI [OS=OneShot] :: GHC.Prim.Int#)
                          = let {
                              ipeTmp_s6CE :: GHC.Prim.Addr#
                              [LclId]
                              ipeTmp_s6CE = GHC.Prim.plusAddr# ww5_s6Gw d_i6eI } in
                            case GHC.Prim.ltAddr# ww5_s6Gw ipeTmp_s6CE of {
                              __DEFAULT -> $wgoBS_s6I9 ww5_s6Gw ww6_s6GA ww7_s6GB eta_B0;
                              1# ->
                                case GHC.Prim.readWord8OffAddr#
                                       @GHC.Prim.RealWorld ww5_s6Gw 0# eta_B0
                                of
                                { (# ipv3_i6eW, ipv4_i6eX #) ->
                                case Data.ByteString.Builder.Prim.Internal.Base16.lowerTable of
                                { Data.ByteString.Builder.Prim.Internal.Base16.EncodingTable table_i6dG ->
                                case GHC.Prim.readWord16OffAddr#
                                       @GHC.Prim.RealWorld
                                       table_i6dG
                                       (GHC.Prim.word2Int# (GHC.Prim.word8ToWord# ipv4_i6eX))
                                       ipv3_i6eW
                                of
                                { (# ipv_i6dM, ipv1_i6dN #) ->
                                case GHC.Prim.writeWord16OffAddr#
                                       @GHC.Prim.RealWorld ww6_s6GA 0# ipv1_i6dN ipv_i6dM
                                of s2_i6dS
                                { __DEFAULT ->
                                letrec {
                                  $wgo_s6Gq [InlPrag=[2], Occ=LoopBreaker, Dmd=SCS(C1(C1(L)))]
                                    :: GHC.Prim.Addr#
                                       -> GHC.Prim.Addr#
                                       -> IO (Data.ByteString.Builder.Internal.BuildSignal r_s6GF)
                                  [LclId, Arity=2, Str=<L><L>, Unf=OtherCon []]
                                  $wgo_s6Gq
                                    = \ (ww8_X1 :: GHC.Prim.Addr#) (ww9_X2 :: GHC.Prim.Addr#) ->
                                        case GHC.Prim.ltAddr# ww8_X1 ipeTmp_s6CE of {
                                          __DEFAULT ->
                                            ($wgoBS_s6I9 ww8_X1 ww9_X2 ww7_s6GB)
                                            `cast` (Sym (GHC.Types.N:IO[0]
                                                             <Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF>_R)
                                                    :: (GHC.Prim.State# GHC.Prim.RealWorld
                                                        -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                                              Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF #))
                                                       ~R# IO
                                                             (Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF));
                                          1# ->
                                            (\ (s_X4 :: GHC.Prim.State# GHC.Prim.RealWorld) ->
                                               case GHC.Prim.readWord8OffAddr#
                                                      @GHC.Prim.RealWorld ww8_X1 0# s_X4
                                               of
                                               { (# ipv2_X6, ipv6_X7 #) ->
                                               case GHC.Prim.readWord16OffAddr#
                                                      @GHC.Prim.RealWorld
                                                      table_i6dG
                                                      (GHC.Prim.word2Int#
                                                         (GHC.Prim.word8ToWord# ipv6_X7))
                                                      ipv2_X6
                                               of
                                               { (# ipv7_Xa, ipv8_Xb #) ->
                                               case GHC.Prim.writeWord16OffAddr#
                                                      @GHC.Prim.RealWorld ww9_X2 0# ipv8_Xb ipv7_Xa
                                               of s1_Xc
                                               { __DEFAULT ->
                                               (($wgo_s6Gq
                                                   (GHC.Prim.plusAddr# ww8_X1 1#)
                                                   (GHC.Prim.plusAddr# ww9_X2 2#))
                                                `cast` (GHC.Types.N:IO[0]
                                                            <Data.ByteString.Builder.Internal.BuildSignal
                                                               r_s6GF>_R
                                                        :: IO
                                                             (Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF)
                                                           ~R# (GHC.Prim.State# GHC.Prim.RealWorld
                                                                -> (# GHC.Prim.State#
                                                                        GHC.Prim.RealWorld,
                                                                      Data.ByteString.Builder.Internal.BuildSignal
                                                                        r_s6GF #))))
                                                 s1_Xc
                                               }
                                               }
                                               })
                                            `cast` (Sym (GHC.Types.N:IO[0]
                                                             <Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF>_R)
                                                    :: (GHC.Prim.State# GHC.Prim.RealWorld
                                                        -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                                              Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF #))
                                                       ~R# IO
                                                             (Data.ByteString.Builder.Internal.BuildSignal
                                                                r_s6GF))
                                        }; } in
                                (($wgo_s6Gq
                                    (GHC.Prim.plusAddr# ww5_s6Gw 1#)
                                    (GHC.Prim.plusAddr# ww6_s6GA 2#))
                                 `cast` (GHC.Types.N:IO[0]
                                             <Data.ByteString.Builder.Internal.BuildSignal r_s6GF>_R
                                         :: IO (Data.ByteString.Builder.Internal.BuildSignal r_s6GF)
                                            ~R# (GHC.Prim.State# GHC.Prim.RealWorld
                                                 -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                                       Data.ByteString.Builder.Internal.BuildSignal
                                                         r_s6GF #))))
                                  s2_i6dS
                                }
                                }
                                }
                                }
                            } } in
                      case GHC.Prim.<=# x1_i6eF y1_s6CA of {
                        __DEFAULT -> jump $j_s6Cz y1_s6CA;
                        1# -> jump $j_s6Cz x1_i6eF
                      };
                    1# ->
                      (# eta_B0,
                         Data.ByteString.Builder.Internal.BufferFull
                           @r_s6GF
                           2#
                           ww6_s6GA
                           (\ (w1_s6Gt :: Data.ByteString.Builder.Internal.BufferRange) ->
                              case w1_s6Gt of
                              { Data.ByteString.Builder.Internal.BufferRange ww9_X2 ww10_X3 ->
                              ($wgoBS_s6I9 ww5_s6Gw ww9_X2 ww10_X3)
                              `cast` (Sym (GHC.Types.N:IO[0]
                                               <Data.ByteString.Builder.Internal.BuildSignal
                                                  r_s6GF>_R)
                                      :: (GHC.Prim.State# GHC.Prim.RealWorld
                                          -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                                                Data.ByteString.Builder.Internal.BuildSignal
                                                  r_s6GF #))
                                         ~R# IO
                                               (Data.ByteString.Builder.Internal.BuildSignal
                                                  r_s6GF))
                              }) #)
                  }
              }; } in
      ($wgoBS_s6I9 ww_s6GK ww3_s6GQ ww4_s6GR)
      `cast` (Sym (GHC.Types.N:IO[0]
                       <Data.ByteString.Builder.Internal.BuildSignal r_s6GF>_R)
              :: (GHC.Prim.State# GHC.Prim.RealWorld
                  -> (# GHC.Prim.State# GHC.Prim.RealWorld,
                        Data.ByteString.Builder.Internal.BuildSignal r_s6GF #))
                 ~R# IO (Data.ByteString.Builder.Internal.BuildSignal r_s6GF))
      }

-- RHS size: {terms: 17, types: 13, coercions: 0, joins: 0/0}
Data.ByteString.Builder.ASCII.byteStringHex1 [InlPrag=[final]]
  :: S.ByteString
     -> forall r.
        Data.ByteString.Builder.Internal.BuildStep r
        -> Data.ByteString.Builder.Internal.BuildStep r
[GblId,
 Arity=3,
 Str=<1P(L,L,L)><1CL(C1(L))><1P(L,L)>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False)
         Tmpl= \ (w_s6GE [Occ=Once1!] :: S.ByteString)
                 (@r_s6GF)
                 (w1_s6GG [Occ=Once1]
                    :: Data.ByteString.Builder.Internal.BuildStep r_s6GF)
                 (w2_s6GH [Occ=Once1!]
                    :: Data.ByteString.Builder.Internal.BufferRange) ->
                 case w_s6GE of
                 { Data.ByteString.Internal.Type.BS ww1_s6GK [Occ=Once1]
                                                    ww2_s6GL [Occ=Once1] ww3_s6GM [Occ=Once1] ->
                 case w2_s6GH of
                 { Data.ByteString.Builder.Internal.BufferRange ww5_s6GQ [Occ=Once1]
                                                                ww6_s6GR [Occ=Once1] ->
                 Data.ByteString.Builder.ASCII.$wbyteStringHex
                   ww1_s6GK ww2_s6GL ww3_s6GM @r_s6GF w1_s6GG ww5_s6GQ ww6_s6GR
                 }
                 }}]
Data.ByteString.Builder.ASCII.byteStringHex1
  = \ (w_s6GE :: S.ByteString)
      (@r_s6GF)
      (w1_s6GG [OS=OneShot]
         :: Data.ByteString.Builder.Internal.BuildStep r_s6GF)
      (w2_s6GH [OS=OneShot]
         :: Data.ByteString.Builder.Internal.BufferRange) ->
      case w_s6GE of
      { Data.ByteString.Internal.Type.BS ww1_s6GK ww2_s6GL ww3_s6GM ->
      case w2_s6GH of
      { Data.ByteString.Builder.Internal.BufferRange ww5_s6GQ ww6_s6GR ->
      Data.ByteString.Builder.ASCII.$wbyteStringHex
        ww1_s6GK ww2_s6GL ww3_s6GM @r_s6GF w1_s6GG ww5_s6GQ ww6_s6GR
      }
      }

-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0}
byteStringHex [InlPrag=[final]] :: S.ByteString -> Builder
[GblId,
 Arity=3,
 Str=<1P(L,L,L)><1CL(C1(L))><1P(L,L)>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)
         Tmpl= Data.ByteString.Builder.ASCII.byteStringHex1
               `cast` (<S.ByteString>_R
                       %<'Many>_N ->_R Sym (Data.ByteString.Builder.Internal.N:Builder[0])
                       :: (S.ByteString
                           -> forall r.
                              Data.ByteString.Builder.Internal.BuildStep r
                              -> Data.ByteString.Builder.Internal.BuildStep r)
                          ~R# (S.ByteString -> Builder))}]
byteStringHex
  = Data.ByteString.Builder.ASCII.byteStringHex1
    `cast` (<S.ByteString>_R
            %<'Many>_N ->_R Sym (Data.ByteString.Builder.Internal.N:Builder[0])
            :: (S.ByteString
                -> forall r.
                   Data.ByteString.Builder.Internal.BuildStep r
                   -> Data.ByteString.Builder.Internal.BuildStep r)
               ~R# (S.ByteString -> Builder))
Edited by Matthew Craven
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information