]> granicus.if.org Git - php/commitdiff
Revert/redo pass_two only once
authorDmitry Stogov <dmitry@zend.com>
Thu, 10 Oct 2019 20:20:36 +0000 (23:20 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 10 Oct 2019 20:20:36 +0000 (23:20 +0300)
ext/opcache/Optimizer/zend_call_graph.c
ext/opcache/Optimizer/zend_call_graph.h
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/jit/zend_jit.c

index 8d677c1b86beb226cc0cadf2e9e41e281cf93bb1..a98dd99d35597ec810f530d30f493246500420dd 100644 (file)
@@ -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;
 }
 /* }}} */
 
index 033c675b63482379066ac9b10901b0690e2b58b9..cfad3358fdfdd6024a1cbd399bfccb364962ff62 100644 (file)
@@ -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);
 
index b0a097ed188cd5a7ca1cca71e09d19982ca7c9ea..96ed33aa9790fb26b87933d05fc744890c10d5c0 100644 (file)
@@ -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) {
index 8c7f1abcc65eba6e785f439a29b7a364a0179ffc..6d34b51f4c17d638faead32382b646c0661116df 100644 (file)
@@ -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) {