Skip to content

Commit acffb7a

Browse files
committed
Keep information about SSA variables, that may be modified indirectly.
1 parent 6164ec9 commit acffb7a

File tree

5 files changed

+35
-15
lines changed

5 files changed

+35
-15
lines changed

ext/opcache/Optimizer/zend_cfg.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
598598
/* Build CFG, Step 4, Mark Reachable Basic Blocks */
599599
zend_mark_reachable_blocks(op_array, cfg, 0);
600600

601+
cfg->dynamic = (flags & ZEND_FUNC_INDIRECT_VAR_ACCESS);
602+
601603
if (func_flags) {
602604
*func_flags |= flags;
603605
}

ext/opcache/Optimizer/zend_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ typedef struct _zend_cfg {
9292
unsigned int split_at_live_ranges : 1;
9393
unsigned int split_at_calls : 1;
9494
unsigned int split_at_recv : 1;
95+
unsigned int dynamic : 1; /* accesses varables by name */
9596
} zend_cfg;
9697

9798
/* Build Flags */

ext/opcache/Optimizer/zend_inference.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3835,21 +3835,14 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
38353835
/* Narrowing integer initialization to doubles */
38363836
zend_type_narrowing(op_array, script, ssa);
38373837

3838-
for (j = 0; j < op_array->last_var; j++) {
3839-
/* $php_errormsg and $http_response_header may be updated indirectly */
3840-
if (zend_string_equals_literal(op_array->vars[j], "php_errormsg")) {
3841-
int i;
3842-
for (i = 0; i < ssa_vars_count; i++) {
3843-
if (ssa->vars[i].var == j) {
3844-
ssa_var_info[i].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3845-
}
3846-
}
3847-
} else if (zend_string_equals_literal(op_array->vars[j], "http_response_header")) {
3848-
int i;
3849-
for (i = 0; i < ssa_vars_count; i++) {
3850-
if (ssa->vars[i].var == j) {
3851-
ssa_var_info[i].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3852-
}
3838+
for (j = 0; j < ssa_vars_count; j++) {
3839+
if (ssa->vars[j].alias) {
3840+
if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
3841+
ssa_var_info[j].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3842+
} else if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
3843+
ssa_var_info[j].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3844+
} else {
3845+
ssa_var_info[j].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
38533846
}
38543847
}
38553848
}

ext/opcache/Optimizer/zend_ssa.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,22 @@ int zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_
11001100
}
11011101
}
11021102

1103+
/* Mark indirectly accessed variables */
1104+
for (i = 0; i < op_array->last_var; i++) {
1105+
if (ssa->cfg.dynamic) {
1106+
ssa_vars[i].alias = SYMTABLE_ALIAS;
1107+
} else if (zend_string_equals_literal(op_array->vars[i], "php_errormsg")) {
1108+
ssa_vars[i].alias = PHP_ERRORMSG_ALIAS;
1109+
} else if (zend_string_equals_literal(op_array->vars[i], "http_response_header")) {
1110+
ssa_vars[i].alias = HTTP_RESPONSE_HEADER_ALIAS;
1111+
}
1112+
}
1113+
for (i = op_array->last_var; i < ssa->vars_count; i++) {
1114+
if (ssa_vars[i].var < op_array->last_var) {
1115+
ssa_vars[i].alias = ssa_vars[ssa_vars[i].var].alias;
1116+
}
1117+
}
1118+
11031119
return SUCCESS;
11041120
}
11051121
/* }}} */

ext/opcache/Optimizer/zend_ssa.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ typedef struct _zend_ssa_op {
9292
int res_use_chain;
9393
} zend_ssa_op;
9494

95+
typedef enum _zend_ssa_alias_kind {
96+
NO_ALIAS,
97+
SYMTABLE_ALIAS,
98+
PHP_ERRORMSG_ALIAS,
99+
HTTP_RESPONSE_HEADER_ALIAS
100+
} zend_ssa_alias_kind;
101+
95102
typedef struct _zend_ssa_var {
96103
int var; /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
97104
int scc; /* strongly connected component */
@@ -102,6 +109,7 @@ typedef struct _zend_ssa_var {
102109
zend_ssa_phi *sym_use_chain; /* uses of this value in Pi constaints */
103110
unsigned int no_val : 1; /* value doesn't mater (used as op1 in ZEND_ASSIGN) */
104111
unsigned int scc_entry : 1;
112+
zend_ssa_alias_kind alias : 2; /* value may be changed indirectly */
105113
} zend_ssa_var;
106114

107115
typedef struct _zend_ssa_var_info {

0 commit comments

Comments
 (0)