Skip to content

Commit 14cca1b

Browse files
committed
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>
1 parent 0e0f43d commit 14cca1b

File tree

2 files changed

+67
-59
lines changed

2 files changed

+67
-59
lines changed

src/backend/utils/fmgr/fmgr.c

Lines changed: 6 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,10 +2126,7 @@ fmgr(Oid procedureId,...)
21262126
*
21272127
* int8, float4, and float8 can be passed by value if Datum is wide enough.
21282128
* (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
2129-
* at compile time even if pass-by-val is possible.) For the float types,
2130-
* we need a support routine even if we are passing by value, because many
2131-
* machines pass int and float function parameters/results differently;
2132-
* so we need to play weird games with unions.
2129+
* at compile time even if pass-by-val is possible.)
21332130
*
21342131
* Note: there is only one switch controlling the pass-by-value option for
21352132
* both int8 and float8; this is to avoid making things unduly complicated
@@ -2149,77 +2146,29 @@ Int64GetDatum(int64 X)
21492146
}
21502147
#endif /* USE_FLOAT8_BYVAL */
21512148

2149+
#ifndef USE_FLOAT4_BYVAL
2150+
21522151
Datum
21532152
Float4GetDatum(float4 X)
21542153
{
2155-
#ifdef USE_FLOAT4_BYVAL
2156-
union
2157-
{
2158-
float4 value;
2159-
int32 retval;
2160-
} myunion;
2161-
2162-
myunion.value = X;
2163-
return SET_4_BYTES(myunion.retval);
2164-
#else
21652154
float4 *retval = (float4 *) palloc(sizeof(float4));
21662155

21672156
*retval = X;
21682157
return PointerGetDatum(retval);
2169-
#endif
21702158
}
2159+
#endif
21712160

2172-
#ifdef USE_FLOAT4_BYVAL
2173-
2174-
float4
2175-
DatumGetFloat4(Datum X)
2176-
{
2177-
union
2178-
{
2179-
int32 value;
2180-
float4 retval;
2181-
} myunion;
2182-
2183-
myunion.value = GET_4_BYTES(X);
2184-
return myunion.retval;
2185-
}
2186-
#endif /* USE_FLOAT4_BYVAL */
2161+
#ifndef USE_FLOAT8_BYVAL
21872162

21882163
Datum
21892164
Float8GetDatum(float8 X)
21902165
{
2191-
#ifdef USE_FLOAT8_BYVAL
2192-
union
2193-
{
2194-
float8 value;
2195-
int64 retval;
2196-
} myunion;
2197-
2198-
myunion.value = X;
2199-
return SET_8_BYTES(myunion.retval);
2200-
#else
22012166
float8 *retval = (float8 *) palloc(sizeof(float8));
22022167

22032168
*retval = X;
22042169
return PointerGetDatum(retval);
2205-
#endif
22062170
}
2207-
2208-
#ifdef USE_FLOAT8_BYVAL
2209-
2210-
float8
2211-
DatumGetFloat8(Datum X)
2212-
{
2213-
union
2214-
{
2215-
int64 value;
2216-
float8 retval;
2217-
} myunion;
2218-
2219-
myunion.value = GET_8_BYTES(X);
2220-
return myunion.retval;
2221-
}
2222-
#endif /* USE_FLOAT8_BYVAL */
2171+
#endif
22232172

22242173

22252174
/*-------------------------------------------------------------------------

src/include/postgres.h

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,14 @@ extern Datum Int64GetDatum(int64 X);
656656
#define UInt64GetDatum(X) Int64GetDatum((int64) (X))
657657
#endif
658658

659+
/*
660+
* Float <-> Datum conversions
661+
*
662+
* These have to be implemented as inline functions rather than macros, when
663+
* passing by value, because many machines pass int and float function
664+
* parameters/results differently; so we need to play weird games with unions.
665+
*/
666+
659667
/*
660668
* DatumGetFloat4
661669
* Returns 4-byte floating point value of a datum.
@@ -664,7 +672,18 @@ extern Datum Int64GetDatum(int64 X);
664672
*/
665673

666674
#ifdef USE_FLOAT4_BYVAL
667-
extern float4 DatumGetFloat4(Datum X);
675+
static inline float4
676+
DatumGetFloat4(Datum X)
677+
{
678+
union
679+
{
680+
int32 value;
681+
float4 retval;
682+
} myunion;
683+
684+
myunion.value = GET_4_BYTES(X);
685+
return myunion.retval;
686+
}
668687
#else
669688
#define DatumGetFloat4(X) (* ((float4 *) DatumGetPointer(X)))
670689
#endif
@@ -676,8 +695,22 @@ extern float4 DatumGetFloat4(Datum X);
676695
* Note: if float4 is pass by reference, this function returns a reference
677696
* to palloc'd space.
678697
*/
698+
#ifdef USE_FLOAT4_BYVAL
699+
static inline Datum
700+
Float4GetDatum(float4 X)
701+
{
702+
union
703+
{
704+
float4 value;
705+
int32 retval;
706+
} myunion;
679707

708+
myunion.value = X;
709+
return SET_4_BYTES(myunion.retval);
710+
}
711+
#else
680712
extern Datum Float4GetDatum(float4 X);
713+
#endif
681714

682715
/*
683716
* DatumGetFloat8
@@ -687,7 +720,18 @@ extern Datum Float4GetDatum(float4 X);
687720
*/
688721

689722
#ifdef USE_FLOAT8_BYVAL
690-
extern float8 DatumGetFloat8(Datum X);
723+
static inline float8
724+
DatumGetFloat8(Datum X)
725+
{
726+
union
727+
{
728+
int64 value;
729+
float8 retval;
730+
} myunion;
731+
732+
myunion.value = GET_8_BYTES(X);
733+
return myunion.retval;
734+
}
691735
#else
692736
#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
693737
#endif
@@ -700,7 +744,22 @@ extern float8 DatumGetFloat8(Datum X);
700744
* to palloc'd space.
701745
*/
702746

747+
#ifdef USE_FLOAT8_BYVAL
748+
static inline Datum
749+
Float8GetDatum(float8 X)
750+
{
751+
union
752+
{
753+
float8 value;
754+
int64 retval;
755+
} myunion;
756+
757+
myunion.value = X;
758+
return SET_8_BYTES(myunion.retval);
759+
}
760+
#else
703761
extern Datum Float8GetDatum(float8 X);
762+
#endif
704763

705764

706765
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy