UNREG: use __builtin___clear_cache where available
authorSergei Trofimovich <slyfox@gentoo.org>
Wed, 21 Jun 2017 20:17:51 +0000 (21:17 +0100)
committerSergei Trofimovich <slyfox@gentoo.org>
Thu, 22 Jun 2017 20:31:09 +0000 (21:31 +0100)
Noticed when was building UNREG ghc with -optc{-Wall,-Werror}:

  rts/sm/Storage.c:1359:3: error:
     error: implicit declaration of function '__clear_cache'
       [-Werror=implicit-function-declaration]
       __clear_cache((void*)begin, (void*)end);
       ^~~~~~~~~~~~~
       |
  1359 |   __clear_cache((void*)begin, (void*)end);
       |   ^

Left direct '__clear_cache' usage gcc toolchain before 4.4.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
rts/sm/Storage.c

index 4aa4b12..e243517 100644 (file)
@@ -1341,6 +1341,14 @@ StgWord calcTotalCompactW (void)
 #include <libkern/OSCacheControl.h>
 #endif
 
+#if defined(__GNUC__)
+/* __clear_cache is a libgcc function.
+ * It existed before __builtin___clear_cache was introduced.
+ * See Trac #8562.
+ */
+extern void __clear_cache(char * begin, char * end);
+#endif /* __GNUC__ */
+
 /* On ARM and other platforms, we need to flush the cache after
    writing code into memory, so the processor reliably sees it. */
 void flushExec (W_ len, AdjustorExecutable exec_addr)
@@ -1356,7 +1364,15 @@ void flushExec (W_ len, AdjustorExecutable exec_addr)
   /* For all other platforms, fall back to a libgcc builtin. */
   unsigned char* begin = (unsigned char*)exec_addr;
   unsigned char* end   = begin + len;
+
+  /* __builtin___clear_cache is supported since GNU C 4.3.6.
+   * We pick 4.4 to simplify condition a bit.
+   */
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+  __builtin___clear_cache((void*)begin, (void*)end);
+# else
   __clear_cache((void*)begin, (void*)end);
+# endif
 #else
 #error Missing support to flush the instruction cache
 #endif