From d1855f14e94d26ccea1fcfbe6f92b18459f96864 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 22 May 2025 23:56:02 +0300 Subject: [PATCH] refactor match function direct calling --- src/builtins/cells.c | 4 ++-- src/builtins/compare.c | 30 ++++++++++++++---------------- src/builtins/fns.c | 4 ++-- src/builtins/select.c | 4 ++-- src/utils/calls.h | 15 ++++++++------- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/builtins/cells.c b/src/builtins/cells.c index 0f771d91..67770082 100644 --- a/src/builtins/cells.c +++ b/src/builtins/cells.c @@ -336,9 +336,9 @@ static NOINLINE Arr* match_cells(bool ne, B w, B x, ur wr, ur xr, ur k, usz len) CMP_AA_CALL(cmp, rp, wp, xp, len); } else { if (we==el_bit || xe==el_bit) { mm_free((Value*)r); return NULL; } - EqFnObj eqfn = EQFN_GET(we, xe); + MatchFnObj match = MATCH_GET(we, xe); for (usz i = 0; i < len; i++) { - bitp_set(rp, i, ne^EQFN_CALL(eqfn, wp, xp, csz)); + bitp_set(rp, i, ne^MATCH_CALL(match, wp, xp, csz)); wp += ww; xp += xw; } } diff --git a/src/builtins/compare.c b/src/builtins/compare.c index 31ddb92a..afeae4a3 100644 --- a/src/builtins/compare.c +++ b/src/builtins/compare.c @@ -99,10 +99,8 @@ bool atomEEqual(B w, B x) { // doesn't consume return false; } -// Functions in eqFns compare segments for matching -// data argument comes from eqFnData static const u8 n = 99; -u8 const eqFnData[] = { // for the main diagonal, amount to shift length by; otherwise, whether to swap arguments +u8 const matchFnData[] = { // for the main diagonal, amount to shift length by; otherwise, whether to swap arguments 0,0,0,0,0,n,n,n, 1,0,0,0,0,n,n,n, 1,1,1,0,0,n,n,n, @@ -173,7 +171,7 @@ static NOINLINE bool eequalFloat(void* wp0, void* xp0, u64 ia, u64 data) { } #define MAKE_TABLE(NAME, F64_F64) \ -INIT_GLOBAL EqFn NAME[] = { \ +INIT_GLOBAL MatchFn NAME[] = { \ F(1_1), F(1_8), F(1_16), F(1_32), F(1_f64), notEq, notEq, notEq, \ F(1_8), F(8_8), F(s8_16), F(s8_32), F(s8_f64), notEq, notEq, notEq, \ F(1_16), F(s8_16), F(8_8), F(s16_32), F(s16_f64), notEq, notEq, notEq, \ @@ -183,8 +181,8 @@ INIT_GLOBAL EqFn NAME[] = { \ notEq, notEq, notEq, notEq, notEq, F(u8_16), F(8_8), F(u16_32), \ notEq, notEq, notEq, notEq, notEq, F(u8_32), F(u16_32), F(8_8), \ }; -MAKE_TABLE(eqFns, F(f64_f64)); -MAKE_TABLE(eeqFns, eequalFloat); +MAKE_TABLE(matchFns, F(f64_f64)); +MAKE_TABLE(matchFnsR, eequalFloat); #undef MAKE_TABLE #undef F @@ -206,7 +204,7 @@ static NOINLINE bool eequalSlow(B w, B x, usz ia) { -#define MATCH_IMPL(ATOM, SLOW, TABLE) \ +#define MATCH_IMPL(ATOM, SLOW, MATCH) \ if (isAtm(w)) { \ if (!isAtm(x)) return false; \ return ATOM(w, x); \ @@ -217,22 +215,22 @@ static NOINLINE bool eequalSlow(B w, B x, usz ia) { usz ia = IA(x); \ if (LIKELY(wr==1)) { if (ia != IA(w)) return false; } \ else if (!eqShPart(SH(w), SH(x), wr)) return false; \ - if (ia==0) return true; \ - u8 we = TI(w,elType); \ - u8 xe = TI(x,elType); \ - if (we!=el_B && xe!=el_B) { \ - usz idx = EQFN_INDEX(we, xe); \ - return TABLE[idx](tyany_ptr(w), tyany_ptr(x), ia, eqFnData[idx]); \ - } \ + if (ia==0) return true; \ + u8 we = TI(w,elType); \ + u8 xe = TI(x,elType); \ + if (we!=el_B && xe!=el_B) { \ + MatchFnObj f = MATCH(we,xe); \ + return MATCH_CALL(f, tyany_ptr(w), tyany_ptr(x), ia); \ + } \ return SLOW(w, x, ia); NOINLINE bool equal(B w, B x) { // doesn't consume NOGC_CHECK("cannot use equal(w,x) during noAlloc"); - MATCH_IMPL(atomEqual, equalSlow, eqFns); + MATCH_IMPL(atomEqual, equalSlow, MATCH_GET); } bool eequal(B w, B x) { // doesn't consume NOGC_CHECK("cannot use eequal(w,x) during noAlloc"); if (w.u==x.u) return true; - MATCH_IMPL(atomEEqual, eequalSlow, eeqFns); + MATCH_IMPL(atomEEqual, eequalSlow, MATCHR_GET); } diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 16840c2a..7b18758b 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -264,10 +264,10 @@ B find_c2(B t, B w, B x) { usz ni = IA(ind); i32* ip = i32any_ptr(ind); u8* wp = (u8*)tyany_ptr(w) + i*elWidth(we); - EqFnObj eqfn = EQFN_GET(we, xe); + MatchFnObj match = MATCH_GET(we, xe); for (usz ii = 0; ii < ni; ii++) { usz j = ip[ii]; - if (!EQFN_CALL(eqfn, wp, xp + (i+j)*xw, wl-i)) bitp_set(rp, j, 0); + if (!MATCH_CALL(match, wp, xp + (i+j)*xw, wl-i)) bitp_set(rp, j, 0); } decG(ind); break; diff --git a/src/builtins/select.c b/src/builtins/select.c index 8ee1ed23..0e0e5796 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -581,10 +581,10 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu u8 cwidth = csz * elWidth(re); u8* rp = (u8*) tyarrv_ptr((TyArr*)ra); u8* np = tyany_ptr(rep); - EqFnObj eq = EQFN_GET(re,re); + MatchFnObj eq = MATCH_GET(re,re); for (usz i = 0; i < wia; i++) { READ_W(cw, i); - EQ1(!EQFN_CALL(eq, rp + cw*cwidth, np + i*cwidth, csz)); + EQ1(!MATCH_CALL(eq, rp + cw*cwidth, np + i*cwidth, csz)); COPY_TO(rp, re, cw*csz, rep, i*csz, csz); } goto dec_ret_ra; diff --git a/src/utils/calls.h b/src/utils/calls.h index ff787cd7..b605d3cd 100644 --- a/src/utils/calls.h +++ b/src/utils/calls.h @@ -26,13 +26,14 @@ CMP_DEF(le, AS); #define CMP_AA_IMM(FN, ELT, WHERE, WP, XP, LEN) CMP_AA_CALL(CMP_AA_FN(FN, ELT), WHERE, WP, XP, LEN) #define CMP_AS_IMM(FN, ELT, WHERE, WP, X, LEN) CMP_AS_CALL(CMP_AS_FN(FN, ELT), WHERE, WP, X, LEN) -typedef bool (*EqFn)(void* a, void* b, u64 l, u64 data); -extern INIT_GLOBAL EqFn eqFns[]; -extern u8 const eqFnData[]; -#define EQFN_INDEX(W_ELT, X_ELT) ((W_ELT)*8 + (X_ELT)) -typedef struct { EqFn fn; u8 data; } EqFnObj; -#define EQFN_GET(W_ELT, X_ELT) ({ u8 eqfn_i_ = EQFN_INDEX(W_ELT, X_ELT); (EqFnObj){.fn=eqFns[eqfn_i_], .data=eqFnData[eqfn_i_]}; }) -#define EQFN_CALL(FN, W, X, L) (FN).fn(W, X, L, (FN).data) // check if L elements starting at a and b match; assumes L≥1 +typedef bool (*MatchFn)(void* a, void* b, u64 l, u64 data); +extern INIT_GLOBAL MatchFn matchFns[]; +extern INIT_GLOBAL MatchFn matchFnsR[]; +extern u8 const matchFnData[]; +typedef struct { MatchFn fn; u8 data; } MatchFnObj; +#define MATCH_GET( W_ELT, X_ELT) ({ u8 mfn_i_ = ((W_ELT)*8 + (X_ELT)); (MatchFnObj){.fn=matchFns [mfn_i_], .data=matchFnData[mfn_i_]}; }) +#define MATCHR_GET(W_ELT, X_ELT) ({ u8 mfn_i_ = ((W_ELT)*8 + (X_ELT)); (MatchFnObj){.fn=matchFnsR[mfn_i_], .data=matchFnData[mfn_i_]}; }) +#define MATCH_CALL(FN, W, X, L) (FN).fn(W, X, L, (FN).data) // check if L elements starting at a and b match; assumes L≥1 typedef bool (*RangeFn)(void* xp, i64* res, u64 len); // assumes len≥1; if x has non-integers or values with absolute value >2⋆53, will return 0 or report min<-2⋆53 or max>2⋆53; else, writes min,max in res and returns 1 extern INIT_GLOBAL RangeFn getRange_fns[el_f64+1]; // limited to ≤el_f64