GitHub

@@ -2661,6 +2661,58 @@ nosplat(node *t)

26612661

return TRUE;

26622662

}

266326632664+

/* Check if node is a simple literal that can be generated into any register */

2665+

static mrb_bool

2666+

is_simple_literal(node *n)

2667+

{

2668+

switch (get_node_type(n)) {

2669+

case NODE_INT:

2670+

case NODE_NIL:

2671+

case NODE_TRUE:

2672+

case NODE_FALSE:

2673+

return TRUE;

2674+

default:

2675+

return FALSE;

2676+

}

2677+

}

2678+2679+

/* Check if all lhs are local variables and get their registers */

2680+

static mrb_bool

2681+

all_lvar_pre(codegen_scope *s, node *pre, int *regs, int max)

2682+

{

2683+

int i = 0;

2684+

while (pre && i < max) {

2685+

if (get_node_type(pre->car) != NODE_LVAR) return FALSE;

2686+

int idx = lv_idx(s, var_node(pre->car)->symbol);

2687+

if (idx <= 0) return FALSE; /* not a local variable */

2688+

regs[i++] = idx;

2689+

pre = pre->cdr;

2690+

}

2691+

return pre == NULL; /* all processed */

2692+

}

2693+2694+

/* Generate a simple literal directly into a specific register */

2695+

static void

2696+

gen_literal_to_reg(codegen_scope *s, node *n, int reg)

2697+

{

2698+

switch (get_node_type(n)) {

2699+

case NODE_INT:

2700+

gen_int(s, reg, int_node(n)->value);

2701+

break;

2702+

case NODE_NIL:

2703+

genop_1(s, OP_LOADNIL, reg);

2704+

break;

2705+

case NODE_TRUE:

2706+

genop_1(s, OP_LOADT, reg);

2707+

break;

2708+

case NODE_FALSE:

2709+

genop_1(s, OP_LOADF, reg);

2710+

break;

2711+

default:

2712+

break;

2713+

}

2714+

}

2715+26642716

static mrb_sym

26652717

attrsym(codegen_scope *s, mrb_sym a)

26662718

{

@@ -4974,6 +5026,37 @@ codegen_masgn(codegen_scope *s, node *varnode, node *rhs, int sp, int val)

49745026

if (an->elements && nosplat(an->elements)) {

49755027

/* fixed rhs */

49765028

t = an->elements;

5029+5030+

/* Optimization: direct generation for simple cases */

5031+

/* When all lhs are local vars and all rhs are simple literals, */

5032+

/* generate directly into target registers (no temporaries) */

5033+

if (masgn_n->pre && !masgn_n->rest && !masgn_n->post) {

5034+

int regs[16]; /* support up to 16 variables */

5035+

node *lhs = masgn_n->pre;

5036+

node *rhs_elem = t;

5037+

int count = 0;

5038+

mrb_bool all_simple = TRUE;

5039+5040+

/* Count and check rhs are all simple literals */

5041+

while (rhs_elem && count < 16) {

5042+

if (!is_simple_literal(rhs_elem->car)) {

5043+

all_simple = FALSE;

5044+

break;

5045+

}

5046+

count++;

5047+

rhs_elem = rhs_elem->cdr;

5048+

}

5049+

if (all_simple && count > 0 && all_lvar_pre(s, lhs, regs, count)) {

5050+

/* Direct generation: generate literals into target registers */

5051+

rhs_elem = t;

5052+

for (int i = 0; i < count; i++) {

5053+

gen_literal_to_reg(s, rhs_elem->car, regs[i]);

5054+

rhs_elem = rhs_elem->cdr;

5055+

}

5056+

return;

5057+

}

5058+

}

5059+49775060

rhs_reg = cursp(); /* Save register where values will be pushed */

49785061

while (t) {

49795062

codegen(s, t->car, VAL);

Read the original on github.com ↗