Specialize ApdMut to reshape if there's only one append
This commit is contained in:
parent
76a40491e9
commit
3b49294145
@ -170,7 +170,7 @@ NOINLINE B leading_axis_arith(FC2 fc2, B w, B x, usz* wsh, usz* xsh, ur mr) { //
|
|||||||
if (mr==wr) w=s; else x=s;
|
if (mr==wr) w=s; else x=s;
|
||||||
return fc2(m_f64(0), w, x);
|
return fc2(m_f64(0), w, x);
|
||||||
} else {
|
} else {
|
||||||
M_APD_SH(r, mr, bsh);
|
M_APD_SH_N(r, mr, bsh, cam);
|
||||||
S_KSLICES(b, bsh, mr, cam, 1) usz bp=0;
|
S_KSLICES(b, bsh, mr, cam, 1) usz bp=0;
|
||||||
if (mr==wr) { SGetU(w); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), GetU(w,i), SLICEI(b))); }
|
if (mr==wr) { SGetU(w); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), GetU(w,i), SLICEI(b))); }
|
||||||
else { SGetU(x); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), SLICEI(b), GetU(x,i))); }
|
else { SGetU(x); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), SLICEI(b), GetU(x,i))); }
|
||||||
@ -569,7 +569,7 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr
|
|||||||
|
|
||||||
base:;
|
base:;
|
||||||
|
|
||||||
M_APD_SH(r, k, xsh);
|
M_APD_SH_N(r, k, xsh, cam);
|
||||||
S_KSLICES(x, xsh, k, cam, 1); FC1 fc1 = c1fn(f);
|
S_KSLICES(x, xsh, k, cam, 1); FC1 fc1 = c1fn(f);
|
||||||
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc1(f, SLICEI(x)));
|
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc1(f, SLICEI(x)));
|
||||||
decG(x);
|
decG(x);
|
||||||
@ -646,7 +646,7 @@ NOINLINE B for_cells_AS(B f, B w, B x, ur wcr, ur wr, u32 chr) {
|
|||||||
}
|
}
|
||||||
generic:;
|
generic:;
|
||||||
S_KSLICES(w, wsh, wk, cam, 1) incBy(x, cam-1);
|
S_KSLICES(w, wsh, wk, cam, 1) incBy(x, cam-1);
|
||||||
M_APD_SH(r, wk, wsh); FC2 fc2 = c2fn(f);
|
M_APD_SH_N(r, wk, wsh, cam); FC2 fc2 = c2fn(f);
|
||||||
for (usz i=0,wp=0; i<cam; i++) APDD(r, fc2(f, SLICEI(w), x));
|
for (usz i=0,wp=0; i<cam; i++) APDD(r, fc2(f, SLICEI(w), x));
|
||||||
decG(w); return taga(APD_SH_GET(r, chr));
|
decG(w); return taga(APD_SH_GET(r, chr));
|
||||||
}
|
}
|
||||||
@ -703,7 +703,7 @@ NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr) {
|
|||||||
return const_cells(x, xk, xsh, inc(f), chr);
|
return const_cells(x, xk, xsh, inc(f), chr);
|
||||||
}
|
}
|
||||||
S_KSLICES(x, xsh, xk, cam, 1) incBy(w, cam-1);
|
S_KSLICES(x, xsh, xk, cam, 1) incBy(w, cam-1);
|
||||||
M_APD_SH(r, xk, xsh); FC2 fc2 = c2fn(f);
|
M_APD_SH_N(r, xk, xsh, cam); FC2 fc2 = c2fn(f);
|
||||||
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc2(f, w, SLICEI(x)));
|
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc2(f, w, SLICEI(x)));
|
||||||
decG(x); return taga(APD_SH_GET(r, chr));
|
decG(x); return taga(APD_SH_GET(r, chr));
|
||||||
}
|
}
|
||||||
@ -757,7 +757,7 @@ NOINLINE B for_cells_AA(B f, B w, B x, ur wcr, ur xcr, u32 chr) {
|
|||||||
}
|
}
|
||||||
generic:;
|
generic:;
|
||||||
|
|
||||||
M_APD_SH(r, zk, zsh);
|
M_APD_SH_N(r, zk, zsh, cam);
|
||||||
S_KSLICES(w, wsh, wk, xkM? cam0 : cam, 1) usz wp=0;
|
S_KSLICES(w, wsh, wk, xkM? cam0 : cam, 1) usz wp=0;
|
||||||
S_KSLICES(x, xsh, xk, xkM? cam : cam0, 1) usz xp=0;
|
S_KSLICES(x, xsh, xk, xkM? cam : cam0, 1) usz xp=0;
|
||||||
FC2 fc2 = c2fn(f);
|
FC2 fc2 = c2fn(f);
|
||||||
|
|||||||
@ -460,7 +460,7 @@ B bqn_merge(B x, u32 type) {
|
|||||||
return taga(r);
|
return taga(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
M_APD_SH(r, xr, SH(x));
|
M_APD_SH_N(r, xr, SH(x), xia);
|
||||||
SGetU(x)
|
SGetU(x)
|
||||||
for (usz i = 0; i < xia; i++) APD(r, GetU(x, i));
|
for (usz i = 0; i < xia; i++) APD(r, GetU(x, i));
|
||||||
decG(x);
|
decG(x);
|
||||||
|
|||||||
@ -665,6 +665,37 @@ NOINLINE void apd_sh_init(ApdMut* m, B x) {
|
|||||||
else m->apd(m, x);
|
else m->apd(m, x);
|
||||||
if (xe==el_B) NOGC_E;
|
if (xe==el_B) NOGC_E;
|
||||||
}
|
}
|
||||||
|
// used if this is the only append: only need to add leading 1s to shape
|
||||||
|
NOINLINE void apd_reshape(ApdMut* m, B x) {
|
||||||
|
ur rr0 = m->rr0; // need to be read before union fields are written
|
||||||
|
for (ur i=0; i<rr0; i++) assert(m->rsh0[i] == 1);
|
||||||
|
|
||||||
|
inc(x);
|
||||||
|
if (isAtm(x)) x = m_unit(x);
|
||||||
|
|
||||||
|
if (rr0 > 0) {
|
||||||
|
ur xr = RNK(x);
|
||||||
|
if (rr0 + xr > UR_MAX) {
|
||||||
|
m->failEl = x;
|
||||||
|
m->end = apd_rnk_err;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ur rr = rr0 + xr;
|
||||||
|
Arr* r = cpyWithShape(x);
|
||||||
|
if (rr <= 1) {
|
||||||
|
arr_shErase(r, rr);
|
||||||
|
} else {
|
||||||
|
usz* xsh = PSH(r);
|
||||||
|
ShArr* rsh = m_shArr(rr);
|
||||||
|
PLAINLOOP for (ur i=0; i<rr0; i++) rsh->a[i] = 1;
|
||||||
|
shcpy(rsh->a + rr0, xsh, xr);
|
||||||
|
arr_shReplace(r, rr, rsh);
|
||||||
|
}
|
||||||
|
x = taga(r);
|
||||||
|
}
|
||||||
|
m->obj = a(x);
|
||||||
|
m->end = apd_ret_end;
|
||||||
|
}
|
||||||
|
|
||||||
NOINLINE void apd_widen(ApdMut* m, B x, ApdFn* const* fns) {
|
NOINLINE void apd_widen(ApdMut* m, B x, ApdFn* const* fns) {
|
||||||
u8 xe = isArr(x)? TI(x,elType) : selfElType(x);
|
u8 xe = isArr(x)? TI(x,elType) : selfElType(x);
|
||||||
|
|||||||
@ -265,7 +265,7 @@ struct ApdMut {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
ApdFn apd_tot_init, apd_sh_init;
|
ApdFn apd_tot_init, apd_sh_init, apd_reshape;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ApdFn apd_dbg_apd;
|
ApdFn apd_dbg_apd;
|
||||||
ApdEnd apd_dbg_end;
|
ApdEnd apd_dbg_end;
|
||||||
@ -275,6 +275,7 @@ ApdFn apd_tot_init, apd_sh_init;
|
|||||||
#endif
|
#endif
|
||||||
#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // end gives uninitialized shape
|
#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // end gives uninitialized shape
|
||||||
#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // end gives full shape; will error on invalid at the end; rsh must be alive until at least the first APD call
|
#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // end gives full shape; will error on invalid at the end; rsh must be alive until at least the first APD call
|
||||||
|
#define M_APD_SH_N(M, RR, RSH, N) M_APD_BASE(M) M.apd = N==1? apd_reshape : apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // same, with known number of appends
|
||||||
#define M_APD_SH1(M, RIA) usz M##_sh0 = (RIA); M_APD_SH(M, 1, &M##_sh0);
|
#define M_APD_SH1(M, RIA) usz M##_sh0 = (RIA); M_APD_SH(M, 1, &M##_sh0);
|
||||||
#define APD(M, A) M.apd(&M, A) // doesn't consume A
|
#define APD(M, A) M.apd(&M, A) // doesn't consume A
|
||||||
#define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A
|
#define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user