From: Dmitry Stogov Date: Thu, 10 Oct 2019 20:20:36 +0000 (+0300) Subject: Revert/redo pass_two only once X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3ad20f80f5c0a07ffbdc3acea2b706990796fdb8;p=php Revert/redo pass_two only once --- diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c index 8d677c1b86..a98dd99d35 100644 --- a/ext/opcache/Optimizer/zend_call_graph.c +++ b/ext/opcache/Optimizer/zend_call_graph.c @@ -250,10 +250,8 @@ static void zend_sort_op_arrays(zend_call_graph *call_graph) // TODO: perform topological sort of cyclic call graph } -int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph) /* {{{ */ +int zend_build_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph) /* {{{ */ { - int i; - call_graph->op_arrays_count = 0; if (zend_foreach_op_array(call_graph, script, zend_op_array_calc) != SUCCESS) { return FAILURE; @@ -264,13 +262,20 @@ int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t buil if (zend_foreach_op_array(call_graph, script, zend_op_array_collect) != SUCCESS) { return FAILURE; } + + return SUCCESS; +} +/* }}} */ + +void zend_analyze_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph) /* {{{ */ +{ + int i; + for (i = 0; i < call_graph->op_arrays_count; i++) { zend_analyze_calls(arena, script, build_flags, call_graph->op_arrays[i], call_graph->func_infos + i); } zend_analyze_recursion(call_graph); zend_sort_op_arrays(call_graph); - - return SUCCESS; } /* }}} */ diff --git a/ext/opcache/Optimizer/zend_call_graph.h b/ext/opcache/Optimizer/zend_call_graph.h index 033c675b63..cfad3358fd 100644 --- a/ext/opcache/Optimizer/zend_call_graph.h +++ b/ext/opcache/Optimizer/zend_call_graph.h @@ -69,7 +69,8 @@ typedef struct _zend_call_graph { BEGIN_EXTERN_C() -int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph); +int zend_build_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph); +void zend_analyze_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph); zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, zend_op_array *op_array); int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info); diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index b0a097ed18..96ed33aa97 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -1298,10 +1298,6 @@ static void zend_optimize_op_array(zend_op_array *op_array, zend_redo_pass_two(op_array); if (op_array->live_range) { - if ((ZEND_OPTIMIZER_PASS_6 & ctx->optimization_level) && - (ZEND_OPTIMIZER_PASS_7 & ctx->optimization_level)) { - return; - } zend_recalc_live_ranges(op_array, NULL); } } @@ -1369,28 +1365,9 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend ctx.optimization_level = optimization_level; ctx.debug_level = debug_level; - zend_optimize_op_array(&script->main_op_array, &ctx); - - ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) { - zend_optimize_op_array(op_array, &ctx); - } ZEND_HASH_FOREACH_END(); - - ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { - if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) { - continue; - } - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { - if (op_array->scope == ce - && op_array->type == ZEND_USER_FUNCTION - && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { - zend_optimize_op_array(op_array, &ctx); - } - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FOREACH_END(); - if ((ZEND_OPTIMIZER_PASS_6 & optimization_level) && (ZEND_OPTIMIZER_PASS_7 & optimization_level) && - zend_build_call_graph(&ctx.arena, script, ZEND_RT_CONSTANTS, &call_graph) == SUCCESS) { + zend_build_call_graph(&ctx.arena, script, &call_graph) == SUCCESS) { /* Optimize using call-graph */ void *checkpoint = zend_arena_checkpoint(ctx.arena); int i; @@ -1398,8 +1375,11 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend for (i = 0; i < call_graph.op_arrays_count; i++) { zend_revert_pass_two(call_graph.op_arrays[i]); + zend_optimize(call_graph.op_arrays[i], &ctx); } + zend_analyze_call_graph(&ctx.arena, script, 0, &call_graph); + for (i = 0; i < call_graph.op_arrays_count; i++) { func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (func_info) { @@ -1480,11 +1460,11 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend } zend_arena_release(&ctx.arena, checkpoint); - } else if (ZEND_OPTIMIZER_PASS_12 & optimization_level) { - zend_adjust_fcall_stack_size(&script->main_op_array, &ctx); + } else { + zend_optimize_op_array(&script->main_op_array, &ctx); ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) { - zend_adjust_fcall_stack_size(op_array, &ctx); + zend_optimize_op_array(op_array, &ctx); } ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { @@ -1495,10 +1475,31 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend if (op_array->scope == ce && op_array->type == ZEND_USER_FUNCTION && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { - zend_adjust_fcall_stack_size(op_array, &ctx); + zend_optimize_op_array(op_array, &ctx); } } ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END(); + + if (ZEND_OPTIMIZER_PASS_12 & optimization_level) { + zend_adjust_fcall_stack_size(&script->main_op_array, &ctx); + + ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) { + zend_adjust_fcall_stack_size(op_array, &ctx); + } ZEND_HASH_FOREACH_END(); + + ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { + if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) { + continue; + } + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { + if (op_array->scope == ce + && op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + zend_adjust_fcall_stack_size(op_array, &ctx); + } + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 8c7f1abcc6..6d34b51f4c 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2828,10 +2828,12 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) checkpoint = zend_arena_checkpoint(CG(arena)); call_graph.op_arrays_count = 0; - if (zend_build_call_graph(&CG(arena), script, ZEND_RT_CONSTANTS, &call_graph) != SUCCESS) { + if (zend_build_call_graph(&CG(arena), script, &call_graph) != SUCCESS) { goto jit_failure; } + zend_analyze_call_graph(&CG(arena), script, ZEND_RT_CONSTANTS, &call_graph); + if (zend_jit_trigger == ZEND_JIT_ON_FIRST_EXEC || zend_jit_trigger == ZEND_JIT_ON_PROF_REQUEST || zend_jit_trigger == ZEND_JIT_ON_HOT_COUNTERS) {