From 7cc37e27237f4eecf0f47f39cf579e1989bd7f81 Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 20 Sep 2021 13:13:03 +0300 Subject: [PATCH] special-case JIT ARRO for 1 and 2 items --- src/builtins/sfns.c | 55 ++++++++++++++++++++++++++------------------ src/core/stuff.h | 2 ++ src/jit/nvm_x86_64.c | 18 ++++++++++----- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index d6cb3373..fd020aa6 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -18,33 +18,51 @@ static Arr* take_impl(usz ria, B x) { // consumes x; returns vā†‘ā„Šš•© without } } -static B unitV1(B x) { - if (isF64(x)) { - i32 i = (i32)x.f; - if (RARE(x.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = x.f; return r; } - if (x.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; } +B m_vec1(B a) { + if (isF64(a)) { + i32 i = (i32)a.f; + if (RARE(a.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = a.f; return r; } + if (a.f == (i8 )i) { i8* rp; B r = m_i8arrv (&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; } } - if (isC32(x)) { - u32 c = o2cu(x); + if (isC32(a)) { + u32 c = o2cu(a); if (LIKELY(cia; if (ia==1 && TI(x,elType)ia; Arr* r = TI(x,slice)(incG(x),0, ia); @@ -645,16 +663,7 @@ B couple_c1(B t, B x) { return taga(r); } B couple_c2(B t, B w, B x) { - if (isAtm(w)&isAtm(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)&isAtm(x)) return m_vec2(w, x); if (isAtm(w)) w = m_atomUnit(w); if (isAtm(x)) x = m_atomUnit(x); if (!eqShape(w, x)) thrF("ā‰: š•Ø and š•© must have equal shapes (%H ≔ ā‰¢š•Ø, %H ≔ ā‰¢š•©)", w, x); diff --git a/src/core/stuff.h b/src/core/stuff.h index 05d53d47..334fdfcd 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -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_v3(B a, B b, B c ); // 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 diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index 3ef76e47..af255356 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -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 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); HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated bool allNum = isNum(el0); r.a[sz-1] = el0; for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false; GS_UPD; - if (allNum) return withFill(r.b, m_f64(0)); + if (allNum) return num_squeeze(r.b); return r.b; } 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 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); } } + // 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 switch (*bc++) { 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 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 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 ARRM: case ARRO:; + 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 ARRM: case ARRO:; bool o = *(bc-1) == ARRO; u32 sz = *bc++; - if (sz) { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B, i64 sz, S) - else { TOPs; CCALL(i_ARR_0); } // unused with optimizations + if (sz==0 ) { 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; case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl) Block* bl = (Block*)L64;