mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-01 19:45:33 +08:00
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.
|
||||
* (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
|
||||
}
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user