(unnamed)

text/plain

Filename: (unnamed)
Type: text/plain
Part: 0
Message: Re: FunctionCallN improvement.
#include "postgres.h"
#include "fmgr.h"

#define NARGS 2					/* Unrolled code can handle up to 10 */

/*
 * Initialize minimum fields of FunctionCallInfoData that must be
 * initialized.
 */
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs)              \
    do {                                                             \
        int     i_;                                                  \
        (Fcinfo)->flinfo = Flinfo;                                   \
        (Fcinfo)->context = NULL;                                    \
        (Fcinfo)->resultinfo = NULL;                                 \
        (Fcinfo)->isnull = false;                                    \
        (Fcinfo)->nargs = Nargs;                                     \
        for(i_ = 0; i_ < Nargs; i_++) (Fcinfo)->argnull[i_] = false; \
    } while(0)

/*
 * dummyFunc is to control excessive optimization.
 * When this function is not called from loop, the initialization of
 * FunctionCallInfoData might move outside of the loop by gcc.
 */
void dummyFunc(FunctionCallInfoData *fcinfo, int cnt)
{
    fcinfo->arg[0] = Int32GetDatum(cnt);
}

void TestMemSet(int cnt)
{
    FunctionCallInfoData fcinfo;

    printf("test MemSetLoop(%d): %d\n", NARGS, cnt);

    for(; cnt; cnt--) {
        MemSetLoop(&fcinfo, 0, sizeof(fcinfo));
        dummyFunc(&fcinfo, cnt);
    }
}

void TestOrigMacro(int cnt)
{
    FunctionCallInfoData fcinfo;

    printf("test OrigMacro(%d): %d\n", NARGS, cnt);

    for(; cnt; cnt--) {
        InitFunctionCallInfoData(&fcinfo, NULL, NARGS);
        dummyFunc(&fcinfo, cnt);
    }
}

#undef InitFunctionCallInfoData

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs)              \
    do {                                                             \
        (Fcinfo)->flinfo = Flinfo;                                   \
        (Fcinfo)->context = NULL;                                    \
        (Fcinfo)->resultinfo = NULL;                                 \
        (Fcinfo)->isnull = false;                                    \
        (Fcinfo)->nargs = Nargs;                                     \
        MemSetLoop((Fcinfo)->argnull, 0, \
                   sizeof(int32) * ((Nargs + sizeof(int32)-1) / sizeof(int32))); \
    } while(0)

void TestSetMacro(int cnt)
{
    FunctionCallInfoData fcinfo;

    printf("test SetMacro(%d): %d\n", NARGS, cnt);

    for(; cnt; cnt--) {
        InitFunctionCallInfoData(&fcinfo, NULL, NARGS);
        dummyFunc(&fcinfo, cnt);
    }
}

#undef InitFunctionCallInfoData

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs)              \
    do {                                                             \
        (Fcinfo)->flinfo = Flinfo;                                   \
        (Fcinfo)->context = NULL;                                    \
        (Fcinfo)->resultinfo = NULL;                                 \
        (Fcinfo)->isnull = false;                                    \
        (Fcinfo)->nargs = Nargs;                                     \
    } while(0)

void TestUnrolled(int cnt)
{
    FunctionCallInfoData fcinfo;

    printf("test Unrolled(%d): %d\n", NARGS, cnt);

    for(; cnt; cnt--) {
        InitFunctionCallInfoData(&fcinfo, NULL, NARGS);
#if NARGS > 0
		fcinfo.argnull[0] = false;
#endif
#if NARGS > 1
		fcinfo.argnull[1] = false;
#endif
#if NARGS > 2
		fcinfo.argnull[2] = false;
#endif
#if NARGS > 3
		fcinfo.argnull[3] = false;
#endif
#if NARGS > 4
		fcinfo.argnull[4] = false;
#endif
#if NARGS > 5
		fcinfo.argnull[5] = false;
#endif
#if NARGS > 6
		fcinfo.argnull[6] = false;
#endif
#if NARGS > 7
		fcinfo.argnull[7] = false;
#endif
#if NARGS > 8
		fcinfo.argnull[8] = false;
#endif
#if NARGS > 9
		fcinfo.argnull[9] = false;
#endif
        dummyFunc(&fcinfo, cnt);
    }
}

int main(int argc, char **argv)
{
    int     test_cnt;

    if(argc != 3) {
        printf("usage: fmgrtest -memset|-origmacro|-setmacro|-unrolled test_cnt\n");
        return 1;
    }
    test_cnt = atoi(argv[2]);

    if(strcmp(argv[1], "-memset") == 0) TestMemSet(test_cnt);
    if(strcmp(argv[1], "-origmacro") == 0) TestOrigMacro(test_cnt);
    if(strcmp(argv[1], "-setmacro") == 0) TestSetMacro(test_cnt);
    if(strcmp(argv[1], "-unrolled") == 0) TestUnrolled(test_cnt);

    return 0;
}