refactor match function direct calling
This commit is contained in:
parent
aab1a15c39
commit
d1855f14e9
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user