[PATCH] Fix clang barrier for const trick by dummy func
LoveSy
lovesykun at gmail.com
Fri Oct 8 08:56:55 UTC 2021
From: YU Jincheng <shana at zju.edu.cn>
- For clang 9+, `asm volatile ("":::"memory")`
does not ensure load after a const pointer
assigned by trick on `ASSIGN_CONST_PTR`
- We found that using a dummy function can do
this trick so this patch converts `barrier`
to an invisible dummy function
- This dummy function `barrier` should be
invisible from the caller to avoid inlining
by the compiler
- This trick introduces one instruction size
overhead which should only be 4-8 bytes and
the runtime overhead is at most one cache
miss (unconditional branch won't introduce
branch misprediction penalty)
Signed-off-by: LoveSy <shana at zju.edu.cn>
---
include/libbb.h | 5 ++++-
libbb/const_hack.c | 15 +++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 libbb/const_hack.c
diff --git a/include/libbb.h b/include/libbb.h
index 02cc008f0..56b404b03 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2284,7 +2284,6 @@ struct globals;
* If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
extern struct globals *const ptr_to_globals;
-#define barrier() asm volatile ("":::"memory")
#if defined(__clang_major__) && __clang_major__ >= 9
/* Clang/llvm drops assignment to "constant" storage. Silently.
@@ -2300,8 +2299,12 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
);
return pp;
}
+/* Clang/llvm needs an invisible dummy function for barrier
+ */
+void barrier();
#else
static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; }
+#define barrier() asm volatile ("":::"memory")
#endif
#define ASSIGN_CONST_PTR(p, v) do { \
diff --git a/libbb/const_hack.c b/libbb/const_hack.c
new file mode 100644
index 000000000..5450b82c6
--- /dev/null
+++ b/libbb/const_hack.c
@@ -0,0 +1,15 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Dummy function as barrier for const trick
+ *
+ * Copyright (C) 2021 by YU Jincheng <shana at zju.edu.cn>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#if defined(__clang_major__) && __clang_major__ >= 9
+void barrier() {
+ // dummy
+ // it should at most cost one instruction (4-8 bytes)
+}
+#endif
\ No newline at end of file
--
2.25.1
More information about the busybox
mailing list