Skip to content

Commit 759c8b3

Browse files
committed
Replace LIVE_COPY with a split live-range
And handle this case in dce_live_ranges().
1 parent ae85c4a commit 759c8b3

File tree

5 files changed

+18
-62
lines changed

5 files changed

+18
-62
lines changed

Zend/zend_compile.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7556,25 +7556,23 @@ void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */
75567556
/* Free DUPed expressions if there are any */
75577557
if (need_frees) {
75587558
uint32_t jump_opnum = zend_emit_jump(0);
7559+
uint32_t start_opnum = get_next_op_number();
75597560
zend_update_jump_target_to_next(coalesce_opnum);
75607561
ZEND_HASH_FOREACH_PTR(CG(memoized_exprs), node) {
7561-
/* Find existing live range for this variable */
7562-
uint32_t i;
7563-
zend_live_range *live_range;
7564-
for (i = 0; i < CG(active_op_array)->last_live_range; i++) {
7565-
live_range = &CG(active_op_array)->live_range[i];
7566-
if (live_range->var / sizeof(zval) == node->u.op.var) {
7567-
break;
7562+
if (node->op_type == IS_TMP_VAR || node->op_type == IS_VAR) {
7563+
/* Add additional live range for this variable, from the start of the current
7564+
* block to the FREE opcode. */
7565+
uint32_t free_opnum = get_next_op_number();
7566+
if (start_opnum != free_opnum) {
7567+
uint32_t live_range = zend_start_live_range(start_opnum);
7568+
zend_end_live_range(live_range, free_opnum, ZEND_LIVE_TMPVAR, node->u.op.var);
75687569
}
7569-
}
75707570

7571-
/* Adjust live range to end at newly inserted FREE opcode.
7572-
* We don't use emit_op here because we're manually manging live ranges. */
7573-
live_range->end = get_next_op_number();
7574-
live_range->var |= ZEND_LIVE_COPY;
7575-
opline = get_next_op();
7576-
opline->opcode = ZEND_FREE;
7577-
SET_NODE(opline->op1, node);
7571+
/* We don't use emit_op here because we're manually manging live ranges. */
7572+
opline = get_next_op();
7573+
opline->opcode = ZEND_FREE;
7574+
SET_NODE(opline->op1, node);
7575+
}
75787576
} ZEND_HASH_FOREACH_END();
75797577
zend_update_jump_target_to_next(jump_opnum);
75807578
} else {

Zend/zend_compile.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ typedef struct _zend_try_catch_element {
172172
#define ZEND_LIVE_LOOP 1
173173
#define ZEND_LIVE_SILENCE 2
174174
#define ZEND_LIVE_ROPE 3
175-
#define ZEND_LIVE_COPY 4
176-
#define ZEND_LIVE_MASK 7
175+
#define ZEND_LIVE_MASK 3
177176

178177
typedef struct _zend_live_range {
179178
uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */

Zend/zend_execute.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,32 +3613,6 @@ static const zend_live_range *find_live_range(const zend_op_array *op_array, uin
36133613
}
36143614
/* }}} */
36153615

3616-
static zend_bool is_in_dup_liveness_hole(zend_op_array *op_array, const zend_live_range *range, uint32_t op_num) {
3617-
uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
3618-
zend_op *opline = &op_array->opcodes[op_num];
3619-
zend_op *cur = &op_array->opcodes[range->end];
3620-
while (cur->opcode == ZEND_FREE) {
3621-
cur--;
3622-
}
3623-
ZEND_ASSERT(cur->opcode == ZEND_JMP);
3624-
3625-
if (opline > cur) {
3626-
/* Inside the FREE block, after the hole */
3627-
return 0;
3628-
}
3629-
3630-
while (++opline <= cur) {
3631-
if (((opline->op1_type & (IS_TMP_VAR|IS_VAR)) && opline->op1.var == var_num) ||
3632-
((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && opline->op2.var == var_num)
3633-
) {
3634-
/* Found use, before hole */
3635-
return 0;
3636-
}
3637-
}
3638-
3639-
return 1;
3640-
}
3641-
36423616
static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) /* {{{ */
36433617
{
36443618
int i;
@@ -3682,12 +3656,6 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num,
36823656
if (!EG(error_reporting) && Z_LVAL_P(var) != 0) {
36833657
EG(error_reporting) = Z_LVAL_P(var);
36843658
}
3685-
} else if (kind == ZEND_LIVE_COPY) {
3686-
/* DUP live ranges are not contiguous, so we need to check whether we
3687-
* are inside the liveness hole. */
3688-
if (!is_in_dup_liveness_hole(&EX(func)->op_array, range, op_num)) {
3689-
zval_ptr_dtor_nogc(var);
3690-
}
36913659
}
36923660
}
36933661
}

ext/opcache/Optimizer/dce.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -514,21 +514,18 @@ static void dce_live_ranges(context *ctx, zend_op_array *op_array, zend_ssa *ssa
514514
}
515515
}
516516

517-
#if ZEND_DEBUG
518-
ZEND_ASSERT(op_array->opcodes[def].result_type & (IS_TMP_VAR|IS_VAR));
519-
ZEND_ASSERT(op_array->opcodes[def].result.var == var);
520-
ZEND_ASSERT(ssa->ops[def].result_def >= 0);
521-
#else
522517
if (!(op_array->opcodes[def].result_type & (IS_TMP_VAR|IS_VAR))
523518
|| op_array->opcodes[def].result.var != var
524519
|| ssa->ops[def].result_def < 0) {
525-
/* TODO: Some wrong live-range? keep it. */
520+
/* This can only happen if this is split COPY_TMP live-range, in which case
521+
* the second part of the live-range will start after a JMP. */
522+
ZEND_ASSERT(op_array->opcodes[def].opcode == ZEND_JMP);
523+
526524
j++;
527525
live_range++;
528526
i++;
529527
continue;
530528
}
531-
#endif
532529

533530
var = ssa->ops[def].result_def;
534531

ext/opcache/Optimizer/zend_dump.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,9 +1034,6 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons
10341034
case ZEND_LIVE_ROPE:
10351035
fprintf(stderr, "(rope)\n");
10361036
break;
1037-
case ZEND_LIVE_COPY:
1038-
fprintf(stderr, "(copy)\n");
1039-
break;
10401037
}
10411038
}
10421039
}
@@ -1093,9 +1090,6 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons
10931090
case ZEND_LIVE_ROPE:
10941091
fprintf(stderr, "(rope)\n");
10951092
break;
1096-
case ZEND_LIVE_COPY:
1097-
fprintf(stderr, "(copy)\n");
1098-
break;
10991093
}
11001094
}
11011095
}

0 commit comments

Comments
 (0)