From: Xinchen Hui Date: Wed, 18 Oct 2017 09:03:07 +0000 (+0800) Subject: Cleanup cfg flags & Added ZEND_FUNC_HAS_EXTENED_INFO X-Git-Tag: php-7.3.0alpha1~1251 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d042d1d8e094fbf7fc4f595542874f37dabd2b83;p=php Cleanup cfg flags & Added ZEND_FUNC_HAS_EXTENED_INFO --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 8d99418efd..fcd20c86fe 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1890,7 +1890,7 @@ void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* Build CFG */ checkpoint = zend_arena_checkpoint(ctx->arena); - if (zend_build_cfg(&ctx->arena, op_array, ZEND_CFG_SPLIT_AT_LIVE_RANGES, &cfg, NULL) != SUCCESS) { + if (zend_build_cfg(&ctx->arena, op_array, ZEND_CFG_SPLIT_AT_LIVE_RANGES, &cfg) != SUCCESS) { zend_arena_release(&ctx->arena, checkpoint); return; } diff --git a/ext/opcache/Optimizer/dce.c b/ext/opcache/Optimizer/dce.c index 5c432c1f94..54a1bad997 100644 --- a/ext/opcache/Optimizer/dce.c +++ b/ext/opcache/Optimizer/dce.c @@ -553,7 +553,7 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reor int removed_ops = 0; /* DCE of CV operations that changes arguments may affect vararg functions. */ - zend_bool has_varargs = ssa->cfg.vararg; + zend_bool has_varargs = (ssa->cfg.flags & ZEND_FUNC_VARARG) != 0; context ctx; ctx.ssa = ssa; diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 733c99ce7a..976cd2d192 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -39,7 +39,7 @@ # include "ssa_integrity.c" #endif -int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, uint32_t *flags) +int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa) { uint32_t build_flags; @@ -51,12 +51,11 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, /* Build SSA */ memset(ssa, 0, sizeof(zend_ssa)); - if (zend_build_cfg(&ctx->arena, op_array, - ZEND_CFG_NO_ENTRY_PREDECESSORS, &ssa->cfg, flags) != SUCCESS) { + if (zend_build_cfg(&ctx->arena, op_array, ZEND_CFG_NO_ENTRY_PREDECESSORS, &ssa->cfg) != SUCCESS) { return FAILURE; } - if (*flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) { + if ((ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS)) { /* TODO: we can't analyze functions with indirect variable access ??? */ return FAILURE; } @@ -75,7 +74,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, } /* Identify reducible and irreducible loops */ - if (zend_cfg_identify_loops(op_array, &ssa->cfg, flags) != SUCCESS) { + if (zend_cfg_identify_loops(op_array, &ssa->cfg) != SUCCESS) { return FAILURE; } @@ -90,7 +89,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, if (ctx->debug_level & ZEND_DUMP_DFA_PHI) { build_flags |= ZEND_SSA_DEBUG_PHI_PLACEMENT; } - if (zend_build_ssa(&ctx->arena, ctx->script, op_array, build_flags, ssa, flags) != SUCCESS) { + if (zend_build_ssa(&ctx->arena, ctx->script, op_array, build_flags, ssa) != SUCCESS) { return FAILURE; } @@ -1189,10 +1188,9 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx void zend_optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx) { void *checkpoint = zend_arena_checkpoint(ctx->arena); - uint32_t flags = 0; zend_ssa ssa; - if (zend_dfa_analyze_op_array(op_array, ctx, &ssa, &flags) != SUCCESS) { + if (zend_dfa_analyze_op_array(op_array, ctx, &ssa) != SUCCESS) { zend_arena_release(&ctx->arena, checkpoint); return; } diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index 2c1c0a7185..a4d4c1b1d5 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -48,7 +48,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc } else { succ->flags |= ZEND_BB_FOLLOW; - if (cfg->split_at_calls) { + if ((cfg->flags & ZEND_CFG_STACKLESS)) { if (opcode == ZEND_INCLUDE_OR_EVAL || opcode == ZEND_GENERATOR_CREATE || opcode == ZEND_YIELD || @@ -59,7 +59,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc succ->flags |= ZEND_BB_ENTRY; } } - if (cfg->split_at_recv) { + if ((cfg->flags & ZEND_CFG_RECV_ENTRY)) { if (opcode == ZEND_RECV || opcode == ZEND_RECV_INIT) { succ->flags |= ZEND_BB_RECV_ENTRY; @@ -149,7 +149,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * b = blocks + block_map[live_range->end]; b->flags |= ZEND_BB_KILL_VAR; if (!(b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE))) { - if (cfg->split_at_live_ranges) { + if ((cfg->flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES)) { changed = 1; zend_mark_reachable(op_array->opcodes, cfg, b); } else { @@ -282,7 +282,7 @@ static void initialize_block(zend_basic_block *block) { block_map[i]++; \ } while (0) -int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg, uint32_t *func_flags) /* {{{ */ +int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg) /* {{{ */ { uint32_t flags = 0; uint32_t i; @@ -294,9 +294,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b zval *zv; zend_bool extra_entry_block = 0; - cfg->split_at_live_ranges = (build_flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES) != 0; - cfg->split_at_calls = (build_flags & ZEND_CFG_STACKLESS) != 0; - cfg->split_at_recv = (build_flags & ZEND_CFG_RECV_ENTRY) != 0; + cfg->flags = build_flags & (ZEND_CFG_SPLIT_AT_LIVE_RANGES|ZEND_CFG_STACKLESS|ZEND_CFG_RECV_ENTRY); cfg->map = block_map = zend_arena_calloc(arena, op_array->last, sizeof(uint32_t)); @@ -304,7 +302,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b BB_START(0); for (i = 0; i < op_array->last; i++) { zend_op *opline = op_array->opcodes + i; - switch(opline->opcode) { + switch (opline->opcode) { case ZEND_RECV: case ZEND_RECV_INIT: if (build_flags & ZEND_CFG_RECV_ENTRY) { @@ -443,6 +441,12 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b case ZEND_FUNC_GET_ARGS: flags |= ZEND_FUNC_VARARG; break; + case ZEND_EXT_NOP: + case ZEND_EXT_STMT: + case ZEND_EXT_FCALL_BEGIN: + case ZEND_EXT_FCALL_END: + flags |= ZEND_FUNC_HAS_EXTENDED_INFO; + break; } } @@ -452,7 +456,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b extra_entry_block = 1; } - if (cfg->split_at_live_ranges) { + if ((cfg->flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES)) { for (j = 0; j < op_array->last_live_range; j++) { BB_START(op_array->live_range[j].start); BB_START(op_array->live_range[j].end); @@ -600,12 +604,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b /* Build CFG, Step 4, Mark Reachable Basic Blocks */ zend_mark_reachable_blocks(op_array, cfg, 0); - cfg->dynamic = (flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0; - cfg->vararg = (flags & ZEND_FUNC_VARARG) != 0; - - if (func_flags) { - *func_flags |= flags; - } + cfg->flags |= flags; return SUCCESS; } @@ -807,7 +806,7 @@ static void swap_blocks(block_info *a, block_info *b) { *b = tmp; } -int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32_t *flags) /* {{{ */ +int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { int i, j, k, n; int time; @@ -913,7 +912,8 @@ int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32 free_alloca(sorted_blocks, sorted_blocks_use_heap); free_alloca(entry_times, tree_use_heap); ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap); - *flags |= flag; + + cfg->flags |= flag; return SUCCESS; } diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h index 90872e2ef1..b7604c9eda 100644 --- a/ext/opcache/Optimizer/zend_cfg.h +++ b/ext/opcache/Optimizer/zend_cfg.h @@ -90,11 +90,7 @@ typedef struct _zend_cfg { zend_basic_block *blocks; /* array of basic blocks */ int *predecessors; uint32_t *map; - unsigned int split_at_live_ranges : 1; - unsigned int split_at_calls : 1; - unsigned int split_at_recv : 1; - unsigned int dynamic : 1; /* accesses varables by name */ - unsigned int vararg : 1; /* uses func_get_args() */ + uint32_t flags; } zend_cfg; /* Build Flags */ @@ -124,11 +120,11 @@ typedef struct _zend_cfg { BEGIN_EXTERN_C() -int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg, uint32_t *func_flags); +int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg); void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg); int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg); int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg); -int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32_t *flags); +int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg); END_EXTERN_C() diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index ac13187624..3910631335 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -895,6 +895,9 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons if (func_flags & ZEND_FUNC_NO_LOOPS) { fprintf(stderr, ", no_loops"); } + if (func_flags & ZEND_FUNC_HAS_EXTENDED_INFO) { + fprintf(stderr, ", extended_info"); + } //TODO: this is useful only for JIT??? #if 0 if (info->flags & ZEND_JIT_FUNC_NO_IN_MEM_CVS) { @@ -972,7 +975,7 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons if (op_array->last_live_range) { fprintf(stderr, "LIVE RANGES:\n"); for (i = 0; i < op_array->last_live_range; i++) { - if (cfg->split_at_live_ranges) { + if ((cfg->flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES)) { fprintf(stderr, " %u: BB%u - BB%u ", EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK), cfg->map[op_array->live_range[i].start], diff --git a/ext/opcache/Optimizer/zend_func_info.h b/ext/opcache/Optimizer/zend_func_info.h index a126bef708..a16285b0f1 100644 --- a/ext/opcache/Optimizer/zend_func_info.h +++ b/ext/opcache/Optimizer/zend_func_info.h @@ -22,14 +22,15 @@ #include "zend_ssa.h" /* func flags */ -#define ZEND_FUNC_INDIRECT_VAR_ACCESS (1<<0) +#define ZEND_FUNC_INDIRECT_VAR_ACCESS (1<<0) /* accesses varables by name */ #define ZEND_FUNC_HAS_CALLS (1<<1) -#define ZEND_FUNC_VARARG (1<<2) +#define ZEND_FUNC_VARARG (1<<2) /* uses func_get_args() */ #define ZEND_FUNC_NO_LOOPS (1<<3) #define ZEND_FUNC_IRREDUCIBLE (1<<4) #define ZEND_FUNC_RECURSIVE (1<<7) #define ZEND_FUNC_RECURSIVE_DIRECTLY (1<<8) #define ZEND_FUNC_RECURSIVE_INDIRECTLY (1<<9) +#define ZEND_FUNC_HAS_EXTENDED_INFO (1<<10) /* The following flags are valid only for return values of internal functions * returned by zend_get_func_info() diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 14a618af7c..1e5b4a2a73 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -1365,7 +1365,8 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend for (i = 0; i < call_graph.op_arrays_count; i++) { func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (func_info) { - zend_dfa_analyze_op_array(call_graph.op_arrays[i], &ctx, &func_info->ssa, &func_info->flags); + zend_dfa_analyze_op_array(call_graph.op_arrays[i], &ctx, &func_info->ssa); + func_info->flags = func_info->ssa.cfg.flags; } } diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index 1ab0fb5c04..9780c3fddb 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -99,7 +99,7 @@ void zend_optimizer_pass3(zend_op_array *op_array); void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx); -int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, uint32_t *flags); +int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa); void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, zend_call_info **call_map); void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimizer_nop_removal(zend_op_array *op_array); diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index fe38d5addf..3083593fd2 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -859,7 +859,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, } /* }}} */ -int zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, uint32_t *func_flags) /* {{{ */ +int zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */ { zend_basic_block *blocks = ssa->cfg.blocks; zend_ssa_block *ssa_blocks; @@ -1115,7 +1115,7 @@ int zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_ /* Mark indirectly accessed variables */ for (i = 0; i < op_array->last_var; i++) { - if (ssa->cfg.dynamic) { + if ((ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS)) { ssa_vars[i].alias = SYMTABLE_ALIAS; } else if (zend_string_equals_literal(op_array->vars[i], "php_errormsg")) { ssa_vars[i].alias = PHP_ERRORMSG_ALIAS; diff --git a/ext/opcache/Optimizer/zend_ssa.h b/ext/opcache/Optimizer/zend_ssa.h index 97be2b93b0..13401fe7ad 100644 --- a/ext/opcache/Optimizer/zend_ssa.h +++ b/ext/opcache/Optimizer/zend_ssa.h @@ -143,7 +143,7 @@ typedef struct _zend_ssa { BEGIN_EXTERN_C() -int zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, uint32_t *func_flags); +int zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa); int zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa); int zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var);