From cafe78d12aa2db789f141dd41cf16268ddcab76f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 24 Apr 2016 17:04:22 +0200 Subject: [PATCH] Introduce ZEND_BITSET_FOREACH macros --- Zend/zend_bitset.h | 27 ++++++++++ ext/opcache/Optimizer/zend_ssa.c | 90 +++++++++++++++----------------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/Zend/zend_bitset.h b/Zend/zend_bitset.h index e3c2ec748d..fb19b54329 100644 --- a/Zend/zend_bitset.h +++ b/Zend/zend_bitset.h @@ -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_ */ /* diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index b75ae5c576..c8992a601f 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -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(); } } } -- 2.50.1