Unroll cloneSmallArray when possible
Motivation
Currently, cloneSmallArray#
never unrolls the memcpy
:
{-# language MagicHash #-}
module CloneFive
( cloneFive
) where
import GHC.Exts
cloneFive :: SmallArray# a -> SmallArray# a
cloneFive x = cloneSmallArray# x 42# 5#
With -O2
, we get this cmm:
{offset
cCr: // global
Hp = Hp + 56;
if (Hp > HpLim) (likely: False) goto cCv; else goto cCu;
cCv: // global
HpAlloc = 56;
R2 = R2;
R1 = CloneFive.cloneFive_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
cCu: // global
I64[Hp - 48] = stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN_info;
I64[Hp - 40] = 5;
_cCl::I64 = Hp - 48;
call MO_Memcpy 8(_cCl::I64 + 16, R2 + 352, 40);
R1 = _cCl::I64;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
Proposal
Unroll the memcpy
when the length is statically known. This is already done for memset
in several places.