special-case JIT ARRO for 1 and 2 items

This commit is contained in:
dzaima 2021-09-20 13:13:03 +03:00
parent 4246aa5694
commit 7cc37e2723
3 changed files with 46 additions and 29 deletions

View File

@ -18,33 +18,51 @@ static Arr* take_impl(usz ria, B x) { // consumes x; returns v↑⥊𝕩 without
} }
} }
static B unitV1(B x) { B m_vec1(B a) {
if (isF64(x)) { if (isF64(a)) {
i32 i = (i32)x.f; i32 i = (i32)a.f;
if (RARE(x.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = x.f; return r; } if (RARE(a.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = a.f; return r; }
if (x.f == (i8 )i) { i8* rp; B r = m_i8arrv (&rp, 1); rp[0] = i; return r; } if (a.f == (i8 )i) { i8* rp; B r = m_i8arrv (&rp, 1); rp[0] = i; return r; }
else if (x.f == (i16)i) { i16* rp; B r = m_i16arrv(&rp, 1); rp[0] = i; return r; } else if (a.f == (i16)i) { i16* rp; B r = m_i16arrv(&rp, 1); rp[0] = i; return r; }
else { i32* rp; B r = m_i32arrv(&rp, 1); rp[0] = i; return r; } else { i32* rp; B r = m_i32arrv(&rp, 1); rp[0] = i; return r; }
} }
if (isC32(x)) { if (isC32(a)) {
u32 c = o2cu(x); u32 c = o2cu(a);
if (LIKELY(c<U8_MAX )) { u8* rp; B r = m_c8arrv (&rp, 1); rp[0] = c; return r; } if (LIKELY(c<U8_MAX )) { u8* rp; B r = m_c8arrv (&rp, 1); rp[0] = c; return r; }
else if (LIKELY(c<U16_MAX)) { u16* rp; B r = m_c16arrv(&rp, 1); rp[0] = c; return r; } else if (LIKELY(c<U16_MAX)) { u16* rp; B r = m_c16arrv(&rp, 1); rp[0] = c; return r; }
else { u32* rp; B r = m_c32arrv(&rp, 1); rp[0] = c; return r; } else { u32* rp; B r = m_c32arrv(&rp, 1); rp[0] = c; return r; }
} }
Arr* ra = m_fillarrp(1); arr_shVec(ra); Arr* ra = m_fillarrp(1); arr_shVec(ra);
fillarr_setFill(ra, asFill(inc(x))); fillarr_setFill(ra, asFill(inc(a)));
fillarr_ptr(ra)[0] = x; fillarr_ptr(ra)[0] = a;
return taga(ra); return taga(ra);
} }
B m_vec2(B a, B b) {
if (isAtm(a)&isAtm(b)) {
if (LIKELY(isNum(a)&isNum(b))) {
i32 ai=a.f; i32 bi=b.f;
if (RARE(ai!=a.f | bi!=b.f)) { f64* rp; B r = m_f64arrv(&rp, 2); rp[0]=o2fu(a); rp[1]=o2fu(b); return r; }
else if (ai==(i8 )ai & bi==(i8 )bi) { i8* rp; B r = m_i8arrv (&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
else if (ai==(i16)ai & bi==(i16)bi) { i16* rp; B r = m_i16arrv(&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
else { i32* rp; B r = m_i32arrv(&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
}
if (isC32(b)&isC32(a)) {
u32 ac=o2cu(a); u32 bc=o2cu(b);
if (ac==(u8 )ac & bc==(u8 )bc) { u8* rp; B r = m_c8arrv (&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
else if (ac==(u16)ac & bc==(u16)bc) { u16* rp; B r = m_c16arrv(&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
else { u32* rp; B r = m_c32arrv(&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
}
}
return m_v2(a,b);
}
B shape_c1(B t, B x) { B shape_c1(B t, B x) {
if (isAtm(x)) return unitV1(x); if (isAtm(x)) return m_vec1(x);
usz ia = a(x)->ia; usz ia = a(x)->ia;
if (ia==1 && TI(x,elType)<el_B) { if (ia==1 && TI(x,elType)<el_B) {
B n = IGet(x,0); B n = IGet(x,0);
dec(x); dec(x);
return unitV1(n); return m_vec1(n);
} }
if (reusable(x)) { FL_KEEP(x, fl_squoze); if (reusable(x)) { FL_KEEP(x, fl_squoze);
decSh(v(x)); arr_shVec(a(x)); decSh(v(x)); arr_shVec(a(x));
@ -635,7 +653,7 @@ B join_c2(B t, B w, B x) {
B couple_c1(B t, B x) { B couple_c1(B t, B x) {
if (isAtm(x)) return unitV1(x); if (isAtm(x)) return m_vec1(x);
usz rr = rnk(x); usz rr = rnk(x);
usz ia = a(x)->ia; usz ia = a(x)->ia;
Arr* r = TI(x,slice)(incG(x),0, ia); Arr* r = TI(x,slice)(incG(x),0, ia);
@ -645,16 +663,7 @@ B couple_c1(B t, B x) {
return taga(r); return taga(r);
} }
B couple_c2(B t, B w, B x) { B couple_c2(B t, B w, B x) {
if (isAtm(w)&isAtm(x)) { if (isAtm(w)&isAtm(x)) return m_vec2(w, x);
if (LIKELY(isNum(w)&isNum(x))) {
i32 wi=w.f; i32 xi=x.f;
if (RARE(wi!=w.f | xi!=x.f)) { f64* rp; B r = m_f64arrv(&rp, 2); rp[0]=o2fu(w); rp[1]=o2fu(x); return r; }
else if (wi==(i8 )wi & xi==(i8 )xi) { i8* rp; B r = m_i8arrv (&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
else if (wi==(i16)wi & xi==(i16)xi) { i16* rp; B r = m_i16arrv(&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
else { i32* rp; B r = m_i32arrv(&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
}
if (isC32(x)&isC32(w)) { u32* rp; B r = m_c32arrv(&rp, 2); rp[0]=o2cu(w); rp[1]=o2cu(x); return r; }
}
if (isAtm(w)) w = m_atomUnit(w); if (isAtm(w)) w = m_atomUnit(w);
if (isAtm(x)) x = m_atomUnit(x); if (isAtm(x)) x = m_atomUnit(x);
if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);

View File

@ -91,6 +91,8 @@ static B m_v1(B a ); // consumes all
static B m_v2(B a, B b ); // consumes all static B m_v2(B a, B b ); // consumes all
static B m_v3(B a, B b, B c ); // consumes all static B m_v3(B a, B b, B c ); // consumes all
static B m_v4(B a, B b, B c, B d); // consumes all static B m_v4(B a, B b, B c, B d); // consumes all
B m_vec1(B a);
B m_vec2(B a, B b);
// random stuff // random stuff

View File

@ -78,13 +78,16 @@ INS B i_FN2Oi(B w, B x, BB2B fm, BBB2B fd, u32* bc) { POS_UPD;
INS B i_ARR_0() { // TODO combine with ADDI INS B i_ARR_0() { // TODO combine with ADDI
return emptyHVec(); return emptyHVec();
} }
INS B i_ARR_2(B e1, B e0) {
return m_vec2(e0,e1);
}
INS B i_ARR_p(B el0, i64 sz, B* cStack) { assert(sz>0); INS B i_ARR_p(B el0, i64 sz, B* cStack) { assert(sz>0);
HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated
bool allNum = isNum(el0); bool allNum = isNum(el0);
r.a[sz-1] = el0; r.a[sz-1] = el0;
for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false; for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false;
GS_UPD; GS_UPD;
if (allNum) return withFill(r.b, m_f64(0)); if (allNum) return num_squeeze(r.b);
return r.b; return r.b;
} }
INS B i_DFND_0(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_funBlock(bl, sc); } INS B i_DFND_0(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_funBlock(bl, sc); }
@ -536,6 +539,7 @@ Nvm_res m_nvm(Body* body) {
#define POS_UPD(R1,R2) MOV4moi(r_ENV, offsetof(Env,pos), body->bl->map[bcpos]<<1 | 1); #define POS_UPD(R1,R2) MOV4moi(r_ENV, offsetof(Env,pos), body->bl->map[bcpos]<<1 | 1);
#define GS_SET(R) MOV8pr(&gStack, R) #define GS_SET(R) MOV8pr(&gStack, R)
#define GET(R,P,U) { i32 p = SPOSq(-(P)); if (U && lGPos!=p) { Reg t=LEA0(R,r_CS,p,0); GS_SET(t); lGPos=p; if(U!=2) MOV8rm(R,t); } else { MOV8rmo(R, r_CS, p); } } #define GET(R,P,U) { i32 p = SPOSq(-(P)); if (U && lGPos!=p) { Reg t=LEA0(R,r_CS,p,0); GS_SET(t); lGPos=p; if(U!=2) MOV8rm(R,t); } else { MOV8rmo(R, r_CS, p); } }
// use GET(R_A1,0,2); as GS_UPD when there's only one argument, and GET(R_A3,-1,2); when there are zero arguments (i think?)
#define NORES(D) if (depth>D) MOV8rm(R_RES, SPOS(R_A3, -D, 0)); // call at end if rax is unset; arg is removed stack item count #define NORES(D) if (depth>D) MOV8rm(R_RES, SPOS(R_A3, -D, 0)); // call at end if rax is unset; arg is removed stack item count
switch (*bc++) { switch (*bc++) {
case POPS: TOPp; case POPS: TOPp;
@ -551,12 +555,14 @@ Nvm_res m_nvm(Body* body) {
case FN2O: TOPp; GET(R_A1,1,0); GET(R_A2,2,1); IMM(R_A3,off); CCALL(i_FN2O); break; // (B w, B f, B x, u32* bc) case FN2O: TOPp; GET(R_A1,1,0); GET(R_A2,2,1); IMM(R_A3,off); CCALL(i_FN2O); break; // (B w, B f, B x, u32* bc)
case FN1Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,0,2); CCALL(fn); } break; case FN1Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,0,2); CCALL(fn); } break;
case FN2Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,1,1); CCALL(fn); } break; case FN2Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,1,1); CCALL(fn); } break;
case FN1Oi:TOPp; GET(R_A1,0,2); IMM(R_A1,L64); IMM(R_A2,off); CCALL(i_FN1Oi); break; // ( B x, BB2B fm, u32* bc) case FN1Oi:TOPp; GET(R_A1,0,2); IMM(R_A1,L64); IMM(R_A2,off); CCALL(i_FN1Oi); break; // ( B x, BB2B fm, u32* bc)
case FN2Oi:TOPp; GET(R_A1,1,1); IMM(R_A2,L64); IMM(R_A3, L64); IMM(R_A4,off); CCALL(i_FN2Oi); break; // (B w, B x, BB2B fm, BBB2B fd, u32* bc) case FN2Oi:TOPp; GET(R_A1,1,1); IMM(R_A2,L64); IMM(R_A3, L64); IMM(R_A4,off); CCALL(i_FN2Oi); break; // (B w, B x, BB2B fm, BBB2B fd, u32* bc)
case ARRM: case ARRO:; case ARRM: case ARRO:; bool o = *(bc-1) == ARRO;
u32 sz = *bc++; u32 sz = *bc++;
if (sz) { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B, i64 sz, S) if (sz==0 ) { TOPs; CCALL(i_ARR_0); } // unused with optimizations
else { TOPs; CCALL(i_ARR_0); } // unused with optimizations else if (sz==1 && o) { TOPp; GET(R_A3,0,2); CCALL(m_vec1); } // (B a)
else if (sz==2 && o) { TOPp; GET(R_A1,1,1); CCALL(i_ARR_2); } // (B a, B b)
else { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B a, i64 sz, S)
break; break;
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl) case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
Block* bl = (Block*)L64; Block* bl = (Block*)L64;