Skip to content

Commit 35a3e45

Browse files
committed
Better registers usage
1 parent c64cb19 commit 35a3e45

File tree

1 file changed

+95
-57
lines changed

1 file changed

+95
-57
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 95 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,8 @@ static void* dasm_labels[zend_lb_MAX];
894894
|| }
895895
| .if X64
896896
|| } else if (!IS_32BIT(zv)) {
897-
| mov64 tmp_reg, ((uintptr_t)zv)
898-
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
897+
| mov64 Ra(tmp_reg), ((uintptr_t)zv)
898+
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra(tmp_reg)]
899899
| .endif
900900
|| } else {
901901
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
@@ -913,8 +913,8 @@ static void* dasm_labels[zend_lb_MAX];
913913
|| if (Z_MODE(dst_addr) == IS_REG) {
914914
| mov64 Ra(Z_REG(dst_addr)), ((uintptr_t)Z_LVAL_P(zv))
915915
|| } else {
916-
| mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
917-
| SET_ZVAL_LVAL dst_addr, tmp_reg
916+
| mov64 Ra(tmp_reg), ((uintptr_t)Z_LVAL_P(zv))
917+
| SET_ZVAL_LVAL dst_addr, Ra(tmp_reg)
918918
|| }
919919
|| } else {
920920
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
@@ -948,8 +948,8 @@ static void* dasm_labels[zend_lb_MAX];
948948
|| }
949949
| .if X64
950950
|| } else if (!IS_32BIT(zv)) {
951-
| mov64 tmp_reg, ((uintptr_t)zv)
952-
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
951+
| mov64 Ra(tmp_reg), ((uintptr_t)zv)
952+
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra(tmp_reg)]
953953
| .endif
954954
|| } else {
955955
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
@@ -986,9 +986,9 @@ static void* dasm_labels[zend_lb_MAX];
986986
| mov64 Ra(Z_REG(res_addr)), ((uintptr_t)Z_LVAL_P(zv))
987987
| SET_ZVAL_LVAL dst_addr, Ra(Z_REG(res_addr))
988988
|| } else {
989-
| mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
990-
| SET_ZVAL_LVAL dst_addr, tmp_reg
991-
| SET_ZVAL_LVAL res_addr, tmp_reg
989+
| mov64 Ra(tmp_reg), ((uintptr_t)Z_LVAL_P(zv))
990+
| SET_ZVAL_LVAL dst_addr, Ra(tmp_reg)
991+
| SET_ZVAL_LVAL res_addr, Ra(tmp_reg)
992992
|| }
993993
|| } else if (Z_MODE(dst_addr) == IS_REG) {
994994
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
@@ -5367,20 +5367,28 @@ static int zend_jit_simple_assign(dasm_State **Dst,
53675367
int save_r1)
53685368
/* Labels: 1,2,3 */
53695369
{
5370-
ZEND_ASSERT(Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0);
5370+
zend_reg tmp_reg;
5371+
5372+
if (Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0) {
5373+
tmp_reg = ZREG_R0;
5374+
} else {
5375+
/* ASSIGN_DIM */
5376+
tmp_reg = ZREG_FCARG1a;
5377+
}
5378+
53715379
if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
53725380
zval *zv = Z_ZV(val_addr);
53735381

53745382
if (!res_addr) {
5375-
| ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, r0
5383+
| ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, tmp_reg
53765384
} else {
5377-
| ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, r0
5385+
| ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, tmp_reg
53785386
}
53795387
if (Z_REFCOUNTED_P(zv)) {
53805388
if (!res_addr) {
5381-
| ADDREF_CONST zv, r0
5389+
| ADDREF_CONST zv, Ra(tmp_reg)
53825390
} else {
5383-
| ADDREF_CONST_2 zv, r0
5391+
| ADDREF_CONST_2 zv, Ra(tmp_reg)
53845392
}
53855393
}
53865394
} else {
@@ -5400,7 +5408,7 @@ static int zend_jit_simple_assign(dasm_State **Dst,
54005408
if (res_addr) {
54015409
| SET_ZVAL_TYPE_INFO res_addr, IS_NULL
54025410
}
5403-
| SAVE_VALID_OPLINE opline, r0
5411+
| SAVE_VALID_OPLINE opline, Ra(tmp_reg)
54045412
| mov FCARG1d, val.var
54055413
| EXT_CALL zend_jit_undefined_op_helper, r0
54065414
if (save_r1) {
@@ -5435,22 +5443,22 @@ static int zend_jit_simple_assign(dasm_State **Dst,
54355443
| // ZVAL_COPY_VALUE(return_value, &ref->value);
54365444
ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8);
54375445
if (!res_addr) {
5438-
| ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, ZREG_R0
5446+
| ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg
54395447
} else {
5440-
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, ZREG_R0
5448+
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg
54415449
}
54425450
| je >2
54435451
| IF_NOT_REFCOUNTED dh, >3
54445452
if (!res_addr) {
5445-
| GC_ADDREF r0
5453+
| GC_ADDREF Ra(tmp_reg)
54465454
} else {
5447-
| add dword [r0], 2
5455+
| add dword [Ra(tmp_reg)], 2
54485456
}
54495457
| jmp >3
54505458
|2:
54515459
if (res_addr) {
54525460
| IF_NOT_REFCOUNTED dh, >2
5453-
| GC_ADDREF r0
5461+
| GC_ADDREF Ra(tmp_reg)
54545462
|2:
54555463
}
54565464
if (save_r1) {
@@ -5470,20 +5478,20 @@ static int zend_jit_simple_assign(dasm_State **Dst,
54705478
}
54715479

54725480
if (!res_addr) {
5473-
| ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, ZREG_R0
5481+
| ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, tmp_reg
54745482
} else {
5475-
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, ZREG_R0
5483+
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, tmp_reg
54765484
}
54775485

54785486
if (val_type == IS_CV) {
54795487
if (!res_addr) {
5480-
| TRY_ADDREF val_info, dh, r0
5488+
| TRY_ADDREF val_info, dh, Ra(tmp_reg)
54815489
} else {
5482-
| TRY_ADDREF_2 val_info, dh, r0
5490+
| TRY_ADDREF_2 val_info, dh, Ra(tmp_reg)
54835491
}
54845492
} else {
54855493
if (res_addr) {
5486-
| TRY_ADDREF val_info, dh, r0
5494+
| TRY_ADDREF val_info, dh, Ra(tmp_reg)
54875495
}
54885496
}
54895497
|3:
@@ -5543,24 +5551,33 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
55435551
/* Labels: 1,2,3,4,5,8 */
55445552
{
55455553
int done = 0;
5554+
zend_reg ref_reg, tmp_reg;
5555+
5556+
if (Z_MODE(var_addr) == IS_REG || Z_REG(var_use_addr) != ZREG_R0) {
5557+
ref_reg = ZREG_FCARG1a;
5558+
tmp_reg = ZREG_R0;
5559+
} else {
5560+
/* ASSIGN_DIM */
5561+
ref_reg = ZREG_R0;
5562+
tmp_reg = ZREG_FCARG1a;
5563+
}
55465564

55475565
if (var_info & MAY_BE_REF) {
5548-
if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ZREG_FCARG1a || Z_OFFSET(var_use_addr) != 0) {
5549-
| LOAD_ZVAL_ADDR FCARG1a, var_use_addr
5550-
var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
5566+
if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ref_reg || Z_OFFSET(var_use_addr) != 0) {
5567+
| LOAD_ZVAL_ADDR Ra(ref_reg), var_use_addr
5568+
var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ref_reg, 0);
55515569
}
55525570
| // if (Z_ISREF_P(variable_ptr)) {
5553-
| IF_NOT_Z_TYPE, FCARG1a, IS_REFERENCE, >1
5571+
| IF_NOT_Z_TYPE, Ra(ref_reg), IS_REFERENCE, >1
55545572
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
5555-
| GET_Z_PTR FCARG1a, FCARG1a
5573+
| GET_Z_PTR FCARG1a, Ra(ref_reg)
55565574
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
55575575
return 0;
55585576
}
5559-
| add FCARG1a, offsetof(zend_reference, val)
5577+
| lea Ra(ref_reg), [FCARG1a + offsetof(zend_reference, val)]
55605578
|1:
55615579
}
55625580
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
5563-
ZEND_ASSERT(Z_REG(var_use_addr) != ZREG_R0);
55645581
if (RC_MAY_BE_1(var_info)) {
55655582
int in_cold = 0;
55665583

@@ -5570,13 +5587,42 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
55705587
|1:
55715588
in_cold = 1;
55725589
}
5573-
if (Z_REG(var_use_addr) == ZREG_FCARG1a) {
5574-
| GET_ZVAL_PTR r0, var_use_addr
5575-
| mov aword T1, r0 // save
5590+
if (Z_REG(var_use_addr) == ZREG_FCARG1a || Z_REG(var_use_addr) == ZREG_R0) {
5591+
zend_bool keep_gc = 0;
5592+
5593+
| GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
5594+
if (tmp_reg == ZREG_FCARG1a) {
5595+
if (Z_MODE(val_addr) == IS_REG) {
5596+
keep_gc = 1;
5597+
} else if ((val_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) == 0) {
5598+
keep_gc = 1;
5599+
} else if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
5600+
if (sizeof(void*) == 4) {
5601+
keep_gc = 1;
5602+
} else {
5603+
zval *zv = Z_ZV(val_addr);
5604+
5605+
if (Z_TYPE_P(zv) == IS_DOUBLE) {
5606+
if (Z_DVAL_P(zv) == 0 || IS_32BIT(zv)) {
5607+
keep_gc = 1;
5608+
}
5609+
} else if (IS_SIGNED_32BIT(Z_LVAL_P(zv))) {
5610+
keep_gc = 1;
5611+
}
5612+
}
5613+
} else if (Z_MODE(val_addr) == IS_MEM_ZVAL) {
5614+
if ((val_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_DOUBLE) {
5615+
keep_gc = 1;
5616+
}
5617+
}
5618+
}
5619+
if (!keep_gc) {
5620+
| mov aword T1, Ra(tmp_reg) // save
5621+
}
55765622
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val, val_addr, val_info, res_addr, in_cold, 0)) {
55775623
return 0;
55785624
}
5579-
if (Z_REG(var_use_addr) == ZREG_FCARG1a) {
5625+
if (!keep_gc) {
55805626
| mov FCARG1a, aword T1 // restore
55815627
}
55825628
} else {
@@ -5618,26 +5664,20 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
56185664
if (var_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
56195665
| IF_NOT_ZVAL_REFCOUNTED var_use_addr, >5
56205666
}
5621-
| GET_ZVAL_PTR r0, var_use_addr
5622-
| GC_DELREF r0
56235667
if (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) {
56245668
if (Z_REG(var_use_addr) == ZREG_FP) {
5625-
| GET_ZVAL_PTR FCARG1a, var_use_addr
5626-
| IF_GC_MAY_NOT_LEAK FCARG1a, >5
5627-
} else if (Z_REG(var_use_addr) != ZREG_FCARG1a) {
5628-
| GET_ZVAL_PTR FCARG1a, var_use_addr
5629-
| IF_GC_MAY_NOT_LEAK FCARG1a, >5
5630-
| mov T1, Ra(Z_REG(var_use_addr)) // save
5631-
} else {
5632-
| GET_ZVAL_PTR r0, var_use_addr
5633-
| IF_GC_MAY_NOT_LEAK r0, >5
56345669
| mov T1, Ra(Z_REG(var_use_addr)) // save
5635-
| GET_ZVAL_PTR FCARG1a, var_use_addr
56365670
}
5671+
| GET_ZVAL_PTR FCARG1a, var_use_addr
5672+
| GC_DELREF FCARG1a
5673+
| IF_GC_MAY_NOT_LEAK FCARG1a, >5
56375674
| EXT_CALL gc_possible_root, r0
56385675
if (Z_REG(var_use_addr) != ZREG_FP) {
56395676
| mov Ra(Z_REG(var_use_addr)), T1 // restore
56405677
}
5678+
} else {
5679+
| GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
5680+
| GC_DELREF Ra(tmp_reg)
56415681
}
56425682
|5:
56435683
}
@@ -5714,7 +5754,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
57145754
|6:
57155755
if (opline->op2_type == IS_UNUSED) {
57165756
uint32_t var_info = MAY_BE_NULL;
5717-
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
5757+
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
57185758

57195759
| // var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
57205760
| LOAD_ADDR_ZTS FCARG2a, executor_globals, uninitialized_zval
@@ -5729,28 +5769,26 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
57295769
| //ZEND_VM_C_GOTO(assign_dim_op_ret_null);
57305770
| jmp >9
57315771
|.code
5732-
| mov FCARG1a, r0
57335772

57345773
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0, 0)) {
57355774
return 0;
57365775
}
57375776
} else {
57385777
uint32_t var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
5739-
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
5778+
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
57405779

57415780
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, NULL, NULL, NULL)) {
57425781
return 0;
57435782
}
57445783

5745-
|8:
5746-
| mov FCARG1a, r0
5747-
57485784
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
57495785
var_info |= MAY_BE_REF;
57505786
}
57515787
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
57525788
var_info |= MAY_BE_RC1;
57535789
}
5790+
5791+
|8:
57545792
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
57555793
if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
57565794
return 0;
@@ -9191,7 +9229,7 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o
91919229
if (opline->op1_type == IS_CONST) {
91929230
zval *zv = RT_CONSTANT(opline, opline->op1);
91939231

9194-
| ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, r0
9232+
| ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_R0
91959233
if (Z_REFCOUNTED_P(zv)) {
91969234
| ADDREF_CONST zv, r0
91979235
}
@@ -10297,7 +10335,7 @@ static int zend_jit_return(dasm_State **Dst, const zend_op *opline, const zend_o
1029710335

1029810336
if (opline->op1_type == IS_CONST) {
1029910337
zval *zv = RT_CONSTANT(opline, opline->op1);
10300-
| ZVAL_COPY_CONST ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, r0
10338+
| ZVAL_COPY_CONST ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_R0
1030110339
if (Z_REFCOUNTED_P(zv)) {
1030210340
| ADDREF_CONST zv, r0
1030310341
}
@@ -11102,7 +11140,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
1110211140
| cmp dword EX->This.u2.num_args, arg_num
1110311141
| jae >5
1110411142
}
11105-
| ZVAL_COPY_CONST res_addr, -1, -1, zv, r0
11143+
| ZVAL_COPY_CONST res_addr, -1, -1, zv, ZREG_R0
1110611144
if (Z_REFCOUNTED_P(zv)) {
1110711145
| ADDREF_CONST zv, r0
1110811146
}

0 commit comments

Comments
 (0)