prefetch# isn't as general as it should be (currently the general version isn't type safe)
the fully general prefetch# needs to have certain arguments be compile time constants, see #8107
Internally ghc's prefetch# uses the prefetch intrinsic from lvm, compiler/llvmGen/LlvmCodeGen/CodeGen.hs
with the following hard coded arguments
ver <= 29 = [mkIntLit i32 0, mkIntLit i32 3] otherwise = [mkIntLit i32 0, mkIntLit i32 3, mkIntLit i32 1]
this correspond roughly (ignoring what the int arg to ghc means,it clearly not the analogue of the c compiler prefetch level, as i originally thoug )
prefetch# addr _ | ver <= 29 = llvm29.prefetch addr 0 3
|otherwise = llvm3.prefetch addr 0 3 1
Now: reading the LLVM language spec http://llvm.org/docs/LangRef.html\#llvm-prefetch-intrinsic documents what this is supposed to, namely
Syntax:¶ declare void @llvm.prefetch(i8* <address>, i32 <rw>, i32 <locality>, i32 <cache type>) Overview: The ‘llvm.prefetch‘ intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a noop. Prefetches have no effect on the behavior of the program but can change its performance characteristics. Arguments: address is the address to be prefetched, rw is the specifier determining if the fetch should be for a read (0) or write (1), and locality is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local keep in cache. The cache type specifies whether the prefetch is performed on the data (1) or instruction (0) cache. The rw, locality and cache type arguments must be constant integers.
Its important to note and emphasize that many of the alternative parameter settings have actual implementations on many modern hardware targets (especially x86_64), and can be useful for a variety of workloads.