[m-rev.] diff: speed up is_finite/1 and is_nan/1 in C grades
Julien Fischer
jfischer at opturion.com
Wed Sep 17 12:01:14 AEST 2014
Speed up is_finite/1 and is_nan/1 in C grades.
The Mercury runtime procedures MR_is_{inf,nan} are defined as functions, even
on systems (e.g. all those that support the relevant bits of C99), where the
underlying C stdlib uses macros to implement those operations. Define the
above runtime procedures as macros speeds up an artificial test case (counting
infinities in a list of floats) by ~3.5%.
Change the name of MR_is_inf to MR_is_infinite.
runtime/mercury_float.h:
Rename MR_is_inf to MR_is_infinite.
Define MR_is_{infinite,nan} as macros on systems that support C99.
This avoids some unnecessary function call overhead.
Rename the function versions of MR_is_infinite and MR_is_nan to
MR_is_infinite_func and MR_is_nan_func.
runtime/mercury_float.c:
library/float.m:
Conform to the above changes.
diff --git a/library/float.m b/library/float.m
index 4b7b0c2..bc263e3 100644
--- a/library/float.m
+++ b/library/float.m
@@ -692,7 +692,7 @@ is_infinite(F) :-
[will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
does_not_affect_liveness],
"
- SUCCESS_INDICATOR = MR_is_inf(Flt);
+ SUCCESS_INDICATOR = MR_is_infinite(Flt);
").
:- pragma foreign_proc("IL",
is_inf(Flt::in),
diff --git a/runtime/mercury_float.c b/runtime/mercury_float.c
index 90ecfc4..dee4ab0 100644
--- a/runtime/mercury_float.c
+++ b/runtime/mercury_float.c
@@ -76,7 +76,7 @@ MR_sprintf_float(char *buf, MR_Float f)
return;
}
- if (MR_is_inf(f)) {
+ if (MR_is_infinite(f)) {
if (f < 0) {
strcpy(buf, "-infinity");
} else {
@@ -122,7 +122,7 @@ MR_sprintf_float(char *buf, MR_Float f)
}
MR_bool
-MR_is_nan(MR_Float Flt)
+MR_is_nan_func(MR_Float Flt)
{
#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISNANF)
return isnanf(Flt);
@@ -136,7 +136,7 @@ MR_is_nan(MR_Float Flt)
}
MR_bool
-MR_is_inf(MR_Float Flt)
+MR_is_inf_func(MR_Float Flt)
{
/*
** On Solaris, isinf() is detected by configure but we pass -fno-builtin
diff --git a/runtime/mercury_float.h b/runtime/mercury_float.h
index 7c40298..4e4a6fa 100644
--- a/runtime/mercury_float.h
+++ b/runtime/mercury_float.h
@@ -210,7 +210,31 @@ void MR_sprintf_float(char *buf, MR_Float f);
MR_Integer MR_hash_float(MR_Float);
-MR_bool MR_is_nan(MR_Float);
-MR_bool MR_is_inf(MR_Float);
+/*
+** We define MR_is_{nan,infinite} as macros if we support the relevant bits
+** of C99 since the resulting code is faster.
+*/
+#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISNANF)
+ #define MR_is_nan(f) isnanf((f))
+#elif defined(MR_HAVE_ISNAN)
+ #define MR_is_nan(f) isnan((f))
+#else
+ #define MR_is_nan(f) MS_is_nan_func((f))
+#endif
+
+/*
+** See comments for function MR_is_infinite_func in mercury_float.c for the
+** handling of Solaris here.
+*/
+#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF) && !defined(MR_SOLARIS)
+ #define MR_is_infinite(f) isinff((f))
+#elif defined(MR_HAVE_ISINF) && !defined(MR_SOLARIS)
+ #define MR_is_infinite(f) isinf((f))
+#else
+ #define MR_is_infinite(f) MR_is_infinite_func((f))
+#endif
+
+MR_bool MR_is_nan_func(MR_Float);
+MR_bool MR_is_infinite_func(MR_Float);
#endif /* not MERCURY_FLOAT_H */
More information about the reviews
mailing list