mild optimization of v_set argument consumption

This commit is contained in:
dzaima 2022-09-08 20:05:13 +03:00
parent 3ccef1fe86
commit 1619b6087b
3 changed files with 31 additions and 23 deletions

View File

@ -160,18 +160,18 @@ INS B i_EXTU(u32 p, Scope* sc) {
vars[p] = bi_optOut;
return r;
}
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false, true); dec(s); return x; }
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true, true); dec(s); return x; }
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false, true, true, false); return x; }
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true, true, true, false); return x; }
INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
B w = v_get(pscs, s, true);
B r = c2(f,w,x); dec(f);
v_set(pscs, s, r, true, false); dec(s);
v_set(pscs, s, r, true, false, true, false);
return r;
}
INS B i_SETC(B s, B f, Scope** pscs, u32* bc) { POS_UPD;
B x = v_get(pscs, s, true);
B r = c1(f,x); dec(f);
v_set(pscs, s, r, true, false); dec(s);
v_set(pscs, s, r, true, false, true, false);
return r;
}
FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {

View File

@ -498,15 +498,18 @@ FORCE_INLINE bool v_merge(Scope* pscs[], B s, B x, bool upd, bool hdr) {
SGet(x)
for (usz i = 0; i < oia; i++) {
B cx = m_unit(Get(x,i));
if (!hdr) v_set (pscs, op[i], cx, upd, true);
else if (!v_seth(pscs, op[i], cx)) { dec(cx); return false; }
dec(cx);
if (!hdr) v_set(pscs, op[i], cx, upd, true, false, true);
else {
bool ok = v_seth(pscs, op[i], cx);
dec(cx);
if (!ok) return false;
}
}
} else {
B cells = toCells(incG(x));
B* xp = harr_ptr(cells);
for (usz i = 0; i < oia; i++) {
if (!hdr) v_set (pscs, op[i], xp[i], upd, true);
if (!hdr) v_set (pscs, op[i], xp[i], upd, true, false, false);
else if (!v_seth(pscs, op[i], xp[i])) { dec(cells); return false; }
}
dec(cells);
@ -524,25 +527,25 @@ NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
B c = sp[i];
if (isVar(c)) {
Scope* sc = pscs[(u16)(c.u>>32)];
v_set(pscs, c, ns_getU(x, pos2gid(sc->body, (u32)c.u)), upd, true);
v_set(pscs, c, ns_getU(x, pos2gid(sc->body, (u32)c.u)), upd, true, false, false);
} else if (isExt(c)) {
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd, true);
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd, true, false, false);
} else if (isObj(c)) {
assert(TY(c) == t_fldAlias);
FldAlias* cf = c(FldAlias,c);
v_set(pscs, cf->obj, ns_getU(x, cf->p), upd, true);
v_set(pscs, cf->obj, ns_getU(x, cf->p), upd, true, false, false);
} else thrM("Assignment: extracting non-name from namespace");
}
return;
}
SGetU(x)
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd, true);
SGet(x)
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], Get(x,i), upd, true, false, true);
} else if (s.u == bi_N.u) {
return;
} else if (isObj(s)) {
if (TY(s) == t_arrMerge) v_merge(pscs, s, x, upd, false);
else if (TY(s) == t_fldAlias) thrF("Assignment: Cannot assign non-namespace to a list containing aliases"); // v_set(pscs, c(FldAlias, s)->obj, x, upd, true);
else if (TY(s) == t_fldAlias) thrF("Assignment: Cannot assign non-namespace to a list containing aliases");
else UD;
} else if (isExt(s)) {
Scope* sc = pscs[(u16)(s.u>>32)];
@ -581,7 +584,7 @@ NOINLINE bool v_sethF(Scope* pscs[], B s, B x) {
}
if (TY(s)==t_vfyObj) return equal(c(WrappedObj,s)->obj,x);
if (TY(s)==t_arrMerge) return v_merge(pscs, s, x, false, true);
if (TY(s)==t_fldAlias) return false; // return v_seth(pscs, c(FldAlias, s)->obj, x);
if (TY(s)==t_fldAlias) return false;
UD;
}
@ -827,19 +830,19 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
break;
}
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true); dec(s); ADD(x); break; }
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true, true); dec(s); ADD(x); break; }
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true, true, false); ADD(x); break; }
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true, true, true, false); ADD(x); break; }
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
B w = v_get(pscs, s, true);
B r = c2(f,w,x); dec(f);
v_set(pscs, s, r, true, false); dec(s);
v_set(pscs, s, r, true, false, true, false);
ADD(r);
break;
}
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
B x = v_get(pscs, s, true);
B r = c1(f,x); dec(f);
v_set(pscs, s, r, true, false); dec(s);
v_set(pscs, s, r, true, false, true, false);
ADD(r);
break;
}

View File

@ -66,7 +66,7 @@ enum {
FN1Ci, FN1Oi, FN2Ci, FN2Oi, // FN__ alternatives that don't take the function from the stack, but instead as an 2×u32 immediate in the bytecode
SETNi, SETUi, SETMi, SETCi, // SET_ alternatives that expect the set variable as a depth-position pair like VAR_
SETNv, SETUv, SETMv, SETCv, // SET_i alternatives that also don't return the result
SETH1, SETH2, PRED1, PRED2, // internal versions of SETH and PRED, with 2×u64 arguments (only 1 for PRED1) specifying bodies to jump to on fail (or NULL if is last)
SETH1, SETH2, PRED1, PRED2, // versions of SETH and PRED with 2×u64 arguments (only 1 for PRED1) specifying bodies to jump to on fail (or NULL if is last)
DFND0, DFND1, DFND2, // internal versions of DFND with a specific type, and a u64 argument representing the block pointer
FAIL, // this body cannot be called monadically/dyadically
BC_SIZE
@ -299,9 +299,14 @@ FORCE_INLINE void v_setI(Scope* sc, u32 p, B x, bool upd, bool chk) { // consume
sc->vars[p] = x;
}
}
FORCE_INLINE void v_set(Scope* pscs[], B s, B x, bool upd, bool chk) { // doesn't consume; if chk is false, content variables _may_ not be checked to be set
if (RARE(!isVar(s))) v_setF(pscs, s, x, upd);
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd, chk);
FORCE_INLINE void v_set(Scope* pscs[], B s, B x, bool upd, bool chk, bool consumeS, bool consumeX) { // if chk is false, content variables _may_ not be checked to be set
if (LIKELY(isVar(s))) {
v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, consumeX? x : inc(x), upd, chk);
} else {
v_setF(pscs, s, x, upd);
if (consumeX) dec(x);
if (consumeS) dec(s);
}
}
FORCE_INLINE bool v_seth(Scope* pscs[], B s, B x) { // doesn't consume; s cannot contain extended variables