inline scope variable setting

This commit is contained in:
dzaima 2021-06-19 21:03:33 +03:00
parent 4eb2ef8c5c
commit 8ad686ab1b
7 changed files with 68 additions and 60 deletions

4
build
View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
# gcc -std=gnu11 -O3 -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
# gcc -std=gnu11 -O3 -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm

4
buildg
View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
clang -std=gnu11 -O3 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -Wno-unused-function -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
# gcc -std=gnu11 -O3 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
clang -std=gnu11 -O3 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -no-pie -Wno-unused-function -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
# gcc -std=gnu11 -O3 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
# gcc -DDEBUG -std=gnu11 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
# gcc -DDEBUG -std=gnu11 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm

37
src/h.h
View File

@ -101,8 +101,9 @@
#define CHR_MAX 1114111
#define U16_MAX ((u16)~(u16)0)
#define U32_MAX ((u32)~(u32)0)
#define NOINLINE __attribute__ ((noinline))
#define NORETURN __attribute__ ((noreturn))
#define NOINLINE __attribute__((noinline))
#define FORCE_INLINE __attribute__((always_inline)) static inline
#define NORETURN __attribute__((noreturn))
#define AUTO __auto_type
#define LIKELY(X) __builtin_expect(X,1)
#define RARE(X) __builtin_expect(X,0)
@ -125,22 +126,22 @@ CTR_FOR(F)
#define fsizeof(T,F,E,N) (offsetof(T, F) + sizeof(E)*(N)) // type, flexible array member name, flexible array member type, item amount
#define ftag(x) ((u64)(x) << 48)
#define tag(v, t) b(((u64)(v)) | ftag(t))
// .111111111110000000000000000000000000000000000000000000000000000 infinity
// .111111111111000000000000000000000000000000000000000000000000000 qNaN
// .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0
// 0111111111110................................................... direct value with no need of refcounting
static const u16 C32_TAG = 0b0111111111110001; // 0111111111110001................00000000000ccccccccccccccccccccc char
static const u16 TAG_TAG = 0b0111111111110010; // 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?; 5=no fill)
static const u16 VAR_TAG = 0b0111111111110011; // 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference
static const u16 EXT_TAG = 0b0111111111110100; // 0111111111110100ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn extended variable reference
static const u16 I32_TAG = 0b0111111111110111; // 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused
static const u16 MD1_TAG = 0b1111111111110010; // 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier
static const u16 MD2_TAG = 0b1111111111110011; // 1111111111110011ppppppppppppppppppppppppppppppppppppppppppppp000 2-modifier
static const u16 FUN_TAG = 0b1111111111110100; // 1111111111110100ppppppppppppppppppppppppppppppppppppppppppppp000 function
static const u16 NSP_TAG = 0b1111111111110101; // 1111111111110101ppppppppppppppppppppppppppppppppppppppppppppp000 namespace maybe?
static const u16 OBJ_TAG = 0b1111111111110110; // 1111111111110110ppppppppppppppppppppppppppppppppppppppppppppp000 custom object (e.g. bigints)
static const u16 ARR_TAG = 0b1111111111110111; // 1111111111110111ppppppppppppppppppppppppppppppppppppppppppppp000 array (everything else is an atom)
static const u16 VAL_TAG = 0b1111111111110 ; // 1111111111110................................................... pointer to Value, needs refcounting
// .FF0 .111111111110000000000000000000000000000000000000000000000000000 infinity
// .FF8 .111111111111000000000000000000000000000000000000000000000000000 qNaN
// .FF. .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0
// 7FF. 0111111111110................................................... direct value with no need of refcounting
static const u16 C32_TAG = 0b0111111111110001; // 7FF1 0111111111110001................00000000000ccccccccccccccccccccc char
static const u16 TAG_TAG = 0b0111111111110010; // 7FF2 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?; 5=no fill)
static const u16 VAR_TAG = 0b0111111111110011; // 7FF3 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference
static const u16 EXT_TAG = 0b0111111111110100; // 7FF4 0111111111110100ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn extended variable reference
static const u16 I32_TAG = 0b0111111111110111; // 7FF7 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused
static const u16 MD1_TAG = 0b1111111111110010; // FFF2 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier
static const u16 MD2_TAG = 0b1111111111110011; // FFF3 1111111111110011ppppppppppppppppppppppppppppppppppppppppppppp000 2-modifier
static const u16 FUN_TAG = 0b1111111111110100; // FFF4 1111111111110100ppppppppppppppppppppppppppppppppppppppppppppp000 function
static const u16 NSP_TAG = 0b1111111111110101; // FFF5 1111111111110101ppppppppppppppppppppppppppppppppppppppppppppp000 namespace maybe?
static const u16 OBJ_TAG = 0b1111111111110110; // FFF6 1111111111110110ppppppppppppppppppppppppppppppppppppppppppppp000 custom object (e.g. bigints)
static const u16 ARR_TAG = 0b1111111111110111; // FFF7 1111111111110111ppppppppppppppppppppppppppppppppppppppppppppp000 array (everything else is an atom)
static const u16 VAL_TAG = 0b1111111111110 ; // FFF. 1111111111110................................................... pointer to Value, needs refcounting
void cbqn_init();

View File

@ -11,7 +11,7 @@ static void repl_init() {
cbqn_init();
replPath = m_str32(U"REPL"); gc_add(replPath);
Block* initBlock = bqn_comp(m_str32(U"\"(REPL initializer)\""), inc(replPath), m_f64(0));
gsc = m_scope(initBlock->body, NULL, 0); gc_add(tag(gsc,OBJ_TAG));
gsc = m_scope(initBlock->body, NULL, 0, 0, NULL); gc_add(tag(gsc,OBJ_TAG));
ptr_dec(initBlock);
init = true;
}

View File

@ -564,39 +564,22 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
#undef GS_UPD
}
Scope* m_scope(Body* body, Scope* psc, u16 varAm) { // doesn't consume
Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars) { // doesn't consume
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, varAm), t_scope);
sc->body = body; ptr_inc(body);
sc->psc = psc; if(psc) ptr_inc(psc);
sc->varAm = varAm;
sc->ext = NULL;
i32 i = 0;
while (i<initVarAm) { sc->vars[i] = initVars[i]; i++; }
while (i<varAm) sc->vars[i++] = bi_noVar;
return sc;
}
B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
Body* body = bl->body;
u16 varAm = body->varAm;
assert(varAm>=ga);
Scope* sc = m_scope(body, psc, varAm);
i32 i = 0;
while (i<ga) { sc->vars[i] = svar[i]; i++; }
while (i<varAm) sc->vars[i++] = bi_noVar;
bool jit = USE_JIT;
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT just for blocks starting with `123456⋄`
B r;
if (jit) {
if (!body->nvm) {
Nvm_res r = m_nvm(body);
body->nvm = r.p;
body->nvmRefs = r.refs;
}
r = evalJIT(body, sc, body->nvm);
} else {
r = evalBC(body, sc);
}
static void scope_dec(Scope* sc) {
i32 varAm = sc->varAm;
if (sc->refc>1) {
usz innerRef = 1;
for (i = 0; i < varAm; i++) {
for (i32 i = 0; i < varAm; i++) {
B c = sc->vars[i];
if (isVal(c) && v(c)->refc==1) {
u8 t = v(c)->type;
@ -608,21 +591,45 @@ B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
assert(innerRef<=sc->refc);
if (innerRef==sc->refc) {
value_free((Value*)sc);
return r;
return;
}
}
ptr_dec(sc);
}
B execBodyInline(Body* body, Scope* sc) {
bool jit = USE_JIT;
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT just for blocks starting with `123456⋄`
if (jit) {
if (!body->nvm) {
Nvm_res r = m_nvm(body);
body->nvm = r.p;
body->nvmRefs = r.refs;
}
return evalJIT(body, sc, body->nvm);
} else {
return evalBC(body, sc);
}
}
FORCE_INLINE B execBlock(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
Body* body = bl->body;
u16 varAm = body->varAm;
assert(varAm>=ga);
Scope* sc = m_scope(body, psc, varAm, ga, svar);
B r = execBodyInline(body, sc);
scope_dec(sc);
return r;
}
B funBl_c1(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return actualExec(b->bl, b->sc, 3, (B[]){t, x, bi_N }); }
B funBl_c2(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return actualExec(b->bl, b->sc, 3, (B[]){t, x, w }); }
B md1Bl_c1(B D, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return actualExec(b->bl, b->sc, 5, (B[]){D, x, bi_N, inc(d->m1), inc(d->f) }); }
B md1Bl_c2(B D, B w, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return actualExec(b->bl, b->sc, 5, (B[]){D, x, w , inc(d->m1), inc(d->f) }); }
B md2Bl_c1(B D, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return actualExec(b->bl, b->sc, 6, (B[]){D, x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
B md2Bl_c2(B D, B w, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return actualExec(b->bl, b->sc, 6, (B[]){D, x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
B funBl_c1(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->sc, 3, (B[]){t, x, bi_N }); }
B funBl_c2(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->sc, 3, (B[]){t, x, w }); }
B md1Bl_c1(B D, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->sc, 5, (B[]){D, x, bi_N, inc(d->m1), inc(d->f) }); }
B md1Bl_c2(B D, B w, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->sc, 5, (B[]){D, x, w , inc(d->m1), inc(d->f) }); }
B md2Bl_c1(B D, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->sc, 6, (B[]){D, x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
B md2Bl_c2(B D, B w, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->sc, 6, (B[]){D, x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
B m_funBlock(Block* bl, Scope* psc) { // doesn't consume anything
if (bl->imm) return actualExec(bl, psc, 0, NULL);
if (bl->imm) return execBlock(bl, psc, 0, NULL);
B r = mm_alloc(sizeof(FunBlock), t_fun_block, ftag(FUN_TAG));
c(FunBlock, r)->bl = bl; ptr_inc(bl);
c(FunBlock, r)->sc = psc; ptr_inc(psc);
@ -720,8 +727,8 @@ void md2Bl_print(B x) { printf("{2-modifier block}"); }
B block_decompose(B x) { return m_v2(m_i32(1), x); }
B bl_m1d(B m, B f ) { Md1Block* c = c(Md1Block,m); return c->bl->imm? actualExec(c(Md1Block, m)->bl, c(Md1Block, m)->sc, 2, (B[]){m, f }) : m_md1D(m,f ); }
B bl_m2d(B m, B f, B g) { Md2Block* c = c(Md2Block,m); return c->bl->imm? actualExec(c(Md2Block, m)->bl, c(Md2Block, m)->sc, 3, (B[]){m, f, g}) : m_md2D(m,f,g); }
B bl_m1d(B m, B f ) { Md1Block* c = c(Md1Block,m); return c->bl->imm? execBlock(c(Md1Block, m)->bl, c(Md1Block, m)->sc, 2, (B[]){m, f }) : m_md1D(m,f ); }
B bl_m2d(B m, B f, B g) { Md2Block* c = c(Md2Block,m); return c->bl->imm? execBlock(c(Md2Block, m)->bl, c(Md2Block, m)->sc, 3, (B[]){m, f, g}) : m_md2D(m,f,g); }
void allocStack(void** curr, void** start, void** end, i32 elSize, i32 count) {
usz pageSize = sysconf(_SC_PAGESIZE);

View File

@ -104,7 +104,7 @@ struct Scope {
Block* bqn_comp(B str, B path, B args);
Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl);
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc);
Scope* m_scope(Body* body, Scope* psc, u16 varAm);
Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars);
B evalBC(Body* b, Scope* sc); // doesn't consume; executes bytecode of the body directly in the scope
u32* nextBC(u32* p);