refactor match function direct calling

This commit is contained in:
dzaima 2025-05-22 23:56:02 +03:00
parent aab1a15c39
commit d1855f14e9
5 changed files with 28 additions and 29 deletions

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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