summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Shao <astrohavoc@gmail.com>2022-09-12 13:55:05 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-10-11 12:49:59 -0400
commit66af1399963a1872e520d1dbd1c94fd43e65082d (patch)
treed9b2ab22c705a238ad7497a26a53a6b9a083dc28
parent284cf387537110ce9139bf6ed0841c8f4f41db2a (diff)
downloadhaskell-66af1399963a1872e520d1dbd1c94fd43e65082d.tar.gz
CmmToC: emit explicit tail calls when the C compiler supports it
Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail
-rw-r--r--configure.ac2
-rw-r--r--m4/fp_musttail.m416
-rw-r--r--rts/include/Stg.h7
3 files changed, 23 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index f4c66de811..28f954a9a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -996,6 +996,8 @@ fi
FP_VISIBILITY_HIDDEN
+FP_MUSTTAIL
+
dnl ** check for librt
AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_LIB([rt], [clock_gettime], [AC_SUBST([CabalHaveLibrt], [True])], [AC_SUBST([CabalHaveLibrt], [False])])
diff --git a/m4/fp_musttail.m4 b/m4/fp_musttail.m4
new file mode 100644
index 0000000000..e309f44c7b
--- /dev/null
+++ b/m4/fp_musttail.m4
@@ -0,0 +1,16 @@
+# FP_MUSTTAIL
+# ----------------------------------
+# Is the musttail attribute supported?
+AC_DEFUN([FP_MUSTTAIL],
+[
+ AC_MSG_CHECKING([whether __attribute__((musttail)) is supported])
+ echo 'extern int foo(void); int bar(void) { __attribute__((musttail)) return foo(); }' > conftest.c
+ if $CC -c conftest.c -o conftest.o
+ then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAS_MUSTTAIL, 1, [Has musttail])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ rm -f conftest.c conftest.o
+])
diff --git a/rts/include/Stg.h b/rts/include/Stg.h
index 5849de32c1..31a7a55e9c 100644
--- a/rts/include/Stg.h
+++ b/rts/include/Stg.h
@@ -325,7 +325,11 @@ external prototype return neither of these types to workaround #11395.
Tail calls
-------------------------------------------------------------------------- */
-#define JMP_(cont) return((StgFunPtr)(cont))
+#if defined(HAS_MUSTTAIL)
+#define JMP_(cont) { StgFunPtr (*_f)(void) = (StgFunPtr (*)(void))(cont); __attribute__((musttail)) return _f(); }
+#else
+#define JMP_(cont) return (StgFunPtr)(cont)
+#endif
/* -----------------------------------------------------------------------------
Other Stg stuff...
@@ -591,4 +595,3 @@ typedef union {
c; \
})
#endif
-