Skip to content

Commit b0b43e8

Browse files
committed
Register allocator and deoptimizer for tracing JIT.
1 parent d757be6 commit b0b43e8

File tree

4 files changed

+850
-43
lines changed

4 files changed

+850
-43
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ static uint32_t zend_interval_intersection(zend_lifetime_interval *ival1, zend_l
13701370

13711371
/* See "Optimized Interval Splitting in a Linear Scan Register Allocator",
13721372
Christian Wimmer VEE'05 (2005), Figure 4. Allocation without spilling */
1373-
static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, zend_ssa *ssa, zend_lifetime_interval *current, zend_regset available, zend_regset *hints, zend_lifetime_interval *active, zend_lifetime_interval *inactive, zend_lifetime_interval **list, zend_lifetime_interval **free)
1373+
static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, const zend_op **ssa_opcodes, zend_ssa *ssa, zend_lifetime_interval *current, zend_regset available, zend_regset *hints, zend_lifetime_interval *active, zend_lifetime_interval *inactive, zend_lifetime_interval **list, zend_lifetime_interval **free)
13741374
{
13751375
zend_lifetime_interval *it;
13761376
uint32_t freeUntilPos[ZREG_NUM];
@@ -1403,7 +1403,9 @@ static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, zend_ss
14031403
while (it) {
14041404
if (current->range.start != zend_interval_end(it)) {
14051405
freeUntilPos[it->reg] = 0;
1406-
} else if (zend_jit_may_reuse_reg(op_array->opcodes + current->range.start, ssa->ops + current->range.start, ssa, current->ssa_var, it->ssa_var)) {
1406+
} else if (zend_jit_may_reuse_reg(
1407+
ssa_opcodes ? ssa_opcodes[current->range.start] : op_array->opcodes + current->range.start,
1408+
ssa->ops + current->range.start, ssa, current->ssa_var, it->ssa_var)) {
14071409
if (!ZEND_REGSET_IN(*hints, it->reg) &&
14081410
/* TODO: Avoid most often scratch registers. Find a better way ??? */
14091411
(!current->used_as_hint ||
@@ -1468,7 +1470,7 @@ static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, zend_ss
14681470
}
14691471
while (line <= range->end) {
14701472
regset = zend_jit_get_scratch_regset(
1471-
op_array->opcodes + line,
1473+
ssa_opcodes ? ssa_opcodes[line] : op_array->opcodes + line,
14721474
ssa->ops + line,
14731475
op_array, ssa, current->ssa_var, line == last_use_line);
14741476
ZEND_REGSET_FOREACH(regset, reg) {
@@ -1600,7 +1602,7 @@ static int zend_jit_allocate_blocked_reg(void)
16001602

16011603
/* See "Optimized Interval Splitting in a Linear Scan Register Allocator",
16021604
Christian Wimmer VEE'10 (2005), Figure 2. */
1603-
static zend_lifetime_interval* zend_jit_linear_scan(const zend_op_array *op_array, zend_ssa *ssa, zend_lifetime_interval *list)
1605+
static zend_lifetime_interval* zend_jit_linear_scan(const zend_op_array *op_array, const zend_op **ssa_opcodes, zend_ssa *ssa, zend_lifetime_interval *list)
16041606
{
16051607
zend_lifetime_interval *unhandled, *active, *inactive, *handled, *free;
16061608
zend_lifetime_interval *current, **p, *q;
@@ -1659,7 +1661,7 @@ static zend_lifetime_interval* zend_jit_linear_scan(const zend_op_array *op_arra
16591661
}
16601662
}
16611663

1662-
if (zend_jit_try_allocate_free_reg(op_array, ssa, current, available, &hints, active, inactive, &unhandled, &free) ||
1664+
if (zend_jit_try_allocate_free_reg(op_array, ssa_opcodes, ssa, current, available, &hints, active, inactive, &unhandled, &free) ||
16631665
zend_jit_allocate_blocked_reg()) {
16641666
ZEND_REGSET_EXCL(available, current->reg);
16651667
current->list_next = active;
@@ -1792,7 +1794,7 @@ static zend_lifetime_interval** zend_jit_allocate_registers(const zend_op_array
17921794
}
17931795

17941796
/* Linear Scan Register Allocation */
1795-
list = zend_jit_linear_scan(op_array, ssa, list);
1797+
list = zend_jit_linear_scan(op_array, NULL, ssa, list);
17961798

17971799
if (list) {
17981800
intervals = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_lifetime_interval*));
@@ -2132,7 +2134,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
21322134
}
21332135
}
21342136
if (ssa->cfg.blocks[b].flags & ZEND_BB_LOOP_HEADER) {
2135-
if (!zend_jit_check_timeout(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start)) {
2137+
if (!zend_jit_check_timeout(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start, NULL)) {
21362138
goto jit_failure;
21372139
}
21382140
}

ext/opcache/jit/zend_jit_internal.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,10 @@ typedef struct _zend_jit_trace_start_rec {
302302
#define ZEND_JIT_TRACE_START_REC_SIZE 2
303303

304304
typedef struct _zend_jit_trace_exit_info {
305-
const zend_op *opline; /* opline where VM should continue execution */
306-
uint32_t stack_size;
307-
uint32_t stack_offset;
305+
const zend_op *opline; /* opline where VM should continue execution */
306+
const zend_op_array *op_array;
307+
uint32_t stack_size;
308+
uint32_t stack_offset;
308309
} zend_jit_trace_exit_info;
309310

310311
typedef union _zend_jit_trace_stack {
@@ -430,6 +431,7 @@ struct _zend_jit_trace_stack_frame {
430431
} while (0)
431432

432433
typedef struct _zend_jit_globals {
434+
zend_jit_trace_rec *current_trace;
433435
zend_jit_trace_stack_frame *current_frame;
434436

435437
const zend_op *bad_root_cache_opline[ZEND_JIT_TRACE_BAD_ROOT_SLOTS];

0 commit comments

Comments
 (0)