summaryrefslogtreecommitdiff
path: root/lib/scudo/scudo_crc32.cpp
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-01-10 16:39:36 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-01-10 16:39:36 +0000
commitc4d8f3f75433e6eb6ef37a23255fa8e9becfb70f (patch)
tree0a2599ed57e758980c895fd79fe396e76c3aa6bf /lib/scudo/scudo_crc32.cpp
parent60d67c3850c0d7768976410a996368ab56a0f4bf (diff)
[scudo] Separate hardware CRC32 routines
Summary: As raised in D28304, enabling SSE 4.2 for the whole Scudo tree leads to the emission of SSE 4.2 instructions everywhere, while the runtime checks only applied to the CRC32 computing function. This patch separates the CRC32 function taking advantage of the hardware into its own file, and only enabled -msse4.2 for that file, if detected to be supported by the compiler. Another consequence of removing SSE4.2 globally is realizing that memcpy were not being optimized, which turned out to be due to the -fno-builtin in SANITIZER_COMMON_CFLAGS. So we now explicitely enable builtins for Scudo. The resulting assembly looks good, with some CALLs are introduced instead of the CRC32 code being inlined. Reviewers: kcc, mgorny, alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D28417 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@291570 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/scudo/scudo_crc32.cpp')
-rw-r--r--lib/scudo/scudo_crc32.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/scudo/scudo_crc32.cpp b/lib/scudo/scudo_crc32.cpp
new file mode 100644
index 000000000..94c8c2424
--- /dev/null
+++ b/lib/scudo/scudo_crc32.cpp
@@ -0,0 +1,53 @@
+//===-- scudo_crc32.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// CRC32 function leveraging hardware specific instructions. This has to be
+/// kept separated to restrict the use of compiler specific flags to this file.
+///
+//===----------------------------------------------------------------------===//
+
+// Hardware CRC32 is supported at compilation via the following:
+// - for i386 & x86_64: -msse4.2
+// - for ARM & AArch64: -march=armv8-a+crc or -mcrc
+// An additional check must be performed at runtime as well to make sure the
+// emitted instructions are valid on the target host.
+#include "scudo_crc32.h"
+#include "scudo_utils.h"
+
+#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+# ifdef __SSE4_2__
+# include <smmintrin.h>
+# define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
+# endif
+# ifdef __ARM_FEATURE_CRC32
+# include <arm_acle.h>
+# define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
+# endif
+#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+
+namespace __scudo {
+
+#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+INLINE u32 computeHardwareCRC32(u32 Crc, uptr Data) {
+ return CRC32_INTRINSIC(Crc, Data);
+}
+
+u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
+ if (HashType == CRC32Hardware) {
+ return computeHardwareCRC32(Crc, Data);
+ }
+ return computeSoftwareCRC32(Crc, Data);
+}
+#else
+u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
+ return computeSoftwareCRC32(Crc, Data);
+}
+#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+
+} // namespace __scudo