]> granicus.if.org Git - php/commitdiff
Cleanup cfg flags & Added ZEND_FUNC_HAS_EXTENED_INFO
authorXinchen Hui <laruence@gmail.com>
Wed, 18 Oct 2017 09:03:07 +0000 (17:03 +0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 18 Oct 2017 09:03:07 +0000 (17:03 +0800)
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/dce.c
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/Optimizer/zend_cfg.c
ext/opcache/Optimizer/zend_cfg.h
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_func_info.h
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/Optimizer/zend_optimizer_internal.h
ext/opcache/Optimizer/zend_ssa.c
ext/opcache/Optimizer/zend_ssa.h

index 8d99418efdaf7ab1e13ba712aeaf216cbe1960af..fcd20c86fe1048524252ad3e6b01eb038c7b3f73 100644 (file)
@@ -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;
        }
index 5c432c1f94ce9bce30c262a078dbe9ae7b7ce4b4..54a1bad99793e80c2c8c8929301be096cb1bb4cd 100644 (file)
@@ -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;
index 733c99ce7a813959920582cf8e17628e65f7e07e..976cd2d192a321cc80e71b7a5552b7ccf7e99bb6 100644 (file)
@@ -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;
        }
index 2c1c0a71853418d66c8156d1c1f7db397a8a3e4a..a4d4c1b1d55882413c0514c62473deeae83b4a39 100644 (file)
@@ -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;
 }
index 90872e2ef191948c33a9d6b7434cc3846b797106..b7604c9edaabf677647f98a033d75094a356b04a 100644 (file)
@@ -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()
 
index ac1318762485e7572222ab005181be6fcaaab427..3910631335932e197c8de5e4a56183147e493204 100644 (file)
@@ -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],
index a126bef708173963d3d2a60dd478537bd3f5a3db..a16285b0f166d80b4a8137b5c18467e469d02d10 100644 (file)
 #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()
index 14a618af7c836a8f3acf9bbd2fa68455cab37797..1e5b4a2a7358d908b4a6e1c1a21a5859638c43a2 100644 (file)
@@ -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;
                        }
                }
 
index 1ab0fb5c040974d773a766941c33045a2bbc9067..9780c3fddb98cf4ef05f7b9aef3f751b6af666bb 100644 (file)
@@ -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);
index fe38d5addfc823c954d07318983342ec99a52192..3083593fd282f7ba6a3e9061705a7eeef23cecec 100644 (file)
@@ -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;
index 97be2b93b0b2970b0dfaecac856b1f186f0bd396..13401fe7ad060c04d56cfdd3c8f718dad88e1f87 100644 (file)
@@ -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);