fillarr NOGC

This commit is contained in:
dzaima 2023-03-26 15:36:29 +03:00
parent 709c1896d3
commit 1f70c08aa2
13 changed files with 60 additions and 58 deletions

View File

@ -80,10 +80,9 @@ B ud_c1(B t, B x) {
}
decG(x);
Arr* r = m_fillarrp(ria); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
FILL_TO(rp, el_B, 0, m_f64(0), ria); // don't have r in undefined state if allocation errors
Arr* r = m_fillarr0p(ria);
B* rp = fillarr_ptr(r);
ud_rec(rp, 0, xia, pos, sh);
usz* rsh = arr_shAlloc(r, xia);
@ -135,8 +134,7 @@ B ud_c2(B t, B w, B x) {
for (usz i=wr; i<xr; i++) wsh[i] = xsh[i];
if (empty) {
Arr* ra = arr_shSetU(m_fillarrp(0), rr, sh);
fillarr_setFill(ra, getFillQ(x));
Arr* ra = arr_shSetU(m_fillarrpEmpty(getFillQ(x)), rr, sh);
decG(x);
return taga(ra);
}

View File

@ -81,12 +81,11 @@ static B group_simple(B w, B x, ur xr, usz wia, usz xn, usz* xsh, u8 we) {
if (bad) thrM("⊔: 𝕨 can't contain elements less than ¯1");
if (ria > (i64)(USZ_MAX)) thrOOM();
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
Arr* r = m_fillarr0p(ria);
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
B xf = getFillQ(x);
Arr* rf = m_fillarrp(0); fillarr_setFill(rf, xf);
Arr* rf = m_fillarrpEmpty(xf);
if (xr==1) arr_shVec(rf); else arr_shChangeLen(rf, xr, xsh, 0);
B z = taga(rf);
@ -229,12 +228,14 @@ static B group_simple(B w, B x, ur xr, usz wia, usz xn, usz* xsh, u8 we) {
Arr* c = m_fillarrp(l*csz);
c->ia = 0;
fillarr_setFill(c, inc(xf));
NOGC_E; // ia=0 means that this is a "safe" array
if (xr==1) arr_shVec(c); else arr_shChangeLen(c, xr, xsh, l);
rp[i] = taga(c);
}
if (csz==0) goto done;
SLOW2("𝕨⊔𝕩", w, x);
SGet(x)
NOGC_S; // ia==0 of the elements means they're in a sort of invalid state; though it should be fine as `x` references all the items that may be in them, so this NOGC isn't strictly necessary
if (csz == 1) {
for (usz i = 0; i < xn; i++) {
i32 n = wp[i];
@ -250,6 +251,7 @@ static B group_simple(B w, B x, ur xr, usz wia, usz xn, usz* xsh, u8 we) {
}
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i]*csz;
NOGC_E;
}
done:
@ -294,27 +296,26 @@ B group_c2(B t, B w, B x) {
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < xn; i++) len[o2i64G(GetU(w, i))]++;
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
Arr* r = m_fillarr0p(ria);
B xf = getFillQ(x);
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) {
Arr* c = m_fillarrp(len[i]);
c->ia = 0;
fillarr_setFill(c, inc(xf));
NOGC_E; // see comments in group_simple
arr_shVec(c);
rp[i] = taga(c);
}
Arr* rf = m_fillarrp(0); arr_shVec(rf);
fillarr_setFill(rf, xf);
fillarr_setFill(r, taga(rf));
fillarr_setFill(r, taga(arr_shVec(m_fillarrpEmpty(xf))));
SGet(x)
NOGC_S;
for (usz i = 0; i < xn; i++) {
i64 n = o2i64G(GetU(w, i));
if (n>=0) fillarr_ptr(a(rp[n]))[pos[n]++] = Get(x, i);
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i];
NOGC_E;
decG(w); decG(x); TFREE(lenO); TFREE(pos);
return taga(r);
}

View File

@ -185,18 +185,13 @@ B variation_c2(B t, B w, B x) {
else if (u8_get(&wp, wpE, "f64")) res = taga(cpyF64Arr(incG(x)));
else if (u8_get(&wp, wpE, "h" )) res = taga(cpyHArr (incG(x)));
else if (u8_get(&wp, wpE, "f")) {
Arr* t = m_fillarrp(xia);
fillarr_setFill(t, getFillQ(x));
arr_shCopy(t, x);
HArr* h = NULL;
Arr* r = m_fillarrp(xia);
fillarr_setFill(r, getFillQ(x));
arr_shCopy(r, x);
COPY_TO(fillarr_ptr(r), el_B, 0, x, 0, xia);
NOGC_E;
B* xp = TO_BPTR(x);
B* rp = fillarr_ptr(t);
for (usz i = 0; i < xia; i++) rp[i] = inc(xp[i]);
if (h) ptr_dec(h);
res = taga(t);
res = taga(r);
} else thrF("•internal.Variation: Bad type \"%R\"", taga(wc));
if (slice) {
@ -255,9 +250,10 @@ static B unshare(B x) {
return unshareShape(a(HARR_FC(r, x)));
}
case t_fillarr: case t_fillslice: {
Arr* r = m_fillarrp(xia); arr_shCopy(r, x);
Arr* r = arr_shCopy(m_fillarr0p(xia), x);
fillarr_setFill(r, unshare(getFillQ(x)));
B* rp = fillarr_ptr(r); B* xp = fillarr_ptr(a(x));
B* rp = fillarr_ptr(r);
B* xp = fillarr_ptr(a(x));
for (usz i = 0; i < xia; i++) rp[i] = unshare(xp[i]);
return unshareShape(r);
}

View File

@ -204,9 +204,7 @@ static B to_fill_cell_1(B x) { // consumes x
static B merge_fill_result_1(B rc) {
u64 rr = isArr(rc)? RNK(rc)+1ULL : 1;
if (rr>UR_MAX) thrM("˘: Result rank too large");
B rf = getFillQ(rc);
Arr* r = m_fillarrp(0);
fillarr_setFill(r, rf);
Arr* r = m_fillarrpEmpty(getFillQ(rc));
usz* rsh = arr_shAlloc(r, rr);
if (rr>1) {
rsh[0] = 0;

View File

@ -248,9 +248,7 @@ static B to_fill_cell(B x, ur k) {
static B merge_fill_result(B rc, ur k, usz* sh) {
u64 rr = k; if (isArr(rc)) rr += RNK(rc);
if (rr>UR_MAX) thrM("⎉: Result rank too large");
B rf = getFillQ(rc);
Arr* r = m_fillarrp(0);
fillarr_setFill(r, rf);
Arr* r = m_fillarrpEmpty(getFillQ(rc));
usz* rsh = arr_shAlloc(r, rr);
if (rr>1) {
shcpy(rsh, sh, k);

View File

@ -126,6 +126,7 @@ B select_c2(B t, B w, B x) {
arr_shAtm(r);
fillarr_ptr(r)[0] = xv;
fillarr_setFill(r, xf);
NOGC_E;
rb = taga(r);
}
decG(x);

View File

@ -15,7 +15,7 @@ NOINLINE Arr* emptyArr(B x, ur xr) {
if (isF64(xf)) { u64* rp; r = m_bitarrp(&rp, 0); }
else if (noFill(xf)) { r = (Arr*) m_harrUp(0).c; }
else if (isC32(xf)) { u8* rp; r = m_c8arrp(&rp, 0); }
else { r = m_fillarrp(0); fillarr_setFill(r, xf); }
else { r = m_fillarrpEmpty(xf); }
if (xr<=1) arr_rnk01(r, xr);
return r;
}
@ -53,6 +53,7 @@ B m_vec1(B a) {
Arr* ra = arr_shVec(m_fillarrp(1));
fillarr_ptr(ra)[0] = a;
fillarr_setFill(ra, m_f64(0));
NOGC_E;
fillarr_setFill(ra, asFill(inc(a)));
return taga(ra);
}
@ -86,6 +87,7 @@ FORCE_INLINE B m_vec2Base(B a, B b, bool fills) {
fillarr_setFill(ra, af);
fillarr_ptr(ra)[0] = a;
fillarr_ptr(ra)[1] = b;
NOGC_E;
return taga(ra);
}
noFills:
@ -325,10 +327,12 @@ B shape_c2(B t, B w, B x) {
else { FILL(c32,u32,c*0x0000000100000001) }
} else {
incBy(x, nia); // in addition with the existing reference, this covers the filled amount & asFill
B rf = asFill(x);
r = m_fillarrp(nia);
if (sizeof(B)==8) fill_words(fillarr_ptr(r), x.u, (u64)nia*8);
else for (usz i = 0; i < nia; i++) fillarr_ptr(r)[i] = x;
fillarr_setFill(r, asFill(x));
fillarr_setFill(r, rf);
NOGC_E;
}
#undef FILL
}
@ -1266,6 +1270,7 @@ B pick_ucw(B t, B o, B w, B x) {
fillarr_setFill(x2, getFillQ(x));
xp = fillarr_ptr(x2);
COPY_TO(xp, el_B, 0, x, 0, xia);
NOGC_E;
arr_shCopy(x2, x);
dec(x);
x = taga(x2);

View File

@ -328,11 +328,11 @@ static NOINLINE B zeroCells(B x) { // doesn't consume
u8 xe = TI(x,elType);
B r; ur xr = RNK(x);
if (xr==1) {
if (xe==el_B) { B xf = getFillR(x); r = noFill(xf)? emptyHVec() : m_emptyFVec(xf); }
if (xe==el_B) { B xf = getFillR(x); r = noFill(xf)? emptyHVec() : taga(arr_shVec(m_fillarrpEmpty(xf))); }
else r = elNum(xe)? emptyIVec() : emptyCVec();
} else {
Arr* ra;
if (xe==el_B) { B xf = getFillR(x); if (noFill(xf)) ra = (Arr*)m_harrUp(0).c; else { ra = m_fillarrp(0); fillarr_setFill(ra, xf); } }
if (xe==el_B) { B xf = getFillR(x); ra = noFill(xf)? (Arr*)m_harrUp(0).c : m_fillarrpEmpty(xf); }
else m_tyarrp(&ra, 1, 0, elNum(xe)? t_bitarr : t_c8arr);
usz* rsh = arr_shAlloc(ra, xr);
shcpy(rsh+1, SH(x)+1, xr-1);

View File

@ -60,17 +60,26 @@ static B getFillE(B x) { // errors if there's no fill
}
static Arr* m_fillarrp(usz ia) {
static Arr* m_fillarrp(usz ia) { // needs a NOGC_E after fill & all elements are initialized
CHECK_IA(ia, sizeof(B));
return m_arr(fsizeof(FillArr,a,B,ia), t_fillarr, ia);
Arr* r = m_arr(fsizeof(FillArr,a,B,ia), t_fillarr, ia);
NOGC_S;
return r;
}
static void fillarr_setFill(Arr* x, B fill) { assert(PTY(x)==t_fillarr); ((FillArr*)x)->fill = fill; } // consumes fill
static B* fillarr_ptr(Arr* x) { assert(PTY(x)==t_fillarr); return ((FillArr*)x)->a; }
static B m_emptyFVec(B f) { // consumes f
Arr* r = arr_shVec(m_fillarrp(0));
fillarr_setFill(r, f);
return taga(r);
static Arr* m_fillarrpEmpty(B fill) {
Arr* r = m_fillarrp(0);
fillarr_setFill(r, fill);
NOGC_E;
return r;
}
static Arr* m_fillarr0p(usz ia) { // zero-initialized fillarr, with both fill & elements set to m_f64(0)
Arr* r = arr_shVec(m_fillarrp(ia));
fillarr_setFill(r, m_f64(0));
FILL_TO(fillarr_ptr(r), el_B, 0, m_f64(0), ia);
NOGC_E;
return r;
}
B m_unit(B x); // consumes

View File

@ -631,9 +631,7 @@ B bqn_merge(B x) {
B xf = getFillE(x);
if (isAtm(xf)) { dec(xf); return x; }
i32 xfr = RNK(xf);
B xff = getFillQ(xf);
Arr* r = m_fillarrp(0);
fillarr_setFill(r, xff);
Arr* r = m_fillarrpEmpty(getFillQ(xf));
if (xr+xfr > UR_MAX) thrM(">: Result rank too large");
usz* rsh = arr_shAlloc(r, xr+xfr);
if (rsh) {

View File

@ -136,6 +136,13 @@ static bool eqShape(B w, B x) { assert(isArr(w)); assert(isArr(x));
return eqShPart(wsh, xsh, wr);
}
typedef void (*M_CopyF)(void*, usz, B, usz, usz);
typedef void (*M_FillF)(void*, usz, B, usz);
extern M_CopyF copyFns[el_MAX];
extern M_FillF fillFns[el_MAX];
#define COPY_TO(WHERE, ELT, MS, X, XS, LEN) copyFns[ELT](WHERE, MS, X, XS, LEN)
#define FILL_TO(WHERE, ELT, MS, X, LEN) fillFns[ELT](WHERE, MS, X, LEN)
B bit_sel(B b, B e0, B e1); // consumes b; b must be bitarr; b⊏e0‿e1
Arr* allZeroes(usz ia);
Arr* allOnes(usz ia);

View File

@ -101,7 +101,6 @@ void tyarr_init(void) {
{ u64* tmp; bi_emptyIVec = m_bitarrv(&tmp, 0); gc_add(bi_emptyIVec); }
{ u8* tmp; bi_emptyCVec = m_c8arrv (&tmp, 0); gc_add(bi_emptyCVec); }
Arr* emptySVec = arr_shVec(m_fillarrp(0));
fillarr_setFill(emptySVec, emptyCVec());
Arr* emptySVec = arr_shVec(m_fillarrpEmpty(emptyCVec()));
bi_emptySVec = taga(emptySVec); gc_add(bi_emptySVec);
}

View File

@ -7,14 +7,6 @@
static inline B m1c1_unsafe(D1C1 m, B f, B x) { Md1D d; d.f=f; return m(&d, x); }
static inline B m1c2_unsafe(D1C2 m, B f, B w, B x) { Md1D d; d.f=f; return m(&d, w, x); }
typedef void (*M_CopyF)(void*, usz, B, usz, usz);
typedef void (*M_FillF)(void*, usz, B, usz);
extern M_CopyF copyFns[el_MAX];
extern M_FillF fillFns[el_MAX];
#define COPY_TO(WHERE, ELT, MS, X, XS, LEN) copyFns[ELT](WHERE, MS, X, XS, LEN)
#define FILL_TO(WHERE, ELT, MS, X, LEN) fillFns[ELT](WHERE, MS, X, LEN)
typedef void (*CmpAAFn)(u64*, void*, void*, u64);
typedef void (*CmpASFn)(u64*, void*, u64, u64);
#define CMP_DEF(F, S) extern Cmp##S##Fn cmp_fns_##F##S[];