Changes between Version 2 and Version 3 of MemcpyOptimizations
- Timestamp:
- 06/14/11 14:52:28 (2 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
MemcpyOptimizations
v2 v3 1 1 = memcpy/memmove/memset optimizations = 2 2 3 Starting with version 7.2 GHC has three new primitives for copying/setting blocks of memory, corresponding to the C functions `memcpy`, `memmove`, and `memset`. GHC optimizes occurrences of these primitives into efficient unrolled loops whenever possible (and calls the corresponding C functions otherwise.)3 Starting with version 7.2, GHC has three new primitives for copying/setting blocks of memory, corresponding to the C functions `memcpy`, `memmove`, and `memset`. GHC optimizes occurrences of these primitives into efficient unrolled loops when possible and calls the corresponding C functions otherwise. 4 4 5 5 == Implementation == 6 6 7 The primitives are implemented as three `CallishMachOp`s, defined in `compiler/cmm/CmmMachOp`. The code generator generates calls to these `CallishMachOp`s using three utility functions: `emitMemcpyCall`, `emitMemmoveCall`, and `emitMemsetCall`, defined in `compiler/codeGen/CgPrimOp.hs` (old code generator) and `compiler/codeGen/StgCmmPrim.hs` (new code generator). The helper functions take an extra parameter that indicates the alignment of the arguments, which is used as ahint by the backends.7 The primitives are implemented as three [wiki:Commentary/Compiler/CmmType Cmm language] [wiki:Commentary/Compiler/CmmType#OperatorsandPrimitiveOperations CallishMachOp`s], defined in [[GhcFile(compiler/cmm/CmmMachOp.hs)]]. The code generator generates calls to these `CallishMachOp`s using three utility functions: `emitMemcpyCall`, `emitMemmoveCall`, and `emitMemsetCall`, defined in [[GhcFile(compiler/codeGen/CgPrimOp.hs)]] (old code generator) and [[GhcFile(compiler/codeGen/StgCmmPrim.hs)]] (new code generator). The helper functions take an extra parameter that indicates the alignment of the arguments, which is used as a optimisation hint by the backends. 8 8 9 The reason the primitives are unrolled in the backends, instead of in the code generator, is to allow us to make use of LLVM's `memcpy`/`memmove`/`memset` intrinsics, which LLVM optimizes well. In the x86/x86-64 backend we unroll the primitives ourselves. 9 The reason the primitives are unrolled in the backends, instead of in the code generator, is to allow us to make use of LLVM's `memcpy`/`memmove`/`memset` intrinsics, which LLVM optimizes well. In the x86/x86-64 backend we unroll the primitives ourselves. The different native code generator backends can also generate more efficient code then a generic case higher up. Currently only the X86 backend unrolls these primitives though, SPARC and !PowerPC both just call the corresponding C functions. 10 10 11 11 == Unrolling heuristics == … … 20 20 == User API == 21 21 22 These primitives are exposed to the user asa set of primitive operations on boxed arrays:22 These primitives aren't directly exposed to the user at this time. Instead the primitives are exposed to the user through a set of primitive operations on boxed arrays: 23 23 24 24 * `copyArray#` … … 29 29 * `thawArray#` 30 30 31 The latter four allow the user to efficiently clone an array without first setting all elements to some dummy element, which would be required to e.g. implement `cloneArray#` in terms of `newArray#` and `copyArray#`. The implementation of these primitive operations are in `compiler/cmm/CgPrimOps.hs` (old code generator) and `compiler/codeGen/StgCmmPrim.hs` (new code generator) 31 The latter four allow the user to efficiently clone an array without first setting all elements to some dummy element, which would be required to e.g. implement `cloneArray#` in terms of `newArray#` and `copyArray#`. The implementation of these primitive operations are in [[GhcFile(compiler/cmm/CgPrimOps.hs)]] (old code generator) and [[GhcFile(compiler/codeGen/StgCmmPrim.hs)]] (new code generator). 32 33 == Test API == 34 35 The main test for this feature of GHC is `cgrun069`, located at `testsuite/tests/ghc-regress/codeGen/should_run/`.
