mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Make QM_ASSIGN, JMP_SET and CAST return IS_TMP_VAR.
This commit is contained in:
parent
e8612b72ee
commit
58a41cf795
@ -483,8 +483,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
|
||||
&& opline->result.var == op1->u.op.var) {
|
||||
if (opline->opcode == ZEND_FETCH_R ||
|
||||
opline->opcode == ZEND_FETCH_DIM_R ||
|
||||
opline->opcode == ZEND_FETCH_OBJ_R ||
|
||||
opline->opcode == ZEND_QM_ASSIGN) {
|
||||
opline->opcode == ZEND_FETCH_OBJ_R) {
|
||||
/* It's very rare and useless case. It's better to use
|
||||
additional FREE opcode and simplify the FETCH handlers
|
||||
their selves */
|
||||
@ -1708,7 +1707,9 @@ static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, z
|
||||
SET_NODE(opline->op2, op2);
|
||||
}
|
||||
|
||||
zend_make_tmp_result(result, opline TSRMLS_CC);
|
||||
if (result) {
|
||||
zend_make_tmp_result(result, opline TSRMLS_CC);
|
||||
}
|
||||
|
||||
return opline;
|
||||
}
|
||||
@ -5259,7 +5260,7 @@ void zend_compile_cast(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
|
||||
|
||||
zend_compile_expr(&expr_node, expr_ast TSRMLS_CC);
|
||||
|
||||
opline = zend_emit_op(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
|
||||
opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
|
||||
opline->extended_value = ast->attr;
|
||||
}
|
||||
/* }}} */
|
||||
@ -5278,13 +5279,13 @@ static void zend_compile_shorthand_conditional(znode *result, zend_ast *ast TSRM
|
||||
zend_compile_expr(&cond_node, cond_ast TSRMLS_CC);
|
||||
|
||||
opnum_jmp_set = get_next_op_number(CG(active_op_array));
|
||||
zend_emit_op(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
|
||||
zend_emit_op_tmp(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
|
||||
|
||||
zend_compile_expr(&false_node, false_ast TSRMLS_CC);
|
||||
|
||||
opline_jmp_set = &CG(active_op_array)->opcodes[opnum_jmp_set];
|
||||
opline_jmp_set->op2.opline_num = get_next_op_number(CG(active_op_array)) + 1;
|
||||
opline_qm_assign = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
|
||||
opline_qm_assign = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
|
||||
SET_NODE(opline_qm_assign->result, result);
|
||||
}
|
||||
/* }}} */
|
||||
@ -5311,7 +5312,7 @@ void zend_compile_conditional(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
|
||||
zend_compile_expr(&true_node, true_ast TSRMLS_CC);
|
||||
|
||||
opnum_qm_assign1 = get_next_op_number(CG(active_op_array));
|
||||
zend_emit_op(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
|
||||
zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
|
||||
|
||||
opnum_jmp = zend_emit_jump(0 TSRMLS_CC);
|
||||
|
||||
|
@ -91,7 +91,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -101,6 +101,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
opline->extended_value != IS_OBJECT &&
|
||||
opline->extended_value != IS_RESOURCE) {
|
||||
/* cast of constant operand */
|
||||
zend_uchar type = opline->result_type;
|
||||
uint32_t tv = ZEND_RESULT(opline).var; /* temporary variable */
|
||||
zval res;
|
||||
res = ZEND_OP1_LITERAL(opline);
|
||||
@ -126,11 +127,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
|
||||
if (opline->result_type == IS_TMP_VAR) {
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
|
||||
} else /* if (opline->result_type == IS_VAR) */ {
|
||||
zend_optimizer_replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
|
||||
}
|
||||
zend_optimizer_replace_by_const(op_array, opline + 1, type, tv, &res TSRMLS_CC);
|
||||
} else if (opline->extended_value == _IS_BOOL) {
|
||||
/* T = CAST(X, IS_BOOL) => T = BOOL(X) */
|
||||
opline->opcode = ZEND_BOOL;
|
||||
@ -157,7 +154,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -251,7 +248,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, offset TSRMLS_CC);
|
||||
}
|
||||
EG(current_execute_data) = orig_execute_data;
|
||||
break;
|
||||
@ -271,7 +268,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
}
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
|
||||
}
|
||||
|
||||
/* class constant */
|
||||
@ -332,7 +329,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
}
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &t TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -388,7 +385,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
func->module->type == MODULE_PERSISTENT) {
|
||||
zval t;
|
||||
ZVAL_BOOL(&t, 1);
|
||||
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
|
||||
@ -421,7 +418,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
|
||||
@ -436,7 +433,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) {
|
||||
|
||||
ZVAL_BOOL(&t, 1);
|
||||
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
|
||||
@ -450,7 +447,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
zval t;
|
||||
|
||||
if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 1 TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
|
||||
@ -465,7 +462,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
zval t;
|
||||
|
||||
ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)));
|
||||
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
|
||||
literal_dtor(&ZEND_OP2_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
|
||||
@ -481,7 +478,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
zval t;
|
||||
|
||||
ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline)));
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
}
|
||||
@ -494,7 +491,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
||||
break;
|
||||
}
|
||||
ZVAL_TRUE(&c);
|
||||
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
|
||||
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
}
|
||||
|
@ -262,15 +262,16 @@ check_numeric:
|
||||
}
|
||||
}
|
||||
|
||||
int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
uint32_t var,
|
||||
zval *val TSRMLS_DC)
|
||||
int zend_optimizer_replace_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
zend_uchar type,
|
||||
uint32_t var,
|
||||
zval *val TSRMLS_DC)
|
||||
{
|
||||
zend_op *end = op_array->opcodes + op_array->last;
|
||||
|
||||
while (opline < end) {
|
||||
if (ZEND_OP1_TYPE(opline) == IS_VAR &&
|
||||
if (ZEND_OP1_TYPE(opline) == type &&
|
||||
ZEND_OP1(opline).var == var) {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_FETCH_DIM_W:
|
||||
@ -292,6 +293,25 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
|
||||
opline->opcode = ZEND_SEND_VAL;
|
||||
}
|
||||
break;
|
||||
/* In most cases IS_TMP_VAR operand may be used only once.
|
||||
* The operands are usually destroyed by the opcode handler.
|
||||
* ZEND_CASE is an exception, that keeps operand unchanged,
|
||||
* and allows its reuse. The number of ZEND_CASE instructions
|
||||
* usually terminated by ZEND_FREE that finally kills the value.
|
||||
*/
|
||||
case ZEND_CASE: {
|
||||
zval old_val;
|
||||
ZVAL_COPY_VALUE(&old_val, val);
|
||||
zval_copy_ctor(val);
|
||||
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
|
||||
zval_dtor(&old_val);
|
||||
opline++;
|
||||
continue;
|
||||
}
|
||||
case ZEND_FREE:
|
||||
MAKE_NOP(opline);
|
||||
zval_dtor(val);
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -299,7 +319,7 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ZEND_OP2_TYPE(opline) == IS_VAR &&
|
||||
if (ZEND_OP2_TYPE(opline) == type &&
|
||||
ZEND_OP2(opline).var == var) {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_ASSIGN_REF:
|
||||
@ -316,55 +336,6 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
uint32_t var,
|
||||
zval *val
|
||||
TSRMLS_DC)
|
||||
{
|
||||
zend_op *end = op_array->opcodes + op_array->last;
|
||||
|
||||
while (opline < end) {
|
||||
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
|
||||
ZEND_OP1(opline).var == var) {
|
||||
|
||||
/* In most cases IS_TMP_VAR operand may be used only once.
|
||||
* The operands are usually destroyed by the opcode handler.
|
||||
* ZEND_CASE is an exception, that keeps operand unchanged,
|
||||
* and allows its reuse. The number of ZEND_CASE instructions
|
||||
* usually terminated by ZEND_FREE that finally kills the value.
|
||||
*/
|
||||
if (opline->opcode == ZEND_CASE) {
|
||||
zval old_val;
|
||||
ZVAL_COPY_VALUE(&old_val, val);
|
||||
zval_copy_ctor(val);
|
||||
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
|
||||
ZVAL_COPY_VALUE(val, &old_val);
|
||||
} else if (opline->opcode == ZEND_FREE) {
|
||||
MAKE_NOP(opline);
|
||||
break;
|
||||
} else {
|
||||
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
|
||||
val = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
|
||||
ZEND_OP2(opline).var == var) {
|
||||
|
||||
zend_optimizer_update_op2_const(op_array, opline, val TSRMLS_CC);
|
||||
/* TMP_VAR may be used only once */
|
||||
val = NULL;
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
if (val) {
|
||||
zval_dtor(val);
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_optimize(zend_op_array *op_array,
|
||||
zend_optimizer_ctx *ctx TSRMLS_DC)
|
||||
{
|
||||
|
@ -112,14 +112,11 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
|
||||
void zend_optimizer_update_op2_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
zval *val TSRMLS_DC);
|
||||
int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
uint32_t var,
|
||||
zval *val TSRMLS_DC);
|
||||
void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
uint32_t var,
|
||||
zval *val TSRMLS_DC);
|
||||
int zend_optimizer_replace_by_const(zend_op_array *op_array,
|
||||
zend_op *opline,
|
||||
zend_uchar type,
|
||||
uint32_t var,
|
||||
zval *val TSRMLS_DC);
|
||||
|
||||
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC);
|
||||
void zend_optimizer_pass2(zend_op_array *op_array TSRMLS_DC);
|
||||
|
Loading…
Reference in New Issue
Block a user