mirror of
https://github.com/janet-lang/janet
synced 2025-01-11 16:10:27 +00:00
Addition and subtraction inlining.
This commit is contained in:
parent
5460ff19bf
commit
2bd20c3cb3
@ -23,17 +23,17 @@
|
|||||||
#include <dst/dst.h>
|
#include <dst/dst.h>
|
||||||
#include <dst/dststl.h>
|
#include <dst/dststl.h>
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#define DST_V_NODEF_GROW
|
|
||||||
#include <headerlibs/vector.h>
|
#include <headerlibs/vector.h>
|
||||||
#undef DST_V_NODEF_GROW
|
#undef DST_V_NODEF_GROW
|
||||||
|
|
||||||
/* This logic needs to be expanded for more types */
|
/* This logic needs to be expanded for more types */
|
||||||
|
|
||||||
/* Check if a function recieved only numbers */
|
/* Check if a function received only numbers */
|
||||||
static int numbers(DstFopts opts, DstSM *args) {
|
static int numbers(DstFopts opts, DstAst *ast, DstSM *args) {
|
||||||
int32_t i;
|
int32_t i;
|
||||||
int32_t len = dst_v_count(args);
|
int32_t len = dst_v_count(args);
|
||||||
(void) opts;
|
(void) opts;
|
||||||
|
(void) ast;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
DstSlot s = args[i].slot;
|
DstSlot s = args[i].slot;
|
||||||
if (s.flags & DST_SLOT_CONSTANT) {
|
if (s.flags & DST_SLOT_CONSTANT) {
|
||||||
@ -48,12 +48,34 @@ static int numbers(DstFopts opts, DstSM *args) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_add(DstFopts opts, DstAst *ast, DstSM *args) {
|
/* Fold constants in a DstSM */
|
||||||
(void) ast;
|
static DstSM *foldc(DstSM *sms, DstAst *ast, Dst (*fn)(Dst lhs, Dst rhs)) {
|
||||||
return numbers(opts, args);
|
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;
|
DstCompiler *c = opts.compiler;
|
||||||
int32_t i, len;
|
int32_t i, len;
|
||||||
int32_t op1, op2;
|
int32_t op1, op2;
|
||||||
@ -68,20 +90,44 @@ static DstSlot add(DstFopts opts, DstAst *ast, DstSM *args) {
|
|||||||
/* Compile initial two arguments */
|
/* Compile initial two arguments */
|
||||||
op1 = dstc_preread(c, args[0].map, 0xFF, 1, args[0].slot);
|
op1 = dstc_preread(c, args[0].map, 0xFF, 1, args[0].slot);
|
||||||
op2 = dstc_preread(c, args[1].map, 0xFF, 2, args[1].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[0].slot, op1);
|
||||||
dstc_postread(c, args[1].slot, op2);
|
dstc_postread(c, args[1].slot, op2);
|
||||||
for (i = 2; i < len; i++) {
|
for (i = 2; i < len; i++) {
|
||||||
op1 = dstc_preread(c, args[i].map, 0xFF, 1, args[i].slot);
|
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);
|
dstc_postread(c, args[i].slot, op1);
|
||||||
}
|
}
|
||||||
return t;
|
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 */
|
/* Keep in lexographic order */
|
||||||
static const DstCFunOptimizer optimizers[] = {
|
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. */
|
/* Get a cfunction optimizer. Return NULL if none exists. */
|
||||||
|
@ -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) {
|
static int32_t integer_to_string_impl(uint8_t *buf, int32_t x) {
|
||||||
int neg = 0;
|
int neg = 1;
|
||||||
uint8_t *hi, *low;
|
uint8_t *hi, *low;
|
||||||
int32_t count = 0;
|
int32_t count = 0;
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
buf[0] = '0';
|
buf[0] = '0';
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x > 0) {
|
||||||
neg = 1;
|
neg = 0;
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
while (x > 0) {
|
while (x < 0) {
|
||||||
uint8_t digit = x % 10;
|
uint8_t digit = (uint8_t) -(x % 10);
|
||||||
buf[count++] = '0' + digit;
|
buf[count++] = '0' + digit;
|
||||||
x /= 10;
|
x /= 10;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,9 @@ int dst_lshift(DstArgs arsg);
|
|||||||
int dst_rshift(DstArgs args);
|
int dst_rshift(DstArgs args);
|
||||||
int dst_lshiftu(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 */
|
/* Native type constructors */
|
||||||
int dst_cfun_table(DstArgs args);
|
int dst_cfun_table(DstArgs args);
|
||||||
int dst_cfun_array(DstArgs args);
|
int dst_cfun_array(DstArgs args);
|
||||||
|
Loading…
Reference in New Issue
Block a user