Use static inline functions for float <-> Datum conversions.
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>
This commit is contained in:
parent
0e0f43d6fd
commit
14cca1bf8e
|
@ -2126,10 +2126,7 @@ fmgr(Oid procedureId,...)
|
||||||
*
|
*
|
||||||
* int8, float4, and float8 can be passed by value if Datum is wide enough.
|
* 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
|
* (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,
|
* at compile time even if pass-by-val is possible.)
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Note: there is only one switch controlling the pass-by-value option for
|
* 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
|
* both int8 and float8; this is to avoid making things unduly complicated
|
||||||
|
@ -2149,77 +2146,29 @@ Int64GetDatum(int64 X)
|
||||||
}
|
}
|
||||||
#endif /* USE_FLOAT8_BYVAL */
|
#endif /* USE_FLOAT8_BYVAL */
|
||||||
|
|
||||||
|
#ifndef USE_FLOAT4_BYVAL
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
Float4GetDatum(float4 X)
|
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));
|
float4 *retval = (float4 *) palloc(sizeof(float4));
|
||||||
|
|
||||||
*retval = X;
|
*retval = X;
|
||||||
return PointerGetDatum(retval);
|
return PointerGetDatum(retval);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_FLOAT4_BYVAL
|
#ifndef USE_FLOAT8_BYVAL
|
||||||
|
|
||||||
float4
|
|
||||||
DatumGetFloat4(Datum X)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
int32 value;
|
|
||||||
float4 retval;
|
|
||||||
} myunion;
|
|
||||||
|
|
||||||
myunion.value = GET_4_BYTES(X);
|
|
||||||
return myunion.retval;
|
|
||||||
}
|
|
||||||
#endif /* USE_FLOAT4_BYVAL */
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
Float8GetDatum(float8 X)
|
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));
|
float8 *retval = (float8 *) palloc(sizeof(float8));
|
||||||
|
|
||||||
*retval = X;
|
*retval = X;
|
||||||
return PointerGetDatum(retval);
|
return PointerGetDatum(retval);
|
||||||
|
}
|
||||||
#endif
|
#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 */
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
|
|
|
@ -656,6 +656,14 @@ extern Datum Int64GetDatum(int64 X);
|
||||||
#define UInt64GetDatum(X) Int64GetDatum((int64) (X))
|
#define UInt64GetDatum(X) Int64GetDatum((int64) (X))
|
||||||
#endif
|
#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
|
* DatumGetFloat4
|
||||||
* Returns 4-byte floating point value of a datum.
|
* Returns 4-byte floating point value of a datum.
|
||||||
|
@ -664,7 +672,18 @@ extern Datum Int64GetDatum(int64 X);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_FLOAT4_BYVAL
|
#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
|
#else
|
||||||
#define DatumGetFloat4(X) (* ((float4 *) DatumGetPointer(X)))
|
#define DatumGetFloat4(X) (* ((float4 *) DatumGetPointer(X)))
|
||||||
#endif
|
#endif
|
||||||
|
@ -676,8 +695,22 @@ extern float4 DatumGetFloat4(Datum X);
|
||||||
* Note: if float4 is pass by reference, this function returns a reference
|
* Note: if float4 is pass by reference, this function returns a reference
|
||||||
* to palloc'd space.
|
* 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);
|
extern Datum Float4GetDatum(float4 X);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DatumGetFloat8
|
* DatumGetFloat8
|
||||||
|
@ -687,7 +720,18 @@ extern Datum Float4GetDatum(float4 X);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_FLOAT8_BYVAL
|
#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
|
#else
|
||||||
#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
|
#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
|
||||||
#endif
|
#endif
|
||||||
|
@ -700,7 +744,22 @@ extern float8 DatumGetFloat8(Datum X);
|
||||||
* to palloc'd space.
|
* 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);
|
extern Datum Float8GetDatum(float8 X);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue