Ticket #8256: 0001-prefetch-in-the-native-code-gen-plus-locality-levels.patch

File 0001-prefetch-in-the-native-code-gen-plus-locality-levels.patch, 19.2 KB (added by carter, 23 months ago)

updated patch, sept 19, 12:45am

  • compiler/cmm/CmmMachOp.hs

    From e1d4292e38cabb985b75890eb08758b88d3ff0ff Mon Sep 17 00:00:00 2001
    From: Carter Tazio Schonwald <[email protected]>
    Date: Thu, 19 Sep 2013 00:09:41 -0400
    Subject: [PATCH] prefetch in the native code gen, plus locality levels support
    
    note: currently there is a bug in the asm pretty printing i've yet to track down
    ---
     compiler/cmm/CmmMachOp.hs               |  8 +++-
     compiler/cmm/CmmParse.y                 |  9 +++-
     compiler/cmm/PprC.hs                    |  4 +-
     compiler/codeGen/StgCmmPrim.hs          | 53 +++++++++++++-----------
     compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 11 +++--
     compiler/nativeGen/PPC/CodeGen.hs       |  5 ++-
     compiler/nativeGen/PPC/Instr.hs         |  2 +-
     compiler/nativeGen/SPARC/CodeGen.hs     |  9 +++-
     compiler/nativeGen/X86/CodeGen.hs       | 21 +++++++++-
     compiler/nativeGen/X86/Instr.hs         | 16 +++++++-
     compiler/nativeGen/X86/Ppr.hs           | 13 ++++++
     compiler/prelude/primops.txt.pp         | 73 +++++++++++++++++++++++++++++----
     12 files changed, 177 insertions(+), 47 deletions(-)
    
    diff --git a/compiler/cmm/CmmMachOp.hs b/compiler/cmm/CmmMachOp.hs
    index 8d42bbd..a398336 100644
    a b data CallishMachOp 
    518518  | MO_Touch         -- Keep variables live (when using interior pointers)
    519519
    520520  -- Prefetch
    521   | MO_Prefetch_Data -- Prefetch hint. May change program performance but not
     521  | MO_Prefetch_Data Int -- Prefetch hint. May change program performance but not
    522522                     -- program behavior.
     523                     -- the Int can be 0-3. Needs to be known at compile time
     524                     -- to interact with code generation correctly.
     525                     --  TODO: add support for prefetch WRITES,
     526                     --  currently only exposes prefetch reads, which
     527                     -- would the majority of use cases in ghc anyways
     528
    523529
    524530  -- Note that these three MachOps all take 1 extra parameter than the
    525531  -- standard C lib versions. The extra (last) parameter contains
  • compiler/cmm/CmmParse.y

    diff --git a/compiler/cmm/CmmParse.y b/compiler/cmm/CmmParse.y
    index 8c36dea..830cb92 100644
    a b callishMachOps = listToUFM $ 
    923923        ( "write_barrier", MO_WriteBarrier ),
    924924        ( "memcpy", MO_Memcpy ),
    925925        ( "memset", MO_Memset ),
    926         ( "memmove", MO_Memmove )
     926        ( "memmove", MO_Memmove ),
     927
     928        ("prefetch0",MO_Prefetch_Data 0),
     929        ("prefetch1",MO_Prefetch_Data 1),
     930        ("prefetch2",MO_Prefetch_Data 2),
     931        ("prefetch3",MO_Prefetch_Data 3)
     932
    927933        -- ToDo: the rest, maybe
     934        -- edit; which rest?
    928935    ]
    929936
    930937parseSafety :: String -> P Safety
  • compiler/cmm/PprC.hs

    diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
    index d45b103..1ec08ec 100644
    a b pprCallishMachOp_for_C mop 
    750750        MO_Add2       {} -> unsupported
    751751        MO_U_Mul2     {} -> unsupported
    752752        MO_Touch         -> unsupported
    753         MO_Prefetch_Data -> unsupported
     753        (MO_Prefetch_Data _ ) -> unsupported
     754        --- we COULD support prefetch via "__builtin_prefetch"
     755        --- Not addin g it for now
    754756    where unsupported = panic ("pprCallishMachOp_for_C: " ++ show mop
    755757                            ++ " not supported!")
    756758
  • compiler/codeGen/StgCmmPrim.hs

    diff --git a/compiler/codeGen/StgCmmPrim.hs b/compiler/codeGen/StgCmmPrim.hs
    index 8560f7c..c17aa48 100644
    a b emitPrimOp dflags [res] SizeofMutableByteArrayOp [arg] 
    255255emitPrimOp _ res@[] TouchOp args@[_arg]
    256256   = do emitPrimCall res MO_Touch args
    257257
    258 emitPrimOp _ res@[] PrefetchByteArrayOp args@[_arg]
    259    = do emitPrimCall res MO_Prefetch_Data args
    260 
    261 emitPrimOp _ res@[] PrefetchMutableByteArrayOp args@[_arg]
    262    = do emitPrimCall res MO_Prefetch_Data args
    263 
    264 emitPrimOp _ res@[] PrefetchAddrOp args@[_arg]
    265    = do emitPrimCall res MO_Prefetch_Data args
    266 
    267258--  #define byteArrayContentszh(r,a) r = BYTE_ARR_CTS(a)
    268259emitPrimOp dflags [res] ByteArrayContents_Char [arg]
    269260   = emitAssign (CmmLocal res) (cmmOffsetB dflags arg (arrWordsHdrSize dflags))
    emitPrimOp _ [res] Int64X2InsertOp [v,e,i] = 
    630621    doVecInsertOp Nothing vec2b64 v e i res
    631622
    632623-- Prefetch
    633 emitPrimOp _ res PrefetchByteArrayOp        args = doPrefetchByteArrayOp res args
    634 emitPrimOp _ res PrefetchMutableByteArrayOp args = doPrefetchByteArrayOp res args
    635 emitPrimOp _ res PrefetchAddrOp             args = doPrefetchAddrOp res args
     624emitPrimOp _ res PrefetchByteArrayOp3        args = doPrefetchByteArrayOp 3 res args
     625emitPrimOp _ res PrefetchMutableByteArrayOp3 args = doPrefetchByteArrayOp 3 res args
     626emitPrimOp _ res PrefetchAddrOp3             args = doPrefetchAddrOp  3 res args
     627
     628emitPrimOp _ res PrefetchByteArrayOp2        args = doPrefetchByteArrayOp 2 res args
     629emitPrimOp _ res PrefetchMutableByteArrayOp2 args = doPrefetchByteArrayOp 2 res args
     630emitPrimOp _ res PrefetchAddrOp2             args = doPrefetchAddrOp 2 res args
     631
     632emitPrimOp _ res PrefetchByteArrayOp1        args = doPrefetchByteArrayOp 1 res args
     633emitPrimOp _ res PrefetchMutableByteArrayOp1 args = doPrefetchByteArrayOp 1 res args
     634emitPrimOp _ res PrefetchAddrOp1             args = doPrefetchAddrOp 1 res args
     635
     636emitPrimOp _ res PrefetchByteArrayOp0        args = doPrefetchByteArrayOp 0 res args
     637emitPrimOp _ res PrefetchMutableByteArrayOp0 args = doPrefetchByteArrayOp 0 res args
     638emitPrimOp _ res PrefetchAddrOp0             args = doPrefetchAddrOp 0 res args
     639
    636640
    637641-- The rest just translate straightforwardly
    638642emitPrimOp dflags [res] op [arg]
    doVecInsertOp maybe_pre_write_cast ty src e idx res = do 
    12871291------------------------------------------------------------------------------
    12881292-- Helpers for translating prefetching.
    12891293
    1290 doPrefetchByteArrayOp :: [LocalReg]
     1294doPrefetchByteArrayOp :: Int
     1295                      -> [LocalReg]
    12911296                      -> [CmmExpr]
    12921297                      -> FCode ()
    1293 doPrefetchByteArrayOp res [addr,idx]
     1298doPrefetchByteArrayOp locality res [addr,idx]
    12941299   = do dflags <- getDynFlags
    1295         mkBasicPrefetch (arrWordsHdrSize dflags) res addr idx
    1296 doPrefetchByteArrayOp _ _
     1300        mkBasicPrefetch locality (arrWordsHdrSize dflags) res addr idx
     1301doPrefetchByteArrayOp _ _ _
    12971302   = panic "StgCmmPrim: doPrefetchByteArrayOp"
    12981303
    1299 doPrefetchAddrOp :: [LocalReg]
     1304doPrefetchAddrOp ::Int 
     1305                 -> [LocalReg]
    13001306                 -> [CmmExpr]
    13011307                 -> FCode ()
    1302 doPrefetchAddrOp res [addr,idx]
    1303    = mkBasicPrefetch 0 res addr idx
    1304 doPrefetchAddrOp _ _
     1308doPrefetchAddrOp locality  res [addr,idx]
     1309   = mkBasicPrefetch locality 0 res addr idx
     1310doPrefetchAddrOp _ _  _
    13051311   = panic "StgCmmPrim: doPrefetchAddrOp"
    13061312
    1307 mkBasicPrefetch :: ByteOff      -- Initial offset in bytes
     1313mkBasicPrefetch :: Int          -- Locality level 0-3
     1314                -> ByteOff      -- Initial offset in bytes
    13081315                -> [LocalReg]   -- Destination
    13091316                -> CmmExpr      -- Base address
    13101317                -> CmmExpr      -- Index
    13111318                -> FCode ()
    1312 mkBasicPrefetch off res base idx
     1319mkBasicPrefetch locality off res base idx
    13131320   = do dflags <- getDynFlags
    1314         emitPrimCall [] MO_Prefetch_Data [cmmIndexExpr dflags W8 (cmmOffsetB dflags base off) idx]
     1321        emitPrimCall [] (MO_Prefetch_Data locality) [cmmIndexExpr dflags W8 (cmmOffsetB dflags base off) idx]
    13151322        case res of
    13161323          []    -> return ()
    13171324          [reg] -> emitAssign (CmmLocal reg) base
  • compiler/llvmGen/LlvmCodeGen/CodeGen.hs

    diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
    index def9e2b..28cf9a5 100644
    a b genCall (PrimTarget (MO_UF_Conv _)) [_] args = 
    200200    "Can only handle 1, given" ++ show (length args) ++ "."
    201201
    202202-- Handle prefetching data
    203 genCall t@(PrimTarget MO_Prefetch_Data) [] args = do
     203genCall t@(PrimTarget (MO_Prefetch_Data localityInt)) [] args
     204  | 0 <= localityInt && localityInt <= 3 = do
    204205    ver <- getLlvmVer
    205206    let argTy | ver <= 29  = [i8Ptr, i32, i32]
    206207              | otherwise  = [i8Ptr, i32, i32, i32]
    genCall t@(PrimTarget MO_Prefetch_Data) [] args = do 
    214215    (argVars', stmts3)      <- castVars $ zip argVars argTy
    215216
    216217    trash <- getTrashStmts
    217     let argSuffix | ver <= 29  = [mkIntLit i32 0, mkIntLit i32 3]
    218                   | otherwise  = [mkIntLit i32 0, mkIntLit i32 3, mkIntLit i32 1]
     218    let argSuffix | ver <= 29  = [mkIntLit i32 0, mkIntLit i32 localityInt]
     219                  | otherwise  = [mkIntLit i32 0, mkIntLit i32 localityInt, mkIntLit i32 1]
    219220        call = Expr $ Call StdCall fptr (argVars' ++ argSuffix) []
    220221        stmts = stmts1 `appOL` stmts2 `appOL` stmts3
    221222                `appOL` trash `snocOL` call
    222223    return (stmts, top1 ++ top2)
     224  | otherwise = panic $ "prefetch locality level integer must be between 0 and 3, given: " ++ (show localityInt)
    223225
    224226-- Handle PopCnt and BSwap that need to only convert arg and return types
    225227genCall t@(PrimTarget (MO_PopCnt w)) dsts args =
    cmmPrimOpFunctions mop = do 
    545547    (MO_PopCnt w) -> fsLit $ "llvm.ctpop."  ++ showSDoc dflags (ppr $ widthToLlvmInt w)
    546548    (MO_BSwap w)  -> fsLit $ "llvm.bswap."  ++ showSDoc dflags (ppr $ widthToLlvmInt w)
    547549
    548     MO_Prefetch_Data -> fsLit "llvm.prefetch"
     550    (MO_Prefetch_Data _ )-> fsLit "llvm.prefetch"
     551
    549552
    550553    MO_S_QuotRem {}  -> unsupported
    551554    MO_U_QuotRem {}  -> unsupported
  • compiler/nativeGen/PPC/CodeGen.hs

    diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs
    index 65533d8..5b35956 100644
    a b genCCall' _ _ (PrimTarget MO_WriteBarrier) _ _ 
    911911
    912912genCCall' _ _ (PrimTarget MO_Touch) _ _
    913913 = return $ nilOL
     914 
     915genCCall' _ _ (PrimTarget (MO_Prefetch_Data _)) _ _
     916 = return $ nilOL
    914917
    915918genCCall' dflags gcp target dest_regs args0
    916919  = ASSERT(not $ any (`elem` [II16]) $ map cmmTypeSize argReps)
    genCCall' dflags gcp target dest_regs args0 
    11651168                    MO_U_Mul2 {}     -> unsupported
    11661169                    MO_WriteBarrier  -> unsupported
    11671170                    MO_Touch         -> unsupported
    1168                     MO_Prefetch_Data -> unsupported
     1171                    (MO_Prefetch_Data _ ) -> unsupported
    11691172                unsupported = panic ("outOfLineCmmOp: " ++ show mop
    11701173                                  ++ " not supported")
    11711174
  • compiler/nativeGen/PPC/Instr.hs

    diff --git a/compiler/nativeGen/PPC/Instr.hs b/compiler/nativeGen/PPC/Instr.hs
    index ddb9c51..a147cb1 100644
    a b  
    1 -----------------------------------------------------------------------------
     1--------------------------------------------------------------------------------
    22--
    33-- Machine-dependent assembly language
    44--
  • compiler/nativeGen/SPARC/CodeGen.hs

    diff --git a/compiler/nativeGen/SPARC/CodeGen.hs b/compiler/nativeGen/SPARC/CodeGen.hs
    index 5d2b9a9..ea88053 100644
    a b genCCall 
    392392-- In the SPARC case we don't need a barrier.
    393393--
    394394genCCall (PrimTarget MO_WriteBarrier) _ _
    395  = do   return nilOL
     395 = return $ nilOL
     396
     397-- For now we have prefetc
     398--
     399genCCall (PrimTarget (MO_Prefetch_Data _)) _ _
     400 = return $ nilOL
    396401
    397402genCCall target dest_regs args0
    398403 = do
    outOfLineMachOp_table mop 
    657662        MO_U_Mul2 {}     -> unsupported
    658663        MO_WriteBarrier  -> unsupported
    659664        MO_Touch         -> unsupported
    660         MO_Prefetch_Data -> unsupported
     665        (MO_Prefetch_Data _) -> unsupported
    661666    where unsupported = panic ("outOfLineCmmOp: " ++ show mop
    662667                            ++ " not supported here")
    663668
  • compiler/nativeGen/X86/CodeGen.hs

    diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
    index f6143d3..7fc6704 100644
    a b genCCall _ (PrimTarget MO_WriteBarrier) _ _ = return nilOL 
    16561656
    16571657genCCall _ (PrimTarget MO_Touch) _ _ = return nilOL
    16581658
    1659 genCCall _ (PrimTarget MO_Prefetch_Data) _ _ = return nilOL
     1659genCCall is32bit (PrimTarget (MO_Prefetch_Data n )) _  args@[src] =
     1660        case n of
     1661            0 -> genPrefetch src $ PREFETCH NTA  size
     1662            1 -> genPrefetch src $ PREFETCH Lvl2 size
     1663            2 -> genPrefetch src $ PREFETCH Lvl1 size
     1664            3 -> genPrefetch src $ PREFETCH Lvl0 size
     1665            -- the c / llvm prefetch convention is 0, 1, 2, and 3
     1666            -- the x86 corresponding names are : NTA, 2 , 1, and 0
     1667   where
     1668        size = archWordSize is32bit
     1669        --
     1670        genPrefetch inArg prefetchCTor =
     1671            do
     1672                code_src <- getAnyReg src
     1673                src_r <- getNewRegNat size
     1674                return $ code_src src_r `appOL` (unitOL (prefetchCTor (OpReg src_r) )) 
     1675
     1676                   
    16601677
    16611678genCCall is32Bit (PrimTarget (MO_BSwap width)) [dst] [src] = do
    16621679    dflags <- getDynFlags
    outOfLineCmmOp mop res args 
    23592376              MO_U_Mul2 {}     -> unsupported
    23602377              MO_WriteBarrier  -> unsupported
    23612378              MO_Touch         -> unsupported
    2362               MO_Prefetch_Data -> unsupported
     2379              (MO_Prefetch_Data _ ) -> unsupported
    23632380        unsupported = panic ("outOfLineCmmOp: " ++ show mop
    23642381                          ++ " not supported here")
    23652382
  • compiler/nativeGen/X86/Instr.hs

    diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs
    index 266a4ea..1ac3689 100644
    a b  
    99#include "HsVersions.h"
    1010#include "nativeGen/NCG.h"
    1111
    12 module X86.Instr (Instr(..), Operand(..), JumpDest,
     12module X86.Instr (Instr(..), Operand(..), PrefetchVariant(..), JumpDest,
    1313                  getJumpDestBlockId, canShortcut, shortcutStatics,
    1414                  shortcutJump, i386_insert_ffrees, allocMoreStack,
    1515                  maxSpillSlots, archWordSize)
    data Instr 
    319319                                 -- 1:    popl %reg
    320320
    321321    -- SSE4.2
    322     | POPCNT      Size Operand Reg -- src, dst
     322        | POPCNT      Size Operand Reg -- src, dst
     323   
     324    -- prefetch
     325        | PREFETCH  PrefetchVariant Size Operand -- prefetch Variant, addr size, address to prefetch
     326                                        -- variant can be NTA, Lvl0, Lvl1, or Lvl2
     327
     328data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2
     329
    323330
    324331data Operand
    325332        = OpReg  Reg            -- register
    x86_regUsageOfInstr platform instr 
    417424
    418425    POPCNT _ src dst -> mkRU (use_R src []) [dst]
    419426
     427    -- note: might be a better way to do this
     428    PREFETCH _  _ src -> mkRU (use_R src []) []
     429
    420430    _other              -> panic "regUsage: unrecognised instr"
    421431
    422432 where
    x86_patchRegsOfInstr instr env 
    556566    CLTD _              -> instr
    557567
    558568    POPCNT sz src dst -> POPCNT sz (patchOp src) (env dst)
     569   
     570    PREFETCH lvl size src -> PREFETCH lvl size (patchOp src)
    559571
    560572    _other              -> panic "patchRegs: unrecognised instr"
    561573
  • compiler/nativeGen/X86/Ppr.hs

    diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs
    index 7f9c690..9c5a9cf 100644
    a b pprInstr (XOR size src dst) = pprSizeOpOp (sLit "xor") size src dst 
    577577
    578578pprInstr (POPCNT size src dst) = pprOpOp (sLit "popcnt") size src (OpReg dst)
    579579
     580pprInstr (PREFETCH NTA size src ) =  pprSizeOp_ (sLit "prefetchnta") size src
     581pprInstr (PREFETCH Lvl0 size src) = pprSizeOp_ (sLit "prefetch0") size src
     582pprInstr (PREFETCH Lvl1 size src) = pprSizeOp_ (sLit "prefetch1") size src
     583pprInstr (PREFETCH Lvl2 size src) = pprSizeOp_ (sLit "prefetch2") size src
     584
    580585pprInstr (NOT size op) = pprSizeOp (sLit "not") size op
    581586pprInstr (BSWAP size op) = pprSizeOp (sLit "bswap") size (OpReg op)
    582587pprInstr (NEGI size op) = pprSizeOp (sLit "neg") size op
    pprMnemonic name size = 
    10141019   char '\t' <> ptext name <> pprSize size <> space
    10151020
    10161021
     1022
    10171023pprSizeImmOp :: LitString -> Size -> Imm -> Operand -> SDoc
    10181024pprSizeImmOp name size imm op1
    10191025  = hcat [
    pprSizeImmOp name size imm op1 
    10251031    ]
    10261032
    10271033
     1034pprSizeOp_ :: LitString -> Size -> Operand -> SDoc
     1035pprSizeOp_ name size op1
     1036  = hcat [
     1037        pprMnemonic_ name ,
     1038        pprOperand size op1
     1039    ]
     1040
    10281041pprSizeOp :: LitString -> Size -> Operand -> SDoc
    10291042pprSizeOp name size op1
    10301043  = hcat [
  • compiler/prelude/primops.txt.pp

    diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
    index cfd6afa..ad90d5c 100644
    a b primop WriteOffAddrOp_Int64AsInt64X2 "writeInt64OffAddrAsInt64X2#" GenPrimOp 
    28482848        llvm_only = True
    28492849
    28502850------------------------------------------------------------------------
    2851 section "Prefetch"
    2852         {Prefetch operations}
     2851
     2852section "Prefetch"
     2853        {Prefetch operations: Note how there are locality levels 0-3.
     2854  On x86_64 systems, 0 will correspond with a Nontemporal (NTA)  prefetch,
     2855  which is not persisted in any level of cache. NTA prefetch is suitable for
     2856  streaming  single pass workloads, and perhaps certain workloads larger
     2857  than a CPU's largest cache.
     2858 
     2859  Higher locality numbers correspond to the memory being loaded in more
     2860  levels of the cpu cache, and being retained  }
    28532861------------------------------------------------------------------------
    28542862
    2855 primop PrefetchByteArrayOp "prefetchByteArray#" GenPrimOp
     2863
     2864--- the Int# argument for prefetch is the byte offset on the byteArray or  Addr#
     2865
     2866---
     2867primop PrefetchByteArrayOp3 "prefetchByteArray3#" GenPrimOp
    28562868   ByteArray# -> Int# -> ByteArray#
    2857    with llvm_only = True
     2869   with can_fail = True
    28582870
    2859 primop PrefetchMutableByteArrayOp "prefetchMutableByteArray#" GenPrimOp
     2871primop PrefetchMutableByteArrayOp3 "prefetchMutableByteArray3#" GenPrimOp
    28602872   MutableByteArray# s -> Int# -> State# s -> State# s
    2861    with has_side_effects = True
    2862         llvm_only = True
     2873   with can_fail = True
     2874
     2875primop PrefetchAddrOp3 "prefetchAddr3#" GenPrimOp
     2876    Addr# -> Int# -> Addr#
     2877    with can_fail = True
     2878
     2879----
    28632880
    2864 primop PrefetchAddrOp "prefetchAddr#" GenPrimOp
     2881primop PrefetchByteArrayOp2 "prefetchByteArray2#" GenPrimOp
     2882   ByteArray# -> Int# -> ByteArray#
     2883   with can_fail = True
     2884
     2885primop PrefetchMutableByteArrayOp2 "prefetchMutableByteArray2#" GenPrimOp
     2886   MutableByteArray# s -> Int# -> State# s -> State# s
     2887   with can_fail = True
     2888
     2889primop PrefetchAddrOp2 "prefetchAddr2#" GenPrimOp
    28652890   Addr# -> Int# -> Addr#
    2866    with llvm_only = True
     2891   with can_fail = True
     2892
     2893----
     2894
     2895primop PrefetchByteArrayOp1 "prefetchByteArray1#" GenPrimOp
     2896   ByteArray# -> Int# -> ByteArray#
     2897   with can_fail = True
     2898
     2899primop PrefetchMutableByteArrayOp1 "prefetchMutableByteArray1#" GenPrimOp
     2900   MutableByteArray# s -> Int# -> State# s -> State# s
     2901   with can_fail = True
     2902
     2903primop PrefetchAddrOp1 "prefetchAddr1#" GenPrimOp
     2904   Addr# -> Int# -> Addr#
     2905   with can_fail = True
     2906
     2907----
     2908
     2909primop PrefetchByteArrayOp0 "prefetchByteArray0#" GenPrimOp
     2910   ByteArray# -> Int# -> ByteArray#
     2911   with can_fail = True
     2912
     2913primop PrefetchMutableByteArrayOp0 "prefetchMutableByteArray0#" GenPrimOp
     2914   MutableByteArray# s -> Int# -> State# s -> State# s
     2915   with can_fail = True
     2916
     2917primop PrefetchAddrOp0 "prefetchAddr0#" GenPrimOp
     2918   Addr# -> Int# -> Addr#
     2919   with can_fail = True
     2920
     2921
    28672922
    28682923------------------------------------------------------------------------
    28692924---                                                                  ---