Skip to content

Commit 94fba02

Browse files
committed
Reuse registers allocated for parent trace in side traces
1 parent 333a28e commit 94fba02

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,9 +1717,12 @@ static void zend_jit_dump_lifetime_interval(const zend_op_array *op_array, const
17171717
fprintf(stderr, " store");
17181718
}
17191719
if (ival->hint) {
1720-
var_num = ssa->vars[ival->hint->ssa_var].var;
1721-
fprintf(stderr, " hint=#%d.", ival->hint->ssa_var);
1722-
zend_dump_var(op_array, (var_num < op_array->last_var ? IS_CV : 0), var_num);
1720+
fprintf(stderr, " hint");
1721+
if (ival->hint->ssa_var >= 0) {
1722+
var_num = ssa->vars[ival->hint->ssa_var].var;
1723+
fprintf(stderr, "=#%d.", ival->hint->ssa_var);
1724+
zend_dump_var(op_array, (var_num < op_array->last_var ? IS_CV : 0), var_num);
1725+
}
17231726
if (ival->hint->reg != ZREG_NONE) {
17241727
fprintf(stderr, " (%s)", zend_reg_name[ival->hint->reg]);
17251728
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,7 +1738,7 @@ static void zend_jit_close_var(zend_jit_trace_stack *stack, uint32_t n, const ze
17381738
}
17391739
}
17401740

1741-
static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace_rec *trace_buffer, zend_ssa *ssa)
1741+
static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace_rec *trace_buffer, zend_ssa *ssa, uint32_t parent_trace, uint32_t exit_num)
17421742
{
17431743
const zend_op **ssa_opcodes = ((zend_tssa*)ssa)->tssa_opcodes;
17441744
zend_jit_trace_rec *p;
@@ -1751,22 +1751,28 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
17511751
uint8_t *flags;
17521752
const zend_op_array **vars_op_array;
17531753
zend_lifetime_interval **intervals, *list, *ival;
1754+
zend_lifetime_interval *hints = NULL;
17541755
void *checkpoint;
17551756
zend_jit_trace_stack_frame *frame;
17561757
zend_jit_trace_stack *stack;
1758+
uint32_t parent_vars_count = parent_trace ?
1759+
zend_jit_traces[parent_trace].exit_info[exit_num].stack_size : 0;
17571760
ALLOCA_FLAG(use_heap);
17581761

17591762
ZEND_ASSERT(ssa->var_info != NULL);
17601763

17611764
start = do_alloca(sizeof(int) * ssa->vars_count * 2 +
17621765
ZEND_MM_ALIGNED_SIZE(sizeof(uint8_t) * ssa->vars_count) +
1763-
sizeof(zend_op_array*) * ssa->vars_count, use_heap);
1766+
ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array*) * ssa->vars_count) +
1767+
ZEND_MM_ALIGNED_SIZE(sizeof(zend_lifetime_interval) * parent_vars_count),
1768+
use_heap);
17641769
if (!start) {
17651770
return NULL;
17661771
}
17671772
end = start + ssa->vars_count;
17681773
flags = (uint8_t*)(end + ssa->vars_count);
17691774
vars_op_array = (const zend_op_array**)(flags + ZEND_MM_ALIGNED_SIZE(sizeof(uint8_t) * ssa->vars_count));
1775+
hints = (zend_lifetime_interval*)((char*)vars_op_array + ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array*) * ssa->vars_count));
17701776

17711777
memset(start, -1, sizeof(int) * ssa->vars_count * 2);
17721778
memset(flags, 0, sizeof(uint8_t) * ssa->vars_count);
@@ -2105,6 +2111,30 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
21052111
start = end = NULL;
21062112

21072113
/* Add hints */
2114+
if (parent_vars_count) {
2115+
zend_jit_trace_stack *parent_stack =
2116+
zend_jit_traces[parent_trace].stack_map +
2117+
zend_jit_traces[parent_trace].exit_info[exit_num].stack_offset;
2118+
2119+
j = trace_buffer->op_array->last_var;
2120+
if (trace_buffer->start != ZEND_JIT_TRACE_START_ENTER) {
2121+
j += trace_buffer->op_array->T;
2122+
}
2123+
if (parent_vars_count < (uint32_t)j) {
2124+
j = parent_vars_count;
2125+
}
2126+
if (j) {
2127+
memset(hints, 0, sizeof(zend_lifetime_interval) * j);
2128+
for (i = 0; i < j; i++) {
2129+
if (intervals[i] && STACK_REG(parent_stack, i) != ZREG_NONE) {
2130+
intervals[i]->hint = hints + i;
2131+
hints[i].ssa_var = - 1;
2132+
hints[i].reg = STACK_REG(parent_stack, i);
2133+
}
2134+
}
2135+
}
2136+
}
2137+
21082138
if (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LOOP) {
21092139
zend_ssa_phi *phi = ssa->blocks[1].phis;
21102140

@@ -2241,6 +2271,25 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
22412271
}
22422272
}
22432273

2274+
if (parent_vars_count) {
2275+
/* Variables that reuse registers from parent trace don't have to be loaded */
2276+
j = op_array->last_var;
2277+
if (trace_buffer->start != ZEND_JIT_TRACE_START_ENTER) {
2278+
j += op_array->T;
2279+
}
2280+
if (parent_vars_count < (uint32_t)j) {
2281+
j = parent_vars_count;
2282+
}
2283+
for (i = 0; i < j; i++) {
2284+
if (intervals[i]
2285+
&& intervals[i]->hint
2286+
&& intervals[i]->reg == intervals[i]->hint->reg
2287+
&& intervals[i]->hint->ssa_var == -1) {
2288+
intervals[i]->flags &= ~ZREG_LOAD;
2289+
}
2290+
}
2291+
}
2292+
22442293
/* Remove useless register allocation */
22452294
for (i = 0; i < ssa->vars_count; i++) {
22462295
if (intervals[i] &&
@@ -2333,7 +2382,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
23332382

23342383
/* Register allocation */
23352384
if (zend_jit_reg_alloc && zend_jit_level >= ZEND_JIT_LEVEL_INLINE) {
2336-
ra = zend_jit_trace_allocate_registers(trace_buffer, ssa);
2385+
ra = zend_jit_trace_allocate_registers(trace_buffer, ssa, parent_trace, exit_num);
23372386
}
23382387

23392388
p = trace_buffer;

0 commit comments

Comments
 (0)