1
0
mirror of https://github.com/php/php-src.git synced 2026-04-05 07:02:33 +02:00

Added call-graph analyses

This commit is contained in:
Dmitry Stogov
2015-12-24 14:30:41 +03:00
parent a882d0fd7b
commit b4def0ee88
4 changed files with 66 additions and 16 deletions

View File

@@ -30,10 +30,6 @@
#include "zend_inference.h"
#include "zend_dump.h"
#ifndef HAVE_DFA_PASS
# define HAVE_DFA_PASS 0
#endif
void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
void *checkpoint;
@@ -41,10 +37,6 @@ void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
uint32_t flags = 0;
zend_ssa ssa;
#if !HAVE_DFA_PASS
return;
#endif
/* Build SSA */
memset(&ssa, 0, sizeof(ssa));
checkpoint = zend_arena_checkpoint(ctx->arena);

View File

@@ -28,8 +28,13 @@
#include "zend_vm.h"
#include "zend_cfg.h"
#include "zend_func_info.h"
#include "zend_call_graph.h"
#include "zend_dump.h"
#ifndef HAVE_DFA_PASS
# define HAVE_DFA_PASS 0
#endif
static void zend_optimizer_zval_dtor_wrapper(zval *zvalue)
{
zval_dtor(zvalue);
@@ -606,15 +611,18 @@ static void zend_optimize(zend_op_array *op_array,
}
}
#if HAVE_DFA_PASS
/* pass 6:
* - DFA optimization
*/
if (ZEND_OPTIMIZER_PASS_6 & ctx->optimization_level) {
if ((ZEND_OPTIMIZER_PASS_6 & ctx->optimization_level) &&
!(ZEND_OPTIMIZER_PASS_7 & ctx->optimization_level)) {
optimize_dfa(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_6) {
zend_dump_op_array(op_array, 0, "after pass 6", NULL);
}
}
#endif
/* pass 9:
* - Optimize temp variables usage
@@ -651,12 +659,10 @@ static void zend_optimize(zend_op_array *op_array,
}
}
static void zend_optimize_op_array(zend_op_array *op_array,
zend_optimizer_ctx *ctx)
static void zend_revert_pass_two(zend_op_array *op_array)
{
zend_op *opline, *end;
/* Revert pass_two() */
opline = op_array->opcodes;
end = opline + op_array->last;
while (opline < end) {
@@ -668,11 +674,12 @@ static void zend_optimize_op_array(zend_op_array *op_array,
}
opline++;
}
}
/* Do actual optimizations */
zend_optimize(op_array, ctx);
static void zend_redo_pass_two(zend_op_array *op_array)
{
zend_op *opline, *end;
/* Redo pass_two() */
opline = op_array->opcodes;
end = opline + op_array->last;
while (opline < end) {
@@ -687,6 +694,19 @@ static void zend_optimize_op_array(zend_op_array *op_array,
}
}
static void zend_optimize_op_array(zend_op_array *op_array,
zend_optimizer_ctx *ctx)
{
/* Revert pass_two() */
zend_revert_pass_two(op_array);
/* Do actual optimizations */
zend_optimize(op_array, ctx);
/* Redo pass_two() */
zend_redo_pass_two(op_array);
}
static void zend_adjust_fcall_stack_size(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_function *func;
@@ -714,6 +734,7 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
zend_class_entry *ce;
zend_op_array *op_array;
zend_optimizer_ctx ctx;
zend_call_graph call_graph;
ctx.arena = zend_arena_create(64 * 1024);
ctx.script = script;
@@ -751,6 +772,39 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
}
}
#if HAVE_DFA_PASS
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) {
/* Optimize using call-graph */
uint32_t i;
zend_func_info *func_info;
for (i = 0; i < call_graph.op_arrays_count; i++) {
zend_revert_pass_two(call_graph.op_arrays[i]);
func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]);
if (func_info) {
func_info->ssa.rt_constants = 0;
}
}
for (i = 0; i < call_graph.op_arrays_count; i++) {
optimize_dfa(call_graph.op_arrays[i], &ctx);
}
if (debug_level & ZEND_DUMP_AFTER_PASS_7) {
for (i = 0; i < call_graph.op_arrays_count; i++) {
zend_dump_op_array(call_graph.op_arrays[i], 0, "after pass 7", NULL);
}
}
for (i = 0; i < call_graph.op_arrays_count; i++) {
zend_redo_pass_two(call_graph.op_arrays[i]);
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
}
}
#endif
if (ZEND_OPTIMIZER_PASS_12 & optimization_level) {
zend_adjust_fcall_stack_size(&script->main_op_array, &ctx);

View File

@@ -31,7 +31,7 @@
#define ZEND_OPTIMIZER_PASS_4 (1<<3) /* INIT_FCALL_BY_NAME -> DO_FCALL */
#define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */
#define ZEND_OPTIMIZER_PASS_6 (1<<5) /* DFA based optimization */
#define ZEND_OPTIMIZER_PASS_7 (1<<6)
#define ZEND_OPTIMIZER_PASS_7 (1<<6) /* CALL GRAPH optimization */
#define ZEND_OPTIMIZER_PASS_8 (1<<7)
#define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */
#define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */

View File

@@ -2768,6 +2768,8 @@ file_cache_fallback:
zend_accel_blacklist_load(&accel_blacklist, ZCG(accel_directives.user_blacklist_filename));
}
zend_optimizer_startup();
return SUCCESS;
}
@@ -2785,6 +2787,8 @@ void accel_shutdown(void)
zend_ini_entry *ini_entry;
zend_bool file_cache_only = 0;
zend_optimizer_shutdown();
zend_accel_blacklist_shutdown(&accel_blacklist);
if (!ZCG(enabled) || !accel_startup_ok) {