From 2bd20c3cb3944cfd410be045be0fda656d972ec1 Mon Sep 17 00:00:00 2001 From: bakpakin Date: Thu, 25 Jan 2018 18:48:12 -0500 Subject: [PATCH] Addition and subtraction inlining. --- src/compiler/cfuns.c | 66 ++++++++++++++++++++++++++++++++++------ src/core/string.c | 10 +++--- src/include/dst/dststl.h | 3 ++ 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/compiler/cfuns.c b/src/compiler/cfuns.c index 66674a06..41f956c9 100644 --- a/src/compiler/cfuns.c +++ b/src/compiler/cfuns.c @@ -23,17 +23,17 @@ #include #include #include "compile.h" -#define DST_V_NODEF_GROW #include #undef DST_V_NODEF_GROW /* This logic needs to be expanded for more types */ -/* Check if a function recieved only numbers */ -static int numbers(DstFopts opts, DstSM *args) { +/* Check if a function received only numbers */ +static int numbers(DstFopts opts, DstAst *ast, DstSM *args) { int32_t i; int32_t len = dst_v_count(args); (void) opts; + (void) ast; for (i = 0; i < len; i++) { DstSlot s = args[i].slot; if (s.flags & DST_SLOT_CONSTANT) { @@ -48,12 +48,34 @@ static int numbers(DstFopts opts, DstSM *args) { return 1; } -static int can_add(DstFopts opts, DstAst *ast, DstSM *args) { - (void) ast; - return numbers(opts, args); +/* Fold constants in a DstSM */ +static DstSM *foldc(DstSM *sms, DstAst *ast, Dst (*fn)(Dst lhs, Dst rhs)) { + int32_t ccount; + int32_t i; + DstSM *ret = NULL; + DstSM sm; + Dst current; + for (ccount = 0; ccount < dst_v_count(sms); ccount++) { + if (sms[ccount].slot.flags & DST_SLOT_CONSTANT) continue; + break; + } + if (ccount < 2) return sms; + current = fn(sms[0].slot.constant, sms[1].slot.constant); + for (i = 2; i < ccount; i++) { + Dst nextarg = sms[i].slot.constant; + current = fn(current, nextarg); + } + sm.slot = dstc_cslot(current); + sm.map = ast; + dst_v_push(ret, sm); + for (; i < dst_v_count(sms); i++) { + dst_v_push(ret, sms[i]); + } + return ret; } -static DstSlot add(DstFopts opts, DstAst *ast, DstSM *args) { +/* Emit a series of instructions instead of a function call to a math op */ +static DstSlot opreduce(DstFopts opts, DstAst *ast, DstSM *args, int op) { DstCompiler *c = opts.compiler; int32_t i, len; int32_t op1, op2; @@ -68,20 +90,44 @@ static DstSlot add(DstFopts opts, DstAst *ast, DstSM *args) { /* Compile initial two arguments */ op1 = dstc_preread(c, args[0].map, 0xFF, 1, args[0].slot); op2 = dstc_preread(c, args[1].map, 0xFF, 2, args[1].slot); - dstc_emit(c, ast, (t.index << 8) | (op1 << 16) | (op2 << 24) | DOP_ADD); + dstc_emit(c, ast, (t.index << 8) | (op1 << 16) | (op2 << 24) | op); dstc_postread(c, args[0].slot, op1); dstc_postread(c, args[1].slot, op2); for (i = 2; i < len; i++) { op1 = dstc_preread(c, args[i].map, 0xFF, 1, args[i].slot); - dstc_emit(c, ast, (t.index << 8) | (t.index << 16) | (op1 << 24) | DOP_ADD); + dstc_emit(c, ast, (t.index << 8) | (t.index << 16) | (op1 << 24) | op); dstc_postread(c, args[i].slot, op1); } return t; } +static DstSlot add(DstFopts opts, DstAst *ast, DstSM *args) { + DstSM *newargs = foldc(args, ast, dst_op_add); + DstSlot ret = opreduce(opts, ast, newargs, DOP_ADD); + if (newargs != args) dstc_freeslots(opts.compiler, newargs); + return ret; +} + +static DstSlot sub(DstFopts opts, DstAst *ast, DstSM *args) { + DstSM *newargs; + if (dst_v_count(args) == 1) { + newargs = NULL; + dst_v_push(newargs, args[0]); + dst_v_push(newargs, args[0]); + newargs[0].slot = dstc_cslot(dst_wrap_integer(0)); + newargs[0].map = ast; + } else { + newargs = foldc(args, ast, dst_op_subtract); + } + DstSlot ret = opreduce(opts, ast, newargs, DOP_SUBTRACT); + if (newargs != args) dstc_freeslots(opts.compiler, newargs); + return ret; +} + /* Keep in lexographic order */ static const DstCFunOptimizer optimizers[] = { - {dst_add, can_add, add} + {dst_add, numbers, add}, + {dst_subtract, numbers, sub} }; /* Get a cfunction optimizer. Return NULL if none exists. */ diff --git a/src/core/string.c b/src/core/string.c index 3eccf143..6ddaa99b 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -121,19 +121,19 @@ static const uint8_t *real_to_string(double x) { } static int32_t integer_to_string_impl(uint8_t *buf, int32_t x) { - int neg = 0; + int neg = 1; uint8_t *hi, *low; int32_t count = 0; if (x == 0) { buf[0] = '0'; return 1; } - if (x < 0) { - neg = 1; + if (x > 0) { + neg = 0; x = -x; } - while (x > 0) { - uint8_t digit = x % 10; + while (x < 0) { + uint8_t digit = (uint8_t) -(x % 10); buf[count++] = '0' + digit; x /= 10; } diff --git a/src/include/dst/dststl.h b/src/include/dst/dststl.h index f55ed1f1..7ce0c5fe 100644 --- a/src/include/dst/dststl.h +++ b/src/include/dst/dststl.h @@ -46,6 +46,9 @@ int dst_lshift(DstArgs arsg); int dst_rshift(DstArgs args); int dst_lshiftu(DstArgs args); +Dst dst_op_add(Dst lhs, Dst rhs); +Dst dst_op_subtract(Dst lhs, Dst rhs); + /* Native type constructors */ int dst_cfun_table(DstArgs args); int dst_cfun_array(DstArgs args);