summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2018-09-04 22:43:30 +0000
committerKostya Serebryany <kcc@google.com>2018-09-04 22:43:30 +0000
commit380632208bda2cf9900f48a1cbdca5b2b6805ca9 (patch)
tree36a35da78cba2425f9d4218b729b0b4984e6fb47
parentf2f515f8190982a79e895bb9fc7d0ab25d68cee8 (diff)
downloadcompiler-rt-380632208bda2cf9900f48a1cbdca5b2b6805ca9.tar.gz
[sanitizer] optimize internal_memset for the most performance critical case (16-byte-aligned)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@341420 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_libc.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_libc.cc b/lib/sanitizer_common/sanitizer_libc.cc
index 4b462bfe9..4032cb104 100644
--- a/lib/sanitizer_common/sanitizer_libc.cc
+++ b/lib/sanitizer_common/sanitizer_libc.cc
@@ -73,6 +73,18 @@ void *internal_memmove(void *dest, const void *src, uptr n) {
}
void *internal_memset(void* s, int c, uptr n) {
+ // Optimize for the most performance-critical case:
+ if ((reinterpret_cast<uptr>(s) % 16) == 0 && (n % 16) == 0) {
+ u64 *p = reinterpret_cast<u64*>(s);
+ u64 *e = p + n / 8;
+ u64 v = c;
+ v |= v << 8;
+ v |= v << 16;
+ v |= v << 32;
+ for (; p < e; p += 2)
+ p[0] = p[1] = v;
+ return s;
+ }
// The next line prevents Clang from making a call to memset() instead of the
// loop below.
// FIXME: building the runtime with -ffreestanding is a better idea. However