opt_src := $(wildcard opt/*.c)
# add boolean
-ifeq (${USE_GWCOV}, 1)
-CFLAGS += -DGWCOV
-endif
-
ifeq (${DEBUG_STACK}, 1)
CFLAGS += -DDEBUG_STACK
endif
+
ifeq (${USE_OPTIMIZE}, 1)
util_src += ${opt_src}
CFLAGS+= -DOPTIMIZE
endif
-ifeq (${USE_JIT}, 1)
-include jit/config.mk
-endif
-
-ifeq (${USE_NOMEMOIZE}, 1)
-CFLAGS += -DNOMEMOIZE
-endif
-
-ifeq (${USE_VMBENCH}, 1)
-CFLAGS += -DVMBENCH
-LDFLAGS += -lbsd
-endif
ifeq (${BUILD_ON_WINDOWS}, 1)
CFLAGS += -DBUILD_ON_WINDOWS -D_XOPEN_SOURCE=700
GW_OBJ=${src_obj} ${ast_obj} ${parse_obj} ${emit_obj} ${oo_obj} ${vm_obj} ${util_obj} ${lib_obj}
+CFLAGS += -Iinclude
+LDFLAGS += -lm
+
ifeq ($(shell uname), Linux)
LDFLAGS += -lrt -rdynamic
endif
-Subproject commit 5d45e48e6b8c5961f6aeb2d8ce437434e9dd5fe1
+Subproject commit 5a1fda275fe41169cfe9edae73a7fd95811d24b8
# handle base options
PRG ?=gwion
PREFIX ?=/usr/local
-LDFLAGS += -lm
-CFLAGS += -Iinclude -Iutil/include -Iast/include -D_GNU_SOURCE
+CFLAGS += -Iutil/include -Iast/include -D_GNU_SOURCE
# handle boolean options
USE_OPTIMIZE ?= 0
-USE_VMBENCH ?= 0
USE_NOMEMOIZE ?= 0
# base plugin directories
struct Vector_ config;
struct SoundInfo_ *si;
m_bool loop;
+ m_bool memoize;
} Arg;
ANN void arg_release(Arg*);
struct Gwion_ *gwion;
struct Vector_ stack;
char *escape;
+ m_bool memoize;
};
ANEW ANN Emitter new_emitter(void/*const Env*/);
#ifndef __MEMOIZE
#define __MEMOIZE
-#ifndef NOMEMOIZE
-#define MEMOIZE_CALL const Instr memoize = !GET_FLAG(f, pure) ? NULL : emit_add_instr(emit, MemoizeCall);
-#define MEMOIZE_SET(a) if(memoize)memoize->m_val = a + 1;
-#define MEMOIZE_STORE if(GET_FLAG(emit->env->func, pure)) emit_add_instr(emit, MemoizeStore);
-#define MEMOIZE_INI if(GET_FLAG(func, pure)) func->code->memoize = memoize_ini(emit->gwion->p, func, kindof(func->def->base->ret_type->size, !func->def->base->ret_type->size));
typedef struct Memoize_ * Memoize;
Memoize memoize_ini(MemPool, const Func, const enum Kind);
void memoize_end(MemPool, Memoize);
INSTR(MemoizeCall);
INSTR(MemoizeStore);
-#else
-#define MEMOIZE_CALL
-#define MEMOIZE_STORE
-#define MEMOIZE_INI
-#define MEMOIZE_SET(a)
-#endif
#endif
#define __OPTIM
#ifdef OPTIMIZE
#define OPTIMIZE_CONST(a) CHECK_BO(optimize_const(a))
-ANN m_bool optimize_const(const Exp_Binary*);
+ANN m_bool optimize_const(MemPool mp, const Exp_Binary*);
//ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr);
#else
#define OPTIMIZE_CONST(a)
#endif
-m_bool constant_folding(const Exp_Binary* bin);
+m_bool constant_folding(MemPool mp, const Exp_Binary* bin);
#endif
#include "optim.h"
#include "constant.h"
-ANN static void fold_exp(const Exp_Binary* bin) {
- const Exp n = bin->self->next;
- const Exp e = bin->self;
- free_exp(bin->lhs);
- free_exp(bin->rhs);
+ANN static void fold_exp(MemPool mp, const Exp_Binary* bin) {
+ const Exp n = exp_self(bin)->next;
+ const Exp e = exp_self(bin);
+ free_exp(mp, bin->lhs);
+ free_exp(mp, bin->rhs);
e->exp_type = ae_exp_primary;
- e->d.exp_primary.self = e;
e->next = n;
}
CASE(mul, l, /, r) \
case op_div: DIV_BY_ZERO(l, / , r) break;
-#define describe_fold_xxx(name, type, _l, _r, etype, opt) \
-ANN static m_bool fold_##name(const Exp_Binary* bin) { \
- const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \
- const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \
- type ret = 0; \
- switch(bin->op) { \
- COMMON_CASE(l->_l, r->_r) \
- opt \
- default: \
- return GW_OK; \
- } \
- const Exp e = bin->self; \
- fold_exp(bin); \
- etype##_exp(e, ret); \
- return GW_OK; \
+#define describe_fold_xxx(name, type, _l, _r, etype, opt) \
+ANN static m_bool fold_##name(MemPool mp, const Exp_Binary* bin) { \
+ const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \
+ const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \
+ type ret = 0; \
+ switch(bin->op) { \
+ COMMON_CASE(l->_l, r->_r) \
+ opt \
+ default: \
+ return GW_OK; \
+ } \
+ const Exp e = exp_self(bin); \
+ fold_exp(mp, bin); \
+ etype##_exp(e, ret); \
+ return GW_OK; \
}
describe_fold_xxx(ii, m_int, num, num, int,
case op_mod: DIV_BY_ZERO(l->num, % , r->num) break;
describe_fold_xxx(if, m_float, num, fnum, float,)
describe_fold_xxx(fi, m_float, fnum, num, float,)
-m_bool constant_folding(const Exp_Binary* bin) {
+m_bool constant_folding(MemPool mp, const Exp_Binary* bin) {
if(constant_int(bin->lhs)) {
if(constant_int(bin->rhs))
- CHECK_BB(fold_ii(bin))
+ CHECK_BB(fold_ii(mp, bin))
else if(constant_float(bin->rhs))
- CHECK_BB(fold_if(bin))
+ CHECK_BB(fold_if(mp, bin))
} else if(constant_float(bin->lhs)) {
if(constant_float(bin->rhs))
- CHECK_BB(fold_ff(bin))
+ CHECK_BB(fold_ff(mp, bin))
else if(constant_int(bin->rhs))
- CHECK_BB(fold_fi(bin))
+ CHECK_BB(fold_fi(mp, bin))
}
return GW_OK;
}
#include "optim.h"
#include "constant.h"
-m_bool optimize_const(const Exp_Binary* bin) {
- return constant_folding(bin);
+m_bool optimize_const(MemPool mp, const Exp_Binary* bin) {
+ return constant_folding(mp, bin);
}
static const char usage[] =
"usage: Gwion <options>\n"
-"\t-h\t : this help\n"
-"\t-k\t : show compilation flags\n"
-"\t-c\t <file> : load config\n"
-"\t-s\t <number> : set samplerate\n"
-"\t-i\t <number> : set input channel number\n"
-"\t-o\t <number> : set output channel number\n"
-"\t-d\t <number> : set driver (and arguments)\n"
-"\t-m\t <number> : load module (and arguments)\n"
-"\t-p\t <directory> : add a plugin directory\n";
+"\t-h\t : this help\n"
+"\t-k\t : show compilation flags\n"
+"\t-c\t <file> : load config\n"
+"\t-p\t <path> : add a plugin directory\n"
+"\t-s\t <number> : set samplerate\n"
+"\t-i\t <number> : set input channel number\n"
+"\t-o\t <number> : set output channel number\n"
+"\t-d\t <number> : set driver (and arguments)\n"
+"\t-z\t <number> : set memoization limit\n"
+"\t-m\t <mod:args> : load module (and arguments)\n";
ANN static void config_parse(Arg* arg, const m_str name);
CASE('p', vector_add(&arg->lib, (vtype)get_arg(arg->argv)))
CASE('m', vector_add(&arg->mod, (vtype)get_arg(arg->argv)))
CASE('l', arg->loop = (m_bool)ARG2INT(arg->argv) > 0 ? 1 : -1)
+ CASE('z', arg->memoize = (uint32_t)ARG2INT(arg->argv))
CASE('i', arg->si->in = (uint8_t)ARG2INT(arg->argv))
CASE('o', arg->si->out = (uint8_t)ARG2INT(arg->argv))
CASE('s', arg->si->sr = (uint32_t)ARG2INT(arg->argv))
}
ANN static Instr emit_call(const Emitter emit, const Func f) {
- MEMOIZE_CALL
+ const Instr memoize = !(emit->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall);
f_instr exec;
const Instr prelude = get_prelude(emit, f);
if(f->def->stack_depth) {
exec = Overflow;
} else
exec = Next;
- MEMOIZE_SET(prelude->m_val2);
+ if(memoize)
+ memoize->m_val = prelude->m_val2 + 1;
return emit_add_instr(emit, exec);
}
}
vector_clear(&emit->code->stack_return);
emit_pop_scope(emit);
- MEMOIZE_STORE
+ if(emit->memoize && GET_FLAG(emit->env->func, pure))
+ emit_add_instr(emit, MemoizeStore);
emit_add_instr(emit, FuncReturn);
}
emit_pop_code(emit);
if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl)
emit_func_def_global(emit, func->value_ref);
- MEMOIZE_INI
+ if(emit->memoize && GET_FLAG(func, pure))
+ func->code->memoize = memoize_ini(emit->gwion->p, func,
+ kindof(func->def->base->ret_type->size, !func->def->base->ret_type->size));
return GW_OK;
}
-#ifndef NOMEMOIZE
#include <string.h>
#include "gwion_util.h"
#include "gwion_ast.h"
mreturn[m->kind](data + m->arg_sz, shred->reg-m->ret_sz, m->ret_sz);
return;
}
-}
-#endif
+}
\ No newline at end of file
#include "gwion.h"
#include "compile.h"
-#ifdef VMBENCH
-#include <time.h>
-#include <bsd/sys/time.h>
-#define VMBENCH_INI struct timespec ini, end, ret; \
- clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ini);
-#define VMBENCH_END clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); \
- timespecsub(&end, &ini, &ret); \
- printf("timespec %lu.%09lu\n", ret.tv_sec, ret.tv_nsec);
-#else
-#define VMBENCH_INI
-#define VMBENCH_END
-#endif
-
ANN m_bool gwion_audio(const Gwion gwion) {
Driver* di = gwion->vm->bbq;
if(di->si->arg) {
gwion->vm->bbq->si = new_soundinfo(gwion->p);
arg->si = gwion->vm->bbq->si;
arg_parse(arg);
+ gwion->emit->memoize = arg->memoize;
gwion->plug = new_plug(gwion->p, &arg->lib);
map_init(&gwion->freearg);
shreduler_set_loop(gwion->vm->shreduler, arg->loop);
ANN void gwion_run(const Gwion gwion) {
VM* vm = gwion->vm;
- VMBENCH_INI
vm->bbq->driver->run(vm, vm->bbq);
- VMBENCH_END
}
ANN void gwion_end(const Gwion gwion) {
#define VM_INFO
#endif
-#ifdef VMBENCH
-#include <time.h>
-static struct timespec exec_time;
-#include <bsd/sys/time.h>
-#endif
-
-
ANN static inline m_bool overflow_(const m_bit* mem, const VM_Shred c) {
return mem > (((m_bit*)c + sizeof(struct VM_Shred_) + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP));
}
VM_Shred child;
} a;
register M_Object array_base = NULL;
-#ifdef VMBENCH
-struct timespec exec_ini, exec_end, exec_ret;
-clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini);
-#endif
MUTEX_LOCK(s->mutex);
do {
register Instr instr; DISPATCH();
DISPATCH()
} while(s->curr);
MUTEX_UNLOCK(s->mutex);
-#ifdef VMBENCH
-clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_end);
-timespecsub(&exec_end, &exec_ini, &exec_ret);
-timespecadd(&exec_time, &exec_ret, &exec_time);
-#endif
}
- if(!vm->bbq->is_running) {
-#ifdef VMBENCH
- printf("[VM] exec time %lu.%09lu\n", exec_time.tv_sec, exec_time.tv_nsec);
- printf("[VM] exec time %09lu\n", exec_time.tv_nsec/1000);
-#endif
+ if(!vm->bbq->is_running)
return;
-}
-if(vector_size(&vm->ugen))
- vm_ugen_init(vm);
+ if(vector_size(&vm->ugen))
+ vm_ugen_init(vm);
}
\ No newline at end of file
}
ANN static void free_vm_code(VM_Code a, Gwion gwion) {
-#ifndef NOMEMOIZE
if(a->memoize)
memoize_end(gwion->p, a->memoize);
-#endif
if(!GET_FLAG(a, builtin))
free_code_instr(a->instr, gwion);
xfree(a->name);
-Subproject commit 00c8b5e8217c2eaa4f3157fbe76191221610b912
+Subproject commit 3c8b4049cf29b40e39f38f531a24d61b684a1042