From ece7defd50002dd4041ea433dc3bcaae9b1939a6 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 17 Oct 2003 22:20:26 -0500 Subject: [svn-r7662] Purpose: Refactor integer conversion macros Description: Turned integer conversion macros "inside" out, using an interlocking macro technique similar to templates in C++. The macro which actually performs the conversion is now invoked "genericly" from inside another macro, which will allow the inner conversion loop to be optimized in a much easier way. This "psuedo-template" technique could be useful for other semi-repetitious patterns in the library - possibly the datatype initialization code... Platforms tested: FreeBSD 4.9 (sleipnir) h5committest --- src/H5Tconv.c | 416 ++++++++++++++++++++++++++++++-------------------------- src/H5private.h | 3 + 2 files changed, 225 insertions(+), 194 deletions(-) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 47f96ba..278917c 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -121,9 +121,9 @@ H5FL_BLK_DEFINE_STATIC(array_seq); * CDATA: A pointer to the H5T_cdata_t structure that was passed to the * conversion function. * - * S_ID: The hid_t value for the source data type. + * STYPE: The hid_t value for the source data type. * - * D_ID: The hid_t value for the destination data type. + * DTYPE: The hid_t value for the destination data type. * * BUF: A pointer to the conversion buffer. * @@ -142,146 +142,172 @@ H5FL_BLK_DEFINE_STATIC(array_seq); * D_MAX: The maximum possible destination value. Source values which * are larger than D_MAX generate overflows. * + * The macros are implemented with a generic programming technique, similar + * to templates in C++. The macro which defines the "core" part of the + * conversion (which actually moves the data from the source to the destination) + * is invoked inside the H5T_CONV "template" macro by "gluing" it together, + * which allows the core conversion macro to be invoked as necessary. + * */ -#define H5T_CONV_sS(S_ALIGN,D_ALIGN,ST,DT) { \ +#define H5T_CONV_sS_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + *((DT*)d) = (DT)(*((ST*)s)); \ +} + +#define H5T_CONV_sS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)<=sizeof(DT)); \ - CI_BEGIN(S_ALIGN, D_ALIGN, ST, DT, nelmts-1) { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } CI_END; \ + H5T_CONV(H5T_CONV_sS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, nelmts-1) \ } -#define H5T_CONV_sU(STYPE,DTYPE,ST,DT) { \ +#define H5T_CONV_sU_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s)<0) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = 0; \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ +} + +#define H5T_CONV_sU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)<=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, nelmts-1) { \ - if (*((ST*)s)<0) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = 0; \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_sU, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, nelmts-1) \ +} + +#define H5T_CONV_uS_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) > (D_MAX)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ } -#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MAX) { \ +#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)<=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, nelmts-1) { \ - if (*((ST*)s) > (D_MAX)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_uS, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, nelmts-1) \ } -#define H5T_CONV_uU(STYPE,DTYPE,ST,DT) { \ +#define H5T_CONV_uU_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + *((DT*)d) = (DT)(*((ST*)s)); \ +} + +#define H5T_CONV_uU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)<=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, nelmts-1) { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } CI_END; \ + H5T_CONV(H5T_CONV_uU, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, nelmts-1) \ +} + +#define H5T_CONV_Ss_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) > (DT)(D_MAX)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else if (*((ST*)s) < (D_MIN)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MIN); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ } #define H5T_CONV_Ss(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)>=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) > (DT)(D_MAX)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else if (*((ST*)s) < (D_MIN)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MIN); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_Ss, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ +} + +#define H5T_CONV_Su_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) < 0) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = 0; \ + } \ + } else if (sizeof(ST)>sizeof(DT) && *((ST*)s)>(ST)(D_MAX)) { \ + /*sign vs. unsign ok in previous line*/ \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ } -#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MAX) { \ +#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)>=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) < 0) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = 0; \ - } \ - } else if (sizeof(ST)>sizeof(DT) && *((ST*)s)>(ST)(D_MAX)) { \ - /*sign vs. unsign ok in previous line*/ \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_Su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ } -#define H5T_CONV_Us(STYPE,DTYPE,ST,DT,D_MAX) { \ +#define H5T_CONV_Us_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) > (D_MAX)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ +} + +#define H5T_CONV_Us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)>=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) > (D_MAX)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_Us, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ +} + +#define H5T_CONV_Uu_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) > (D_MAX)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ } -#define H5T_CONV_Uu(STYPE,DTYPE,ST,DT,D_MAX) { \ +#define H5T_CONV_Uu(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)>=sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) > (D_MAX)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_Uu, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ } -#define H5T_CONV_su(STYPE,DTYPE,ST,DT) { \ +#define H5T_CONV_su_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) < 0) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = 0; \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ +} + +#define H5T_CONV_su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)==sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) < 0) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = 0; \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_su, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ +} + +#define H5T_CONV_us_CORE(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)s) > (D_MAX)) { \ + if (!H5T_overflow_g || \ + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ + *((DT*)d) = (D_MAX); \ + } \ + } else { \ + *((DT*)d) = (DT)(*((ST*)s)); \ + } \ } -#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MAX) { \ +#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)==sizeof(DT)); \ - CI_BEGIN(STYPE, DTYPE, ST, DT, 0) { \ - if (*((ST*)s) > (D_MAX)) { \ - if (!H5T_overflow_g || \ - (H5T_overflow_g)(src_id, dst_id, s, d)<0) { \ - *((DT*)d) = (D_MAX); \ - } \ - } else { \ - *((DT*)d) = (DT)(*((ST*)s)); \ - } \ - } CI_END; \ + H5T_CONV(H5T_CONV_us, STYPE, DTYPE, ST, DT, D_MIN, D_MAX, 0) \ } -/* The first part of every integer hardware conversion macro */ -#define CI_BEGIN(STYPE,DTYPE,ST,DT,STRT) { \ +/* The main part of every integer hardware conversion macro */ +#define H5T_CONV(GUTS,STYPE,DTYPE,ST,DT,D_MIN,D_MAX,STRT) { \ hsize_t elmtno; /*element number */ \ void *src, *s; /*source buffer */ \ void *dst, *d; /*destination buffer */ \ @@ -342,8 +368,8 @@ H5FL_BLK_DEFINE_STATIC(array_seq); ((size_t)buf%H5T_NATIVE_##DTYPE##_ALIGN_g || \ /* Cray */ ((size_t)((DT*)buf)!=(size_t)buf) || \ d_stride%H5T_NATIVE_##DTYPE##_ALIGN_g); \ - CI_INC_SRC(s_mv) \ - CI_INC_DST(d_mv) \ + CI_INC_SRC(s_mv) \ + CI_INC_DST(d_mv) \ \ for (elmtno=0; elmtno