]> granicus.if.org Git - php/commitdiff
Introduce ZEND_BITSET_FOREACH macros
authorNikita Popov <nikic@php.net>
Sun, 24 Apr 2016 15:04:22 +0000 (17:04 +0200)
committerNikita Popov <nikic@php.net>
Sun, 24 Apr 2016 15:05:13 +0000 (17:05 +0200)
Zend/zend_bitset.h
ext/opcache/Optimizer/zend_ssa.c

index e3c2ec748d5236d2ddd47d4c2ba159c2667c3f04..fb19b54329427cbab1b64e778968a99ad62e7c10 100644 (file)
@@ -174,6 +174,33 @@ static inline int zend_bitset_last(zend_bitset set, uint32_t len)
        return -1; /* empty set */
 }
 
+#define ZEND_BITSET_FOREACH(set, len, bit) do { \
+       zend_bitset _set = (set); \
+       uint32_t _i, _len = (len); \
+       for (_i = 0; _i < len; _i++) { \
+               zend_ulong _x = _set[_i]; \
+               if (_x) { \
+                       (bit) = ZEND_BITSET_ELM_SIZE * 8 * _i; \
+                       for (; _x != 0; _x >>= Z_UL(1), (bit)++) { \
+                               if (!(_x & Z_UL(1))) continue;
+
+#define ZEND_BITSET_REVERSE_FOREACH(set, len, bit) do { \
+       zend_bitset _set = (set); \
+       uint32_t _i = (len); \
+       zend_ulong _test = Z_UL(1) << (ZEND_BITSET_ELM_SIZE * 8 - 1); \
+       while (_i-- > 0) { \
+               zend_ulong _x = _set[_i]; \
+               if (_x) { \
+                       (bit) = ZEND_BITSET_ELM_SIZE * 8 * (_i + 1) - 1; \
+                       for (; _x != 0; _x <<= Z_UL(1), (bit)--) { \
+                               if (!(_x & _test)) continue; \
+
+#define ZEND_BITSET_FOREACH_END() \
+                       } \
+               } \
+       } \
+} while (0)
+
 #endif /* _ZEND_BITSET_H_ */
 
 /*
index b75ae5c576bb40d5951f0bbe54721ef81e47eda8..c8992a601f0c52a95a78af400f2c11c18efafabf 100644 (file)
@@ -856,29 +856,25 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                        }
 
                        if (!zend_bitset_empty(tmp, set_size)) {
-                               i = op_array->last_var + op_array->T;
-                               while (i > 0) {
-                                       i--;
-                                       if (zend_bitset_in(tmp, i)) {
-                                               zend_ssa_phi *phi = zend_arena_calloc(arena, 1,
-                                                       sizeof(zend_ssa_phi) +
-                                                       sizeof(int) * blocks[j].predecessors_count +
-                                                       sizeof(void*) * blocks[j].predecessors_count);
+                               ZEND_BITSET_REVERSE_FOREACH(tmp, set_size, i) {
+                                       zend_ssa_phi *phi = zend_arena_calloc(arena, 1,
+                                               sizeof(zend_ssa_phi) +
+                                               sizeof(int) * blocks[j].predecessors_count +
+                                               sizeof(void*) * blocks[j].predecessors_count);
 
-                                               if (!phi) {
-                                                       goto failure;
-                                               }
-                                               phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
-                                               memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
-                                               phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
-
-                                           phi->pi = -1;
-                                               phi->var = i;
-                                               phi->ssa_var = -1;
-                                               phi->next = ssa_blocks[j].phis;
-                                               ssa_blocks[j].phis = phi;
+                                       if (!phi) {
+                                               goto failure;
                                        }
-                               }
+                                       phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
+                                       memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
+                                       phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
+
+                                       phi->pi = -1;
+                                       phi->var = i;
+                                       phi->ssa_var = -1;
+                                       phi->next = ssa_blocks[j].phis;
+                                       ssa_blocks[j].phis = phi;
+                               } ZEND_BITSET_FOREACH_END();
                        }
                }
        }
@@ -921,38 +917,34 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                        }
 
                        if (!zend_bitset_empty(tmp, set_size)) {
-                               i = op_array->last_var + op_array->T;
-                               while (i > 0) {
-                                       i--;
-                                       if (zend_bitset_in(tmp, i)) {
-                                               zend_ssa_phi **pp = &ssa_blocks[j].phis;
-                                               while (*pp) {
-                                                       if ((*pp)->pi <= 0 && (*pp)->var == i) {
-                                                               break;
-                                                       }
-                                                       pp = &(*pp)->next;
+                               ZEND_BITSET_REVERSE_FOREACH(tmp, set_size, i) {
+                                       zend_ssa_phi **pp = &ssa_blocks[j].phis;
+                                       while (*pp) {
+                                               if ((*pp)->pi <= 0 && (*pp)->var == i) {
+                                                       break;
                                                }
-                                               if (*pp == NULL) {
-                                                       zend_ssa_phi *phi = zend_arena_calloc(arena, 1,
-                                                               sizeof(zend_ssa_phi) +
-                                                               sizeof(int) * blocks[j].predecessors_count +
-                                                               sizeof(void*) * blocks[j].predecessors_count);
-
-                                                       if (!phi) {
-                                                               goto failure;
-                                                       }
-                                                       phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
-                                                       memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
-                                                       phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
+                                               pp = &(*pp)->next;
+                                       }
+                                       if (*pp == NULL) {
+                                               zend_ssa_phi *phi = zend_arena_calloc(arena, 1,
+                                                       sizeof(zend_ssa_phi) +
+                                                       sizeof(int) * blocks[j].predecessors_count +
+                                                       sizeof(void*) * blocks[j].predecessors_count);
 
-                                                   phi->pi = -1;
-                                                       phi->var = i;
-                                                       phi->ssa_var = -1;
-                                                       phi->next = NULL;
-                                                       *pp = phi;
+                                               if (!phi) {
+                                                       goto failure;
                                                }
+                                               phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi));
+                                               memset(phi->sources, 0xff, sizeof(int) * blocks[j].predecessors_count);
+                                               phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[j].predecessors_count);
+
+                                               phi->pi = -1;
+                                               phi->var = i;
+                                               phi->ssa_var = -1;
+                                               phi->next = NULL;
+                                               *pp = phi;
                                        }
-                               }
+                               } ZEND_BITSET_FOREACH_END();
                        }
                }
        }