]> granicus.if.org Git - postgresql/commitdiff
Use static inline functions for float <-> Datum conversions.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 31 Aug 2016 13:00:28 +0000 (16:00 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 31 Aug 2016 13:00:28 +0000 (16:00 +0300)
Now that we are OK with using static inline functions, we can use them
to avoid function call overhead of pass-by-val versions of Float4GetDatum,
DatumGetFloat8, and Float8GetDatum. Those functions are only a few CPU
instructions long, but they could not be written into macros previously,
because we need a local union variable for the conversion.

I kept the pass-by-ref versions as regular functions. They are very simple
too, but they call palloc() anyway, so shaving a few instructions from the
function call doesn't seem so important there.

Discussion: <dbb82a4a-2c15-ba27-dd0a-009d2aa72b77@iki.fi>

src/backend/utils/fmgr/fmgr.c
src/include/postgres.h

index 7e6a60d62411d26e11dd3a4e89e924f22a3a6cc5..7aae35074fa317c322bedf245e3d243994b8183b 100644 (file)
@@ -2126,10 +2126,7 @@ fmgr(Oid procedureId,...)
  *
  * int8, float4, and float8 can be passed by value if Datum is wide enough.
  * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
- * at compile time even if pass-by-val is possible.)  For the float types,
- * we need a support routine even if we are passing by value, because many
- * machines pass int and float function parameters/results differently;
- * so we need to play weird games with unions.
+ * at compile time even if pass-by-val is possible.)
  *
  * Note: there is only one switch controlling the pass-by-value option for
  * both int8 and float8; this is to avoid making things unduly complicated
@@ -2149,77 +2146,29 @@ Int64GetDatum(int64 X)
 }
 #endif   /* USE_FLOAT8_BYVAL */
 
+#ifndef USE_FLOAT4_BYVAL
+
 Datum
 Float4GetDatum(float4 X)
 {
-#ifdef USE_FLOAT4_BYVAL
-       union
-       {
-               float4          value;
-               int32           retval;
-       }                       myunion;
-
-       myunion.value = X;
-       return SET_4_BYTES(myunion.retval);
-#else
        float4     *retval = (float4 *) palloc(sizeof(float4));
 
        *retval = X;
        return PointerGetDatum(retval);
-#endif
 }
+#endif
 
-#ifdef USE_FLOAT4_BYVAL
-
-float4
-DatumGetFloat4(Datum X)
-{
-       union
-       {
-               int32           value;
-               float4          retval;
-       }                       myunion;
-
-       myunion.value = GET_4_BYTES(X);
-       return myunion.retval;
-}
-#endif   /* USE_FLOAT4_BYVAL */
+#ifndef USE_FLOAT8_BYVAL
 
 Datum
 Float8GetDatum(float8 X)
 {
-#ifdef USE_FLOAT8_BYVAL
-       union
-       {
-               float8          value;
-               int64           retval;
-       }                       myunion;
-
-       myunion.value = X;
-       return SET_8_BYTES(myunion.retval);
-#else
        float8     *retval = (float8 *) palloc(sizeof(float8));
 
        *retval = X;
        return PointerGetDatum(retval);
-#endif
 }
-
-#ifdef USE_FLOAT8_BYVAL
-
-float8
-DatumGetFloat8(Datum X)
-{
-       union
-       {
-               int64           value;
-               float8          retval;
-       }                       myunion;
-
-       myunion.value = GET_8_BYTES(X);
-       return myunion.retval;
-}
-#endif   /* USE_FLOAT8_BYVAL */
+#endif
 
 
 /*-------------------------------------------------------------------------
index fb1933f8f288bea512515f674e05dcc28cccbbff..d999013238a8821ff8ab649341e6a76587dc6302 100644 (file)
@@ -656,6 +656,14 @@ extern Datum Int64GetDatum(int64 X);
 #define UInt64GetDatum(X) Int64GetDatum((int64) (X))
 #endif
 
+/*
+ * Float <-> Datum conversions
+ *
+ * These have to be implemented as inline functions rather than macros, when
+ * passing by value, because many machines pass int and float function
+ * parameters/results differently; so we need to play weird games with unions.
+ */
+
 /*
  * DatumGetFloat4
  *             Returns 4-byte floating point value of a datum.
@@ -664,7 +672,18 @@ extern Datum Int64GetDatum(int64 X);
  */
 
 #ifdef USE_FLOAT4_BYVAL
-extern float4 DatumGetFloat4(Datum X);
+static inline float4
+DatumGetFloat4(Datum X)
+{
+       union
+       {
+               int32           value;
+               float4          retval;
+       }                       myunion;
+
+       myunion.value = GET_4_BYTES(X);
+       return myunion.retval;
+}
 #else
 #define DatumGetFloat4(X) (* ((float4 *) DatumGetPointer(X)))
 #endif
@@ -676,8 +695,22 @@ extern float4 DatumGetFloat4(Datum X);
  * Note: if float4 is pass by reference, this function returns a reference
  * to palloc'd space.
  */
+#ifdef USE_FLOAT4_BYVAL
+static inline Datum
+Float4GetDatum(float4 X)
+{
+       union
+       {
+               float4          value;
+               int32           retval;
+       }                       myunion;
 
+       myunion.value = X;
+       return SET_4_BYTES(myunion.retval);
+}
+#else
 extern Datum Float4GetDatum(float4 X);
+#endif
 
 /*
  * DatumGetFloat8
@@ -687,7 +720,18 @@ extern Datum Float4GetDatum(float4 X);
  */
 
 #ifdef USE_FLOAT8_BYVAL
-extern float8 DatumGetFloat8(Datum X);
+static inline float8
+DatumGetFloat8(Datum X)
+{
+       union
+       {
+               int64           value;
+               float8          retval;
+       }                       myunion;
+
+       myunion.value = GET_8_BYTES(X);
+       return myunion.retval;
+}
 #else
 #define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
 #endif
@@ -700,7 +744,22 @@ extern float8 DatumGetFloat8(Datum X);
  * to palloc'd space.
  */
 
+#ifdef USE_FLOAT8_BYVAL
+static inline Datum
+Float8GetDatum(float8 X)
+{
+       union
+       {
+               float8          value;
+               int64           retval;
+       }                       myunion;
+
+       myunion.value = X;
+       return SET_8_BYTES(myunion.retval);
+}
+#else
 extern Datum Float8GetDatum(float8 X);
+#endif
 
 
 /*