1 |
|
|
#include "gwion_util.h" |
2 |
|
|
#include "gwion_ast.h" |
3 |
|
|
#include "gwion_env.h" |
4 |
|
|
#include "vm.h" |
5 |
|
|
#include "instr.h" |
6 |
|
|
#include "emit.h" |
7 |
|
|
#include "gwion.h" |
8 |
|
|
#include "memoize.h" |
9 |
|
|
|
10 |
|
|
struct Memoize_ { |
11 |
|
|
struct Vector_ v; |
12 |
|
|
m_uint arg_sz; |
13 |
|
|
m_uint ret_sz; |
14 |
|
|
size_t limit; |
15 |
|
|
size_t curr; |
16 |
|
|
}; |
17 |
|
|
|
18 |
|
1 |
Memoize memoize_ini(const Emitter emit, const Func f) { |
19 |
|
1 |
Memoize m = mp_calloc(emit->gwion->mp, Memoize); |
20 |
|
1 |
vector_init(&m->v); |
21 |
|
1 |
m->ret_sz = f->def->base->ret_type->size; |
22 |
|
1 |
m->arg_sz = f->def->stack_depth; |
23 |
|
1 |
m->limit = emit->info->memoize; |
24 |
|
1 |
return m; |
25 |
|
|
} |
26 |
|
|
|
27 |
|
1 |
void memoize_end(MemPool p, Memoize m) { |
28 |
✓✓ |
4 |
for(m_uint i = 0; i < vector_size(&m->v); ++i) |
29 |
|
3 |
mp_free2(p, m->arg_sz + m->arg_sz, (void*)vector_at(&m->v, i)); |
30 |
|
1 |
vector_release(&m->v); |
31 |
|
1 |
mp_free(p, Memoize, m); |
32 |
|
1 |
} |
33 |
|
|
|
34 |
|
13 |
ANN static inline m_bit* get_data(MemPool mp, Memoize m) { |
35 |
✓✓ |
13 |
if(vector_size(&m->v) >= m->limit) |
36 |
|
10 |
return (m_bit*)vector_at(&m->v, m->curr++ % m->limit); |
37 |
|
3 |
m_bit* data = mp_calloc2(mp, m->arg_sz + m->ret_sz); |
38 |
|
3 |
vector_add(&m->v, (vtype)data); |
39 |
|
3 |
return data; |
40 |
|
|
} |
41 |
|
|
|
42 |
|
13 |
INSTR(MemoizeStore) { |
43 |
|
13 |
const Memoize m = shred->code->memoize; |
44 |
|
13 |
m_bit* data = get_data(shred->info->vm->gwion->mp, m); |
45 |
|
13 |
memcpy(data, shred->mem, m->arg_sz); |
46 |
|
13 |
memcpy(data + m->arg_sz, shred->reg - m->ret_sz, m->ret_sz); |
47 |
|
13 |
} |
48 |
|
|
|
49 |
|
60 |
INSTR(MemoizeIni) { |
50 |
|
60 |
const m_uint idx = *(m_uint*)MEM(instr->m_val); |
51 |
|
60 |
const Memoize m = shred->code->memoize; |
52 |
✓✓ |
60 |
if(idx < VLEN(&m->v)) { |
53 |
|
47 |
const m_bit* data = (m_bit*)vector_at(&m->v, idx); |
54 |
|
47 |
memcpy(MEM(instr->m_val + SZ_INT *2), data, instr->m_val2); |
55 |
|
|
} else |
56 |
|
13 |
shred->pc = *(m_uint*)MEM(instr->m_val + SZ_INT); |
57 |
|
60 |
} |