diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2015-06-14 06:01:01 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2015-06-14 06:01:01 +0200 |
commit | 3cfa58367b1b85d346d9be6cf9ae116c63571247 (patch) | |
tree | 95d0ebf14bf0e2953a911d317a17f7fcd1fd1ccb /Zend/zend_compile.c | |
parent | b97944c6d1469ba9979843e27050068aa914eb39 (diff) | |
download | php-git-3cfa58367b1b85d346d9be6cf9ae116c63571247.tar.gz |
Expand optimizations regarding short-circuting a bit
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f753af4483..61271f6143 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5840,31 +5840,65 @@ void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(&left_node, left_ast); + if (left_node.op_type == IS_CONST) { + if ( + (ast->kind == ZEND_AST_AND && !zend_is_true(&left_node.u.constant)) + || (ast->kind == ZEND_AST_OR && zend_is_true(&left_node.u.constant)) + ) { + result->op_type = IS_CONST; + ZVAL_BOOL(&result->u.constant, zend_is_true(&left_node.u.constant)); + } else { + zend_compile_expr(&right_node, right_ast); + + if (right_node.op_type == IS_CONST) { + result->op_type = IS_CONST; + ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant)); + } else { + zend_emit_op(result, ZEND_BOOL, &right_node, NULL); + } + + zval_ptr_dtor(&right_node.u.constant); + } + + zval_ptr_dtor(&left_node.u.constant); + return; + } + opnum_jmpz = get_next_op_number(CG(active_op_array)); opline_jmpz = zend_emit_op(NULL, ast->kind == ZEND_AST_AND ? ZEND_JMPZ_EX : ZEND_JMPNZ_EX, &left_node, NULL); if (left_node.op_type == IS_TMP_VAR) { SET_NODE(opline_jmpz->result, &left_node); - } else { - opline_jmpz->result.var = get_temporary_variable(CG(active_op_array)); - opline_jmpz->result_type = IS_TMP_VAR; } - GET_NODE(result, opline_jmpz->result); zend_compile_expr(&right_node, right_ast); - if (right_node.op_type == IS_CONST && ( - (ast->kind == ZEND_AST_AND && !zend_is_true(&right_node.u.constant)) - || (ast->kind == ZEND_AST_OR && zend_is_true(&right_node.u.constant)) - )) { - result->op_type = IS_CONST; - ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant)); + if (right_node.op_type == IS_CONST && opnum_jmpz == CG(active_op_array)->last) { + if ( + (ast->kind == ZEND_AST_AND && !zend_is_true(&right_node.u.constant)) + || (ast->kind == ZEND_AST_OR && zend_is_true(&right_node.u.constant)) + ) { + CG(active_op_array)->last--; + result->op_type = IS_CONST; + ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant)); + } else { + opline_jmpz->opcode = ZEND_BOOL; + zend_make_var_result(result, opline_jmpz); + } + zval_ptr_dtor(&right_node.u.constant); - } else { - opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL); - SET_NODE(opline_bool->result, result); + return; + } + + if (left_node.op_type != IS_TMP_VAR) { + opline_jmpz->result.var = get_temporary_variable(CG(active_op_array)); + opline_jmpz->result_type = IS_TMP_VAR; } + GET_NODE(result, opline_jmpz->result); + + opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL); + SET_NODE(opline_bool->result, result); zend_update_jump_target_to_next(opnum_jmpz); } |