From 3c63a48df41c3c06bbcaa3b0006783559ed9f5f6 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Tue, 16 Mar 2021 20:50:17 -0500 Subject: [PATCH] (#667) Add constant inlining for tuples and structs. Structs and tuples composed entirely out of constant values will themselves be considered constant values during compilation. This reduces the amount of generated code. --- src/core/compile.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/core/compile.c b/src/core/compile.c index 89122b39..1527c39a 100644 --- a/src/core/compile.c +++ b/src/core/compile.c @@ -504,10 +504,40 @@ static JanetSlot janetc_call(JanetFopts opts, JanetSlot *slots, JanetSlot fun) { static JanetSlot janetc_maker(JanetFopts opts, JanetSlot *slots, int op) { JanetCompiler *c = opts.compiler; JanetSlot retslot; - janetc_pushslots(c, slots); - janetc_freeslots(c, slots); - retslot = janetc_gettarget(opts); - janetc_emit_s(c, op, retslot, 1); + + /* Check if this structure is composed entirely of constants */ + int can_inline = 1; + for (int32_t i = 0; i < janet_v_count(slots); i++) { + if (!(slots[i].flags & JANET_SLOT_CONSTANT) || + (slots[i].flags & JANET_SLOT_SPLICED)) { + can_inline = 0; + break; + } + } + + if (can_inline && (op == JOP_MAKE_STRUCT)) { + JanetKV *st = janet_struct_begin(janet_v_count(slots) / 2); + for (int32_t i = 0; i < janet_v_count(slots); i += 2) { + Janet k = slots[i].constant; + Janet v = slots[i + 1].constant; + janet_struct_put(st, k, v); + } + retslot = janetc_cslot(janet_wrap_struct(janet_struct_end(st))); + janetc_freeslots(c, slots); + } else if (can_inline && (op == JOP_MAKE_TUPLE)) { + Janet *tup = janet_tuple_begin(janet_v_count(slots)); + for (int32_t i = 0; i < janet_v_count(slots); i++) { + tup[i] = slots[i].constant; + } + retslot = janetc_cslot(janet_wrap_tuple(janet_tuple_end(tup))); + janetc_freeslots(c, slots); + } else { + janetc_pushslots(c, slots); + janetc_freeslots(c, slots); + retslot = janetc_gettarget(opts); + janetc_emit_s(c, op, retslot, 1); + } + return retslot; }