1 //===-- Implementation of memcpy ------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/string/memcpy.h" 10 #include "src/__support/common.h" 11 #include "src/string/memory_utils/elements.h" 12 13 namespace __llvm_libc { 14 15 // Design rationale 16 // ================ 17 // 18 // Using a profiler to observe size distributions for calls into libc 19 // functions, it was found most operations act on a small number of bytes. 20 // This makes it important to favor small sizes. 21 // 22 // The tests for `count` are in ascending order so the cost of branching is 23 // proportional to the cost of copying. 24 // 25 // The function is written in C++ for several reasons: 26 // - The compiler can __see__ the code, this is useful when performing Profile 27 // Guided Optimization as the optimized code can take advantage of branching 28 // probabilities. 29 // - It also allows for easier customization and favors testing multiple 30 // implementation parameters. 31 // - As compilers and processors get better, the generated code is improved 32 // with little change on the code side. 33 static void memcpy_impl(char *__restrict dst, const char *__restrict src, 34 size_t count) { 35 // Use scalar strategies (_1, _2, _3 ...) 36 using namespace __llvm_libc::scalar; 37 38 if (count == 0) 39 return; 40 if (count == 1) 41 return Copy<_1>(dst, src); 42 if (count == 2) 43 return Copy<_2>(dst, src); 44 if (count == 3) 45 return Copy<_3>(dst, src); 46 if (count == 4) 47 return Copy<_4>(dst, src); 48 if (count < 8) 49 return Copy<HeadTail<_4>>(dst, src, count); 50 if (count < 16) 51 return Copy<HeadTail<_8>>(dst, src, count); 52 if (count < 32) 53 return Copy<HeadTail<_16>>(dst, src, count); 54 if (count < 64) 55 return Copy<HeadTail<_32>>(dst, src, count); 56 if (count < 128) 57 return Copy<HeadTail<_64>>(dst, src, count); 58 return Copy<Align<_32, Arg::Src>::Then<Loop<_32>>>(dst, src, count); 59 } 60 61 LLVM_LIBC_FUNCTION(void *, memcpy, 62 (void *__restrict dst, const void *__restrict src, 63 size_t size)) { 64 memcpy_impl(reinterpret_cast<char *>(dst), 65 reinterpret_cast<const char *>(src), size); 66 return dst; 67 } 68 69 } // namespace __llvm_libc 70