]> granicus.if.org Git - php/commitdiff
Use ZEND_FUNC_FREE_LOOP_VAR flag to avoid useless iterations.
authorDmitry Stogov <dmitry@zend.com>
Mon, 21 Jan 2019 19:18:07 +0000 (22:18 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 21 Jan 2019 19:18:07 +0000 (22:18 +0300)
ext/opcache/Optimizer/scdf.c
ext/opcache/Optimizer/zend_cfg.c
ext/opcache/Optimizer/zend_func_info.h

index 77cfc9715ed1ab3e5620683413594cb38eb61eb4..f3a79338bd00d63af0a5fb4fae5d0070ffa879a8 100644 (file)
@@ -213,6 +213,9 @@ int scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
        int i;
        int removed_ops = 0;
 
+       if (!(ssa->cfg.flags & ZEND_FUNC_FREE_LOOP_VAR)) {
+               return 0;
+       }
        for (i = 0; i < ssa->cfg.blocks_count; i++) {
                if (!zend_bitset_in(scdf->executable_blocks, i)
                                && (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
index 267c39c8ef9c03dfc688e64c66ddc52ea52c6dd2..1bd0a4b5e09a831bc9d397a751b5a373ba511df5 100644 (file)
@@ -110,7 +110,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
        blocks[start].flags = ZEND_BB_START;
        zend_mark_reachable(op_array->opcodes, cfg, blocks + start);
 
-       if (op_array->last_live_range || op_array->last_try_catch) {
+       if (op_array->last_try_catch) {
                zend_basic_block *b;
                int j, changed;
                uint32_t *block_map = cfg->map;
@@ -193,6 +193,12 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
                                }
                        }
                } while (changed);
+       }
+
+       if (cfg->flags & ZEND_FUNC_FREE_LOOP_VAR) {
+               zend_basic_block *b;
+               int j;
+               uint32_t *block_map = cfg->map;
 
                /* Mark blocks that are unreachable, but free a loop var created in a reachable block. */
                for (b = blocks; b < blocks + cfg->blocks_count; b++) {
@@ -417,6 +423,14 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                        case ZEND_EXT_FCALL_END:
                                flags |= ZEND_FUNC_HAS_EXTENDED_INFO;
                                break;
+                       case ZEND_FREE:
+                               if (opline->extended_value == ZEND_FREE_SWITCH) {
+                                       flags |= ZEND_FUNC_FREE_LOOP_VAR;
+                               }
+                               break;
+                       case ZEND_FE_FREE:
+                               flags |= ZEND_FUNC_FREE_LOOP_VAR;
+                               break;
                }
        }
 
index 45d38ddc2cd730b8a55c279999a35b8606743421..656cc59fad8de05bfe06f53a045c0c5a8cf636f6 100644 (file)
@@ -27,6 +27,7 @@
 #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_FREE_LOOP_VAR            (1<<5)
 #define ZEND_FUNC_RECURSIVE                (1<<7)
 #define ZEND_FUNC_RECURSIVE_DIRECTLY       (1<<8)
 #define ZEND_FUNC_RECURSIVE_INDIRECTLY     (1<<9)