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)); \
|
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)
|
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;
|
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++;
|
opline++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove leading NOPs */
|
strip_nop(block);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op_array->T) {
|
if (op_array->T) {
|
||||||
efree(Tsource);
|
efree(Tsource);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue