From: Dmitry Stogov Date: Thu, 28 Aug 2014 13:23:12 +0000 (+0400) Subject: Refactored optimizer (compile different opimizer passes separately, instead of includ... X-Git-Tag: PRE_PHP7_REMOVALS~224 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=234af84c04ad805b88e0ecc209eae88fbd923343;p=php Refactored optimizer (compile different opimizer passes separately, instead of including *.c file) --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index db833fbc53..3289299ce1 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -19,10 +19,18 @@ +----------------------------------------------------------------------+ */ +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + #define DEBUG_BLOCKPASS 0 /* Checks if a constant (like "true") may be replaced by its value */ -static int zend_get_persistent_constant(zend_string *name, zval *result, int copy TSRMLS_DC ELS_DC) +int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy TSRMLS_DC) { zend_constant *c; char *lookup_name; @@ -619,7 +627,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, zval c = ZEND_OP1_LITERAL(src); VAR_UNSET(opline->op1); zval_copy_ctor(&c); - update_op1_const(op_array, opline, &c TSRMLS_CC); + zend_optimizer_update_op1_const(op_array, opline, &c TSRMLS_CC); literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } @@ -633,7 +641,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, zval c = ZEND_OP1_LITERAL(src); VAR_UNSET(opline->op2); zval_copy_ctor(&c); - update_op2_const(op_array, opline, &c TSRMLS_CC); + zend_optimizer_update_op2_const(op_array, opline, &c TSRMLS_CC); literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } @@ -713,7 +721,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, int flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len; if(flen == sizeof("defined")-1 && zend_binary_strcasecmp(fname, flen, "defined", sizeof("defined")-1) == 0) { zval c; - if(zend_get_persistent_constant(Z_STR_P(arg), &c, 0 TSRMLS_CC ELS_CC) != 0) { + if(zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, 0 TSRMLS_CC ELS_CC) != 0) { literal_dtor(arg); MAKE_NOP(sv); MAKE_NOP(fcall); @@ -733,7 +741,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, } } else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) { zval c; - if(zend_get_persistent_constant(Z_STR_P(arg), &c, 1 TSRMLS_CC ELS_CC) != 0) { + if(zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, 1 TSRMLS_CC ELS_CC) != 0) { literal_dtor(arg); MAKE_NOP(sv); MAKE_NOP(fcall); @@ -1019,7 +1027,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, literal_dtor(&ZEND_OP2_LITERAL(opline)); opline->opcode = ZEND_QM_ASSIGN; SET_UNUSED(opline->op2); - update_op1_const(op_array, opline, &result TSRMLS_CC); + zend_optimizer_update_op1_const(op_array, opline, &result TSRMLS_CC); } EG(error_reporting) = er; } else if ((opline->opcode == ZEND_BOOL || @@ -1039,7 +1047,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, ZVAL_NULL(&ZEND_OP1_LITERAL(opline)); } opline->opcode = ZEND_QM_ASSIGN; - update_op1_const(op_array, opline, &result TSRMLS_CC); + zend_optimizer_update_op1_const(op_array, opline, &result TSRMLS_CC); } else if ((opline->opcode == ZEND_RETURN || opline->opcode == ZEND_EXIT) && ZEND_OP1_TYPE(opline) == IS_TMP_VAR && VAR_SOURCE(opline->op1) && @@ -1939,7 +1947,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * #define PASSES 3 -static void zend_block_optimization(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) +void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) { zend_cfg cfg; zend_code_block *cur_block; diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 87cae3b12c..e4aae3b7d0 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -20,6 +20,15 @@ /* pass 11 * - compact literals table */ + +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + #define DEBUG_COMPACT_LITERALS 0 #define LITERAL_VALUE 0x0100 @@ -104,7 +113,7 @@ static void optimizer_literal_class_info(literal_info *info, } } -static void optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) +void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) { zend_op *opline, *end; int i, j, n, *map, cache_slots; diff --git a/ext/opcache/Optimizer/nop_removal.c b/ext/opcache/Optimizer/nop_removal.c index 2d695c0495..bea42229f6 100644 --- a/ext/opcache/Optimizer/nop_removal.c +++ b/ext/opcache/Optimizer/nop_removal.c @@ -23,7 +23,15 @@ * - remove NOPs */ -static void nop_removal(zend_op_array *op_array) +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + +void zend_optimizer_nop_removal(zend_op_array *op_array) { zend_op *end, *opline; uint32_t new_count, i, shift; diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index 13aa377568..aa62a4542d 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -21,6 +21,14 @@ * - optimize INIT_FCALL_BY_NAME to DO_FCALL */ +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + #define ZEND_OP2_IS_CONST_STRING(opline) \ (ZEND_OP2_TYPE(opline) == IS_CONST && \ Z_TYPE(op_array->literals[(opline)->op2.constant]) == IS_STRING) @@ -30,7 +38,8 @@ typedef struct _optimizer_call_info { zend_op *opline; } optimizer_call_info; -static void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) { +void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) +{ zend_op *opline = op_array->opcodes; zend_op *end = opline + op_array->last; int call = 0; diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index df5d00a366..a7838cb9dd 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -19,6 +19,14 @@ +----------------------------------------------------------------------+ */ +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + #define GET_AVAILABLE_T() \ for (i = 0; i < T; i++) { \ if (!taken_T[i]) { \ @@ -30,7 +38,7 @@ max = i; \ } -static void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx) +void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx) { int T = op_array->T; int offset = op_array->last_var; diff --git a/ext/opcache/Optimizer/pass10.c b/ext/opcache/Optimizer/pass10.c deleted file mode 100644 index 7f2004a7dc..0000000000 --- a/ext/opcache/Optimizer/pass10.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Zend OPcache | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2014 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andi Gutmans | - | Zeev Suraski | - | Stanislav Malyshev | - | Dmitry Stogov | - +----------------------------------------------------------------------+ -*/ - -if (((ZEND_OPTIMIZER_PASS_10|ZEND_OPTIMIZER_PASS_5) & OPTIMIZATION_LEVEL) == ZEND_OPTIMIZER_PASS_10) { - nop_removal(op_array); -} diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index de09e89123..def060c66c 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -27,9 +27,18 @@ * - pre-evaluate constant function calls */ +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + #define ZEND_IS_CONSTANT_TYPE(t) ((t) == IS_CONSTANT) -if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { +void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) +{ int i = 0; zend_op *opline = op_array->opcodes; zend_op *end = opline + op_array->last; @@ -82,7 +91,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); } break; @@ -118,9 +127,9 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { MAKE_NOP(opline); if (opline->result_type == IS_TMP_VAR) { - replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); } else /* if (opline->result_type == IS_VAR) */ { - replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); + zend_optimizer_replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); } } else if (opline->extended_value == _IS_BOOL) { /* T = CAST(X, IS_BOOL) => T = BOOL(X) */ @@ -148,7 +157,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); } break; @@ -242,7 +251,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC); } EG(current_execute_data) = orig_execute_data; break; @@ -255,14 +264,14 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { uint32_t tv = ZEND_RESULT(opline).var; zval c; - if (!zend_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { + if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { if (!ctx->constants || !zend_optimizer_get_collected_constant(ctx->constants, &ZEND_OP2_LITERAL(opline), &c)) { break; } } literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); } /* class constant */ @@ -307,7 +316,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { Z_STR(ZEND_OP2_LITERAL(opline)))) != NULL) { ZVAL_DEREF(c); if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_P(c))) { - if (!zend_get_persistent_constant(Z_STR_P(c), &t, 1 TSRMLS_CC) || + if (!zend_optimizer_get_persistent_constant(Z_STR_P(c), &t, 1 TSRMLS_CC) || ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) { break; } @@ -323,7 +332,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC); } } } @@ -379,7 +388,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { func->module->type == MODULE_PERSISTENT) { zval t; ZVAL_BOOL(&t, 1); - if (replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { + if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); @@ -412,7 +421,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } } - if (replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { + if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); @@ -424,10 +433,10 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { "defined", sizeof("defined")-1)) { zval t; - if (zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) { + if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) { ZVAL_BOOL(&t, 1); - if (replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { + if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); @@ -440,8 +449,8 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { "constant", sizeof("constant")-1)) { zval t; - if (zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 1 TSRMLS_CC)) { - if (replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { + 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)) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); @@ -456,7 +465,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { zval t; ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); - if (replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { + if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); literal_dtor(&ZEND_OP1_LITERAL(opline + 1)); @@ -472,7 +481,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { zval t; ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline))); - replace_tmp_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC); literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); } @@ -481,11 +490,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { { zval c; uint32_t tv = ZEND_RESULT(opline).var; - if (!zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &c, 0 TSRMLS_CC)) { + if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &c, 0 TSRMLS_CC)) { break; } ZVAL_TRUE(&c); - replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); + zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); } diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c index 083a7b961b..5fa6560d48 100644 --- a/ext/opcache/Optimizer/pass2.c +++ b/ext/opcache/Optimizer/pass2.c @@ -25,7 +25,16 @@ * - optimize static BRKs and CONTs */ -if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + +void zend_optimizer_pass2(zend_op_array *op_array TSRMLS_DC) +{ zend_op *opline; zend_op *end = op_array->opcodes + op_array->last; diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c index 196bdba180..511431bb2c 100644 --- a/ext/opcache/Optimizer/pass3.c +++ b/ext/opcache/Optimizer/pass3.c @@ -25,6 +25,14 @@ * - change $i++ to ++$i where possible */ +#include "php.h" +#include "Optimizer/zend_optimizer.h" +#include "Optimizer/zend_optimizer_internal.h" +#include "zend_API.h" +#include "zend_constants.h" +#include "zend_execute.h" +#include "zend_vm.h" + /* compares opcodes with allowing oc1 be _EX of oc2 */ #define SAME_OPCODE_EX(oc1, oc2) ((oc1 == oc2) || (oc1 == ZEND_JMPZ_EX && oc2 == ZEND_JMPZ) || (oc1 == ZEND_JMPNZ_EX && oc2 == ZEND_JMPNZ)) @@ -45,7 +53,8 @@ } \ jmp_hitlist[jmp_hitlist_count++] = ZEND_OP2(&op_array->opcodes[target]).opline_num; -if (ZEND_OPTIMIZER_PASS_3 & OPTIMIZATION_LEVEL) { +void zend_optimizer_pass3(zend_op_array *op_array TSRMLS_DC) +{ zend_op *opline; zend_op *end = op_array->opcodes + op_array->last; uint32_t *jmp_hitlist; diff --git a/ext/opcache/Optimizer/pass5.c b/ext/opcache/Optimizer/pass5.c deleted file mode 100644 index fffcf985d5..0000000000 --- a/ext/opcache/Optimizer/pass5.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Zend OPcache | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2014 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andi Gutmans | - | Zeev Suraski | - | Stanislav Malyshev | - | Dmitry Stogov | - +----------------------------------------------------------------------+ -*/ - -if (ZEND_OPTIMIZER_PASS_5 & OPTIMIZATION_LEVEL) { - zend_block_optimization(op_array, ctx TSRMLS_CC); -} diff --git a/ext/opcache/Optimizer/pass9.c b/ext/opcache/Optimizer/pass9.c deleted file mode 100644 index 42c2ae1f4d..0000000000 --- a/ext/opcache/Optimizer/pass9.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Zend OPcache | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2014 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andi Gutmans | - | Zeev Suraski | - | Stanislav Malyshev | - | Dmitry Stogov | - +----------------------------------------------------------------------+ -*/ - -/* pass 9 - * - * - optimize usage of temporary variables - */ - -if (ZEND_OPTIMIZER_PASS_9 & OPTIMIZATION_LEVEL) { - optimize_temporary_variables(op_array, ctx); -} diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 0bbfa5c098..6d011afc60 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -27,15 +27,12 @@ #include "zend_execute.h" #include "zend_vm.h" -#define OPTIMIZATION_LEVEL \ - ZCG(accel_directives).optimization_level - static void zend_optimizer_zval_dtor_wrapper(zval *zvalue) { zval_dtor(zvalue); } -static void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value) +void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value) { zval val; @@ -47,7 +44,7 @@ static void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zend_hash_add(ctx->constants, Z_STR_P(name), &val); } -static int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) +int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) { zval *val; @@ -58,7 +55,7 @@ static int zend_optimizer_get_collected_constant(HashTable *constants, zval *nam return 0; } -static int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name) +int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name) { int i = 0; zend_ulong hash_value = zend_string_hash_val(name); @@ -114,32 +111,9 @@ int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) return i; } -# define LITERAL_LONG(op, val) do { \ - zval _c; \ - ZVAL_LONG(&_c, val); \ - op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \ - } while (0) - -# define LITERAL_BOOL(op, val) do { \ - zval _c; \ - ZVAL_BOOL(&_c, val); \ - op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \ - } while (0) - -# define literal_dtor(zv) do { \ - zval_dtor(zv); \ - ZVAL_NULL(zv); \ - } while (0) - -#define COPY_NODE(target, src) do { \ - target ## _type = src ## _type; \ - target = src; \ - } while (0) - - -static void update_op1_const(zend_op_array *op_array, - zend_op *opline, - zval *val TSRMLS_DC) +void zend_optimizer_update_op1_const(zend_op_array *op_array, + zend_op *opline, + zval *val TSRMLS_DC) { if (opline->opcode == ZEND_FREE) { MAKE_NOP(opline); @@ -170,9 +144,9 @@ static void update_op1_const(zend_op_array *op_array, } } -static void update_op2_const(zend_op_array *op_array, - zend_op *opline, - zval *val TSRMLS_DC) +void zend_optimizer_update_op2_const(zend_op_array *op_array, + zend_op *opline, + zval *val TSRMLS_DC) { ZEND_OP2_TYPE(opline) = IS_CONST; if (opline->opcode == ZEND_INIT_FCALL) { @@ -288,10 +262,10 @@ check_numeric: } } -static int replace_var_by_const(zend_op_array *op_array, - zend_op *opline, - uint32_t var, - 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) { zend_op *end = op_array->opcodes + op_array->last; @@ -321,7 +295,7 @@ static int replace_var_by_const(zend_op_array *op_array, default: break; } - update_op1_const(op_array, opline, val TSRMLS_CC); + zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC); break; } @@ -333,7 +307,7 @@ static int replace_var_by_const(zend_op_array *op_array, default: break; } - update_op2_const(op_array, opline, val TSRMLS_CC); + zend_optimizer_update_op2_const(op_array, opline, val TSRMLS_CC); break; } opline++; @@ -342,11 +316,11 @@ static int replace_var_by_const(zend_op_array *op_array, return 1; } -static void replace_tmp_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) { zend_op *end = op_array->opcodes + op_array->last; @@ -364,13 +338,13 @@ static void replace_tmp_by_const(zend_op_array *op_array, zval old_val; ZVAL_COPY_VALUE(&old_val, val); zval_copy_ctor(val); - update_op1_const(op_array, opline, val TSRMLS_CC); + 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 { - update_op1_const(op_array, opline, val TSRMLS_CC); + zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC); val = NULL; break; } @@ -379,7 +353,7 @@ static void replace_tmp_by_const(zend_op_array *op_array, if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR && ZEND_OP2(opline).var == var) { - update_op2_const(op_array, opline, val TSRMLS_CC); + zend_optimizer_update_op2_const(op_array, opline, val TSRMLS_CC); /* TMP_VAR may be used only once */ val = NULL; break; @@ -391,12 +365,6 @@ static void replace_tmp_by_const(zend_op_array *op_array, } } -#include "Optimizer/nop_removal.c" -#include "Optimizer/block_pass.c" -#include "Optimizer/optimize_temp_vars_5.c" -#include "Optimizer/compact_literals.c" -#include "Optimizer/optimize_func_calls.c" - static void zend_optimize(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC) { @@ -410,7 +378,9 @@ static void zend_optimize(zend_op_array *op_array, * - optimize series of ADD_STRING and/or ADD_CHAR * - convert CAST(IS_BOOL,x) into BOOL(x) */ -#include "Optimizer/pass1_5.c" + if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { + zend_optimizer_pass1(op_array, ctx TSRMLS_CC); + } /* pass 2: * - convert non-numeric constants to numeric constants in numeric operators @@ -418,14 +388,18 @@ static void zend_optimize(zend_op_array *op_array, * - optimize static BRKs and CONTs * - pre-evaluate constant function calls */ -#include "Optimizer/pass2.c" + if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { + zend_optimizer_pass2(op_array TSRMLS_CC); + } /* pass 3: * - optimize $i = $i+expr to $i+=expr * - optimize series of JMPs * - change $i++ to ++$i where possible */ -#include "Optimizer/pass3.c" + if (ZEND_OPTIMIZER_PASS_3 & OPTIMIZATION_LEVEL) { + zend_optimizer_pass3(op_array TSRMLS_CC); + } /* pass 4: * - INIT_FCALL_BY_NAME -> DO_FCALL @@ -437,23 +411,29 @@ static void zend_optimize(zend_op_array *op_array, /* pass 5: * - CFG optimization */ -#include "Optimizer/pass5.c" + if (ZEND_OPTIMIZER_PASS_5 & OPTIMIZATION_LEVEL) { + optimize_cfg(op_array, ctx TSRMLS_CC); + } /* pass 9: * - Optimize temp variables usage */ -#include "Optimizer/pass9.c" + if (ZEND_OPTIMIZER_PASS_9 & OPTIMIZATION_LEVEL) { + optimize_temporary_variables(op_array, ctx); + } /* pass 10: * - remove NOPs */ -#include "Optimizer/pass10.c" + if (((ZEND_OPTIMIZER_PASS_10|ZEND_OPTIMIZER_PASS_5) & OPTIMIZATION_LEVEL) == ZEND_OPTIMIZER_PASS_10) { + zend_optimizer_nop_removal(op_array); + } /* pass 11: * - Compact literals table */ if (ZEND_OPTIMIZER_PASS_11 & OPTIMIZATION_LEVEL) { - optimizer_compact_literals(op_array, ctx TSRMLS_CC); + zend_optimizer_compact_literals(op_array, ctx TSRMLS_CC); } } diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index 1ac883b561..ac87cf9f35 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -76,4 +76,58 @@ struct _zend_block_source { zend_block_source *next; }; +#define OPTIMIZATION_LEVEL \ + ZCG(accel_directives).optimization_level + +#define LITERAL_LONG(op, val) do { \ + zval _c; \ + ZVAL_LONG(&_c, val); \ + op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \ + } while (0) + +#define LITERAL_BOOL(op, val) do { \ + zval _c; \ + ZVAL_BOOL(&_c, val); \ + op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \ + } while (0) + +#define literal_dtor(zv) do { \ + zval_dtor(zv); \ + ZVAL_NULL(zv); \ + } while (0) + +#define COPY_NODE(target, src) do { \ + target ## _type = src ## _type; \ + target = src; \ + } while (0) + +int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC); +int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy TSRMLS_DC); +void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value); +int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value); +int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name); +void zend_optimizer_update_op1_const(zend_op_array *op_array, + zend_op *opline, + zval *val TSRMLS_DC); +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); + +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); +void zend_optimizer_pass3(zend_op_array *op_array TSRMLS_DC); +void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC); +void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC); +void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx); +void zend_optimizer_nop_removal(zend_op_array *op_array); +void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC); + #endif diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index f6e6ca9444..793105b966 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -376,7 +376,15 @@ fi shared_alloc_shm.c \ shared_alloc_mmap.c \ shared_alloc_posix.c \ - Optimizer/zend_optimizer.c, + Optimizer/zend_optimizer.c \ + Optimizer/pass1_5.c \ + Optimizer/pass2.c \ + Optimizer/pass3.c \ + Optimizer/optimize_func_calls.c \ + Optimizer/block_pass.c \ + Optimizer/optimize_temp_vars_5.c \ + Optimizer/nop_removal.c \ + Optimizer/compact_literals.c, shared,,,,yes) PHP_ADD_BUILD_DIR([$ext_builddir/Optimizer], 1) diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index af160b207c..9a0713d608 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -16,7 +16,7 @@ if (PHP_OPCACHE != "no") { zend_shared_alloc.c \ shared_alloc_win32.c", true); - ADD_SOURCES(configure_module_dirname + "/Optimizer", "zend_optimizer.c", "opcache", "OptimizerObj"); + ADD_SOURCES(configure_module_dirname + "/Optimizer", "zend_optimizer.c pass1_5.c pass2.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c", "opcache", "OptimizerObj"); ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname);