| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | const 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 = f->memoize; | |
| 24 | 1 | return m; | |
| 25 | } | ||
| 26 | |||
| 27 | 1 | void memoize_end(MemPool p, const Memoize m) { | |
| 28 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
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 | 35 | ANN static inline m_bit *get_data(MemPool mp, const Memoize m) { | |
| 35 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 3 times.
|
35 | if (vector_size(&m->v) >= m->limit) |
| 36 | 32 | 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 | 35 | INSTR(MemoizeStore) { | |
| 43 | 35 | const Memoize m = shred->code->memoize; | |
| 44 | 35 | m_bit *const data = get_data(shred->info->mp, m); | |
| 45 | 35 | memcpy(data, shred->mem, m->arg_sz); | |
| 46 | 35 | memcpy(data + m->arg_sz, shred->reg - m->ret_sz, m->ret_sz); | |
| 47 | 35 | } | |
| 48 | |||
| 49 | 99 | INSTR(MemoizeIni) { | |
| 50 | 99 | const m_uint idx = *(m_uint *)MEM(instr->m_val); | |
| 51 | 99 | const Memoize m = shred->code->memoize; | |
| 52 |
2/2✓ Branch 0 taken 79 times.
✓ Branch 1 taken 20 times.
|
99 | if (idx < VLEN(&m->v)) { |
| 53 | 79 | const m_bit *data = (m_bit *)vector_at(&m->v, idx); | |
| 54 | 79 | memcpy(MEM(instr->m_val + SZ_INT * 2), data, instr->m_val2); | |
| 55 | } else | ||
| 56 | 20 | shred->pc = *(m_uint *)MEM(instr->m_val + SZ_INT); | |
| 57 | 99 | } | |
| 58 |