compiler,runtime: use LLVM intrinsics for memcpy/memmove

This replaces the custom runtime.memcpy and runtime.memmove functions
with calls to LLVM builtins that should hopefully allow LLVM to better
optimize such calls. They will be lowered to regular libc memcpy/memmove
when they can't be optimized away.

When testing this change with some smoke tests, I found that many smoke
tests resulted in slightly larger binary sizes with this commit applied.
I looked into it and it appears that machine.sendUSBPacket was not
inlined before while it is with this commit applied. Additionally, when
I compared all driver smoke tests with -opt=1 I saw that many were
reduced slightly in binary size and none increased in size.
This commit is contained in:
Ayke van Laethem
2020-03-26 15:26:46 +01:00
committed by Ron Evans
parent c01f81144e
commit eaa54bc7e3
4 changed files with 40 additions and 29 deletions
+2 -1
View File
@@ -678,5 +678,6 @@ func (e *ValueError) Error() string {
return "reflect: call of reflect.Value." + e.Method + " on invalid type"
}
//go:linkname memcpy runtime.memcpy
// Calls to this function are converted to LLVM intrinsic calls such as
// llvm.memcpy.p0i8.p0i8.i32().
func memcpy(dst, src unsafe.Pointer, size uintptr)
+6 -17
View File
@@ -30,26 +30,15 @@ func os_runtime_args() []string {
}
// Copy size bytes from src to dst. The memory areas must not overlap.
func memcpy(dst, src unsafe.Pointer, size uintptr) {
for i := uintptr(0); i < size; i++ {
*(*uint8)(unsafe.Pointer(uintptr(dst) + i)) = *(*uint8)(unsafe.Pointer(uintptr(src) + i))
}
}
// Calls to this function are converted to LLVM intrinsic calls such as
// llvm.memcpy.p0i8.p0i8.i32(dst, src, size, false).
func memcpy(dst, src unsafe.Pointer, size uintptr)
// Copy size bytes from src to dst. The memory areas may overlap and will do the
// correct thing.
func memmove(dst, src unsafe.Pointer, size uintptr) {
if uintptr(dst) < uintptr(src) {
// Copy forwards.
memcpy(dst, src, size)
return
}
// Copy backwards.
for i := size; i != 0; {
i--
*(*uint8)(unsafe.Pointer(uintptr(dst) + i)) = *(*uint8)(unsafe.Pointer(uintptr(src) + i))
}
}
// Calls to this function are converted to LLVM intrinsic calls such as
// llvm.memmove.p0i8.p0i8.i32(dst, src, size, false).
func memmove(dst, src unsafe.Pointer, size uintptr)
// Set the given number of bytes to zero.
func memzero(ptr unsafe.Pointer, size uintptr) {