Skip to content

Commit ae1132b

Browse files
committed
Remove unused temporaries from taken map
If the result has no uses we need to allocate it when visiting the defining instruction. However, we should still go through the logic to remove the temporary from the taken map afterwards, as the temporary can still be reused prior to the defining instruction.
1 parent 517c01b commit ae1132b

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

Zend/Optimizer/optimize_temp_vars_5.c

+17-21
Original file line numberDiff line numberDiff line change
@@ -150,31 +150,27 @@ void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_c
150150

151151
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
152152
currT = VAR_NUM(opline->result.var) - offset;
153-
if (zend_bitset_in(valid_T, currT)) {
154-
if (start_of_T[currT] == opline) {
155-
/* ZEND_FAST_CALL can not share temporary var with others
156-
* since the fast_var could also be set by ZEND_HANDLE_EXCEPTION
157-
* which could be ahead of it */
158-
if (opline->opcode != ZEND_FAST_CALL) {
159-
zend_bitset_excl(taken_T, map_T[currT]);
160-
}
153+
if (!zend_bitset_in(valid_T, currT)) {
154+
/* As a result of DCE, an opcode may have an unused result. */
155+
GET_AVAILABLE_T();
156+
map_T[currT] = i;
157+
zend_bitset_incl(valid_T, currT);
158+
}
159+
opline->result.var = NUM_VAR(map_T[currT] + offset);
160+
if (start_of_T[currT] == opline) {
161+
/* ZEND_FAST_CALL can not share temporary var with others
162+
* since the fast_var could also be set by ZEND_HANDLE_EXCEPTION
163+
* which could be ahead of it */
164+
if (opline->opcode != ZEND_FAST_CALL) {
165+
zend_bitset_excl(taken_T, map_T[currT]);
161166
}
162-
opline->result.var = NUM_VAR(map_T[currT] + offset);
163167
if (opline->opcode == ZEND_ROPE_INIT) {
164-
if (start_of_T[currT] == opline) {
165-
uint32_t num = ((opline->extended_value * sizeof(zend_string*)) + (sizeof(zval) - 1)) / sizeof(zval);
166-
while (num > 1) {
167-
num--;
168-
zend_bitset_excl(taken_T, map_T[currT]+num);
169-
}
168+
uint32_t num = ((opline->extended_value * sizeof(zend_string*)) + (sizeof(zval) - 1)) / sizeof(zval);
169+
while (num > 1) {
170+
num--;
171+
zend_bitset_excl(taken_T, map_T[currT]+num);
170172
}
171173
}
172-
} else {
173-
/* Code which gets here is using a wrongly built opcode such as RECV() */
174-
GET_AVAILABLE_T();
175-
map_T[currT] = i;
176-
zend_bitset_incl(valid_T, currT);
177-
opline->result.var = NUM_VAR(i + offset);
178174
}
179175
}
180176

0 commit comments

Comments
 (0)