@@ -1738,7 +1738,7 @@ static void zend_jit_close_var(zend_jit_trace_stack *stack, uint32_t n, const ze
1738
1738
}
1739
1739
}
1740
1740
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 )
1742
1742
{
1743
1743
const zend_op * * ssa_opcodes = ((zend_tssa * )ssa )-> tssa_opcodes ;
1744
1744
zend_jit_trace_rec * p ;
@@ -1751,22 +1751,28 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
1751
1751
uint8_t * flags ;
1752
1752
const zend_op_array * * vars_op_array ;
1753
1753
zend_lifetime_interval * * intervals , * list , * ival ;
1754
+ zend_lifetime_interval * hints = NULL ;
1754
1755
void * checkpoint ;
1755
1756
zend_jit_trace_stack_frame * frame ;
1756
1757
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 ;
1757
1760
ALLOCA_FLAG (use_heap );
1758
1761
1759
1762
ZEND_ASSERT (ssa -> var_info != NULL );
1760
1763
1761
1764
start = do_alloca (sizeof (int ) * ssa -> vars_count * 2 +
1762
1765
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 );
1764
1769
if (!start ) {
1765
1770
return NULL ;
1766
1771
}
1767
1772
end = start + ssa -> vars_count ;
1768
1773
flags = (uint8_t * )(end + ssa -> vars_count );
1769
1774
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 ));
1770
1776
1771
1777
memset (start , -1 , sizeof (int ) * ssa -> vars_count * 2 );
1772
1778
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
2105
2111
start = end = NULL ;
2106
2112
2107
2113
/* 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
+
2108
2138
if (trace_buffer -> stop == ZEND_JIT_TRACE_STOP_LOOP ) {
2109
2139
zend_ssa_phi * phi = ssa -> blocks [1 ].phis ;
2110
2140
@@ -2241,6 +2271,25 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
2241
2271
}
2242
2272
}
2243
2273
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
+
2244
2293
/* Remove useless register allocation */
2245
2294
for (i = 0 ; i < ssa -> vars_count ; i ++ ) {
2246
2295
if (intervals [i ] &&
@@ -2333,7 +2382,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
2333
2382
2334
2383
/* Register allocation */
2335
2384
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 );
2337
2386
}
2338
2387
2339
2388
p = trace_buffer ;
0 commit comments