mirror of
https://github.com/php/php-src.git
synced 2025-08-19 08:49:28 +02:00
Improved implementation of NOP removal pass from O(n^2) to O(n) (hnw)
This commit is contained in:
parent
e2aba1cf9e
commit
cb17c99511
1 changed files with 47 additions and 39 deletions
|
@ -558,6 +558,52 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
|
|||
convert_to_string((v)); \
|
||||
}
|
||||
|
||||
static void strip_nop(zend_code_block *block)
|
||||
{
|
||||
zend_op *opline = block->start_opline;
|
||||
zend_op *end, *new_end;
|
||||
int new_len = 0;
|
||||
|
||||
/* remove leading NOPs */
|
||||
while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
|
||||
if (block->len == 1) {
|
||||
/* this block is all NOPs, join with following block */
|
||||
if (block->follow_to) {
|
||||
delete_code_block(block);
|
||||
}
|
||||
return;
|
||||
}
|
||||
block->start_opline++;
|
||||
block->start_opline_no++;
|
||||
block->len--;
|
||||
}
|
||||
|
||||
/* strip the inside NOPs */
|
||||
opline = new_end = block->start_opline;
|
||||
end = opline + block->len;
|
||||
|
||||
while (opline < end) {
|
||||
zend_op *src;
|
||||
int len = 0;
|
||||
|
||||
while (opline < end && opline->opcode == ZEND_NOP) {
|
||||
opline++;
|
||||
}
|
||||
src = opline;
|
||||
|
||||
while (opline < end && opline->opcode != ZEND_NOP) {
|
||||
opline++;
|
||||
}
|
||||
len = opline - src;
|
||||
|
||||
/* move up non-NOP opcodes */
|
||||
memmove(new_end, src, len*sizeof(zend_op));
|
||||
|
||||
new_end += len;
|
||||
}
|
||||
block->len = new_end - block->start_opline;
|
||||
}
|
||||
|
||||
static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, char *used_ext TSRMLS_DC)
|
||||
{
|
||||
zend_op *opline = block->start_opline;
|
||||
|
@ -1168,45 +1214,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
|
|||
opline++;
|
||||
}
|
||||
|
||||
/* remove leading NOPs */
|
||||
while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
|
||||
if (block->len == 1) {
|
||||
/* this block is all NOPs, join with following block */
|
||||
if (block->follow_to) {
|
||||
delete_code_block(block);
|
||||
}
|
||||
if (op_array->T) {
|
||||
efree(Tsource);
|
||||
}
|
||||
return;
|
||||
}
|
||||
block->start_opline++;
|
||||
block->start_opline_no++;
|
||||
block->len--;
|
||||
}
|
||||
|
||||
/* strip the inside NOPs */
|
||||
opline = block->start_opline;
|
||||
end = opline + block->len;
|
||||
while (opline < end) {
|
||||
if (opline->opcode == ZEND_NOP) {
|
||||
zend_op *nop = opline + 1;
|
||||
int noplen;
|
||||
while (nop < end && nop->opcode == ZEND_NOP) {
|
||||
nop++;
|
||||
}
|
||||
noplen = nop-opline;
|
||||
if (nop < end) {
|
||||
/* move up non-NOP opcodes */
|
||||
memmove(opline, nop, (end-nop)*sizeof(zend_op));
|
||||
} else {
|
||||
/* all NOPs up to the end, do nothing */
|
||||
}
|
||||
block->len -= noplen;
|
||||
end = block->start_opline + block->len;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
strip_nop(block);
|
||||
|
||||
if (op_array->T) {
|
||||
efree(Tsource);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue