From d78a45a4573b135273f9259571a561bf75fd0104 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 12 Mar 2022 03:44:46 +0200 Subject: [PATCH] smarter virtual function reading deduplication --- src/builtins/sfns.c | 22 ++++++++++++++++++++-- src/utils/mut.c | 1 + src/utils/mut.h | 29 ++++++++++++----------------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 7c6dfcad..bf583ae6 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -9,6 +9,7 @@ static Arr* take_impl(usz ria, B x) { // consumes x; returns v↑⥊𝕩 without if (ria>xia) { B xf = getFillE(x); MAKE_MUT(r, ria); mut_init(r, TI(x,elType)); + MUTG_INIT(r); mut_copyG(r, 0, x, 0, xia); mut_fill(r, xia, xf, ria-xia); dec(x); @@ -204,6 +205,7 @@ B shape_c2(B t, B w, B x) { } MAKE_MUT(m, nia); mut_init(m, TI(x,elType)); + MUTG_INIT(m); i64 div = nia/xia; i64 mod = nia%xia; for (i64 i = 0; i < div; i++) mut_copyG(m, i*xia, x, 0, xia); @@ -411,6 +413,7 @@ B select_c2(B t, B w, B x) { usz csz = arr_csz(x); usz cam = a(x)->sh[0]; MAKE_MUT(r, wia*csz); mut_init(r, TI(x,elType)); + MUTG_INIT(r); for (usz i = 0; i < wia; i++) { B cw = GetU(w, i); if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; } @@ -775,7 +778,8 @@ B take_c2(B t, B w, B x) { if (t>xia) { B xf = getFillE(x); MAKE_MUT(r, t); mut_init(r, TI(x,elType)); - mut_fill(r, 0, xf, t-xia); + mut_fill(r, 0, xf, t-xia); // TODO use G variant + MUTG_INIT(r); mut_copyG(r, t-xia, x, 0, xia); dec(x); dec(xf); a = mut_fp(r); @@ -896,6 +900,7 @@ B join_c2(B t, B w, B x) { return qWithFill(r, f); } MAKE_MUT(r, wia+xia); mut_init(r, el_or(TI(w,elType), TI(x,elType))); + MUTG_INIT(r); mut_copyG(r, 0, w, 0, wia); mut_copyG(r, wia, x, 0, xia); Arr* ra = mut_fp(r); @@ -931,6 +936,7 @@ B couple_c2(B t, B w, B x) { usz ia = a(w)->ia; ur wr = rnk(w); MAKE_MUT(r, ia*2); mut_init(r, el_or(TI(w,elType), TI(x,elType))); + MUTG_INIT(r); mut_copyG(r, 0, w, 0, ia); mut_copyG(r, ia, x, 0, ia); Arr* ra = mut_fp(r); @@ -958,6 +964,7 @@ B shiftb_c1(B t, B x) { usz csz = arr_csz(x); MAKE_MUT(r, ia); mut_init(r, TI(x,elType)); + MUTG_INIT(r); mut_copyG(r, csz, x, 0, ia-csz); mut_fill(r, 0, xf, csz); return qWithFill(mut_fcd(r, x), xf); @@ -970,6 +977,7 @@ B shiftb_c2(B t, B w, B x) { usz wia = a(w)->ia; usz xia = a(x)->ia; MAKE_MUT(r, xia); mut_init(r, el_or(TI(w,elType), TI(x,elType))); + MUTG_INIT(r); int mid = wiaia; usz xia = a(x)->ia; MAKE_MUT(r, xia); mut_init(r, el_or(TI(w,elType), TI(x,elType))); + MUTG_INIT(r); if (wia < xia) { usz m = xia-wia; mut_copyG(r, 0, x, wia, m); @@ -1153,6 +1163,7 @@ B reverse_c1(B t, B x) { usz rp = 0; usz ip = xia; MAKE_MUT(r, xia); mut_init(r, xe); + MUTG_INIT(r); for (usz i = 0; i < cam; i++) { ip-= csz; mut_copyG(r, rp, x, ip, csz); @@ -1172,6 +1183,7 @@ B reverse_c2(B t, B w, B x) { if ((u64)am >= (u64)cam) { am%= (i64)cam; if(am<0) am+= cam; } am*= csz; MAKE_MUT(r, xia); mut_init(r, TI(x,elType)); + MUTG_INIT(r); mut_copyG(r, 0, x, am, xia-am); mut_copyG(r, xia-am, x, 0, am); return withFill(mut_fcd(r, x), xf); @@ -1244,6 +1256,7 @@ B pick_uc1(B t, B o, B x) { B arg = IGet(x, 0); B rep = c1(o, arg); MAKE_MUT(r, ia); mut_init(r, el_or(TI(x,elType), selfElType(rep))); + MUTG_INIT(r); mut_setG(r, 0, rep); mut_copyG(r, 1, x, 1, ia-1); return qWithFill(mut_fcd(r, x), xf); @@ -1274,6 +1287,7 @@ B pick_ucw(B t, B o, B w, B x) { } } MAKE_MUT(r, xia); mut_init(r, el_or(TI(x,elType), selfElType(rep))); + MUTG_INIT(r); mut_setG(r, wi, rep); mut_copyG(r, 0, x, 0, wi); mut_copyG(r, wi+1, x, wi+1, xia-wi-1); @@ -1308,10 +1322,12 @@ B slash_ucw(B t, B o, B w, B x) { repI+= v; } } else { + MUTG_INIT(r); for (usz i = 0; i < ia; i++) mut_setG(r, i, bitp_get(d, i)? Get(rep,repI++) : Get(x,i)); } } else { SGetU(rep) + MUTG_INIT(r); for (usz i = 0; i < ia; i++) { i32 cw = o2iu(GetU(w, i)); if (cw) { @@ -1429,6 +1445,7 @@ B select_ucw(B t, B o, B w, B x) { } } MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); + MUTG_INIT(r); mut_copyG(r, 0, x, 0, xia); SGet(rep) for (usz i = 0; i < wia; i++) { @@ -1442,6 +1459,7 @@ B select_ucw(B t, B o, B w, B x) { return mut_fcd(r, x); } MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); + MUTG_INIT(r); mut_copyG(r, 0, x, 0, xia); SGet(rep) for (usz i = 0; i < wia; i++) { diff --git a/src/utils/mut.c b/src/utils/mut.c index 210204dd..f60ee23f 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -37,6 +37,7 @@ NOINLINE void mut_to(Mut* m, u8 n) { NOINLINE B vec_addR(B w, B x) { usz wia = a(w)->ia; MAKE_MUT(r, wia+1); mut_init(r, el_or(TI(w,elType), selfElType(x))); + MUTG_INIT(r); mut_copyG(r, 0, w, 0, wia); mut_setG(r, wia, x); dec(w); diff --git a/src/utils/mut.h b/src/utils/mut.h index 3cde61b8..068f2e4c 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -98,15 +98,6 @@ static u8 el_or(u8 a, u8 b) { void mut_pfree(Mut* m, usz n); -// do N = OBJ; F, while asserting that OBJ won't change during F -#define CONST_OP(N, OBJ, F) ({ \ - __auto_type N = OBJ; \ - F; \ - if (N!=OBJ) __builtin_unreachable(); \ -}) - -#define MUTG(NAME, ...) CONST_OP(f, m->fns->m_##NAME##G, f(__VA_ARGS__)) - // consumes x; sets m[ms] to x static void mut_set(Mut* m, usz ms, B x) { m->fns->m_set(m, ms, x); } @@ -117,20 +108,23 @@ static void mut_rm(Mut* m, usz ms) { if (m->fns->elType == el_B) dec(m->aB[ms]); // gets object at position ms, without increasing refcount static B mut_getU(Mut* m, usz ms) { return m->fns->m_getU(m, ms); } - // doesn't consume; fills m[ms…ms+l] with x static void mut_fill(Mut* m, usz ms, B x, usz l) { m->fns->m_fill(m, ms, x, l); } // expects x to be an array, each position must be written to precisely once -// doesn't consume x +// doesn't consume static void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { assert(isArr(x)); m->fns->m_copy(m, ms, x, xs, l); } -// mut_set but assumes the type of x already fits in m -static void mut_setG(Mut* m, usz ms, B x) { MUTG(set, m, ms, x); } -// mut_fill but assumes the type of x already fits in m -static void mut_fillG(Mut* m, usz ms, B x, usz l) { MUTG(fill, m, ms, x, l); } -// mut_copy but assumes the type of x already fits in m -static void mut_copyG(Mut* m, usz ms, B x, usz xs, usz l) { MUTG(copy, m, ms, x, xs, l); } + +#define MUTG_INIT(N) MutFns N##_mutfns = *N->fns +// // mut_set but assumes the type of x already fits in m +#define mut_setG(N, ms, x) N##_mutfns.m_setG(N, ms, x) +// // mut_fill but assumes the type of x already fits in m +#define mut_fillG(N, ms, x, l) N##_mutfns.m_fillG(N, ms, x, l) +// // mut_copy but assumes the type of x already fits in m +#define mut_copyG(N, ms, x, xs, l) N##_mutfns.m_copyG(N, ms, x, xs, l) + + static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) { // TODO rewrite this whole thing to be all fancy u64 i = rs; @@ -191,6 +185,7 @@ FORCE_INLINE B vec_join_inline(B w, B x) { } } MAKE_MUT(r, ria); mut_init(r, el_or(TI(w,elType), TI(x,elType))); + MUTG_INIT(r); mut_copyG(r, 0, w, 0, wia); mut_copyG(r, wia, x, 0, xia); dec(w); dec(x);