summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_ssa.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-06-07 21:52:47 +0200
committerNikita Popov <nikic@php.net>2016-06-13 19:03:59 +0200
commit046889518d1e25a6aff858b28fddf05246bfd99f (patch)
tree700208e0b096eb1f08785ed7fee471b1b23f8812 /ext/opcache/Optimizer/zend_ssa.c
parent9877d8f019cc0c1070fc963419029f4faf00b34a (diff)
downloadphp-git-046889518d1e25a6aff858b28fddf05246bfd99f.tar.gz
Add support for "instanceof" pi nodes
Diffstat (limited to 'ext/opcache/Optimizer/zend_ssa.c')
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index 9e585f4536..6f1fff961c 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -139,6 +139,7 @@ static inline void pi_range_max(zend_ssa_phi *phi, int var, zend_long val) {
static void pi_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
phi->has_range_constraint = 0;
+ phi->constraint.type.ce = NULL;
phi->constraint.type.type_mask = MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN;
phi->constraint.type.type_mask |= type_mask;
if (type_mask & MAY_BE_NULL) {
@@ -222,8 +223,8 @@ static inline zend_bool sub_will_overflow(zend_long a, zend_long b) {
* Order of Phis is importent, Pis must be placed before Phis
*/
static void place_essa_pis(
- zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa,
- zend_dfg *dfg) /* {{{ */ {
+ zend_arena **arena, const zend_script *script, const zend_op_array *op_array,
+ uint32_t build_flags, zend_ssa *ssa, zend_dfg *dfg) /* {{{ */ {
zend_basic_block *blocks = ssa->cfg.blocks;
int j, blocks_count = ssa->cfg.blocks_count;
for (j = 0; j < blocks_count; j++) {
@@ -485,6 +486,23 @@ static void place_essa_pis(
pi_not_type_mask(pi, type_mask);
}
}
+ } else if (opline->op1_type == IS_TMP_VAR && (opline-1)->opcode == ZEND_INSTANCEOF &&
+ opline->op1.var == (opline-1)->result.var && (opline-1)->op1_type == IS_CV &&
+ (opline-1)->op2_type == IS_CONST) {
+ int var = EX_VAR_TO_NUM((opline-1)->op1.var);
+ zend_string *lcname = Z_STR_P(CRT_CONSTANT((opline-1)->op2) + 1);
+ zend_class_entry *ce = zend_hash_find_ptr(&script->class_table, lcname);
+ if (!ce) {
+ ce = zend_hash_find_ptr(CG(class_table), lcname);
+ if (!ce || ce->type != ZEND_INTERNAL_CLASS) {
+ continue;
+ }
+ }
+
+ if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
+ pi_type_mask(pi, MAY_BE_OBJECT);
+ pi->constraint.type.ce = ce;
+ }
}
}
}
@@ -806,7 +824,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
}
/* }}} */
-int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, uint32_t *func_flags) /* {{{ */
+int zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, uint32_t *func_flags) /* {{{ */
{
zend_basic_block *blocks = ssa->cfg.blocks;
zend_ssa_block *ssa_blocks;
@@ -854,7 +872,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
/* Place e-SSA pis. This will add additional "def" points, so it must
* happen before def propagation. */
- place_essa_pis(arena, op_array, build_flags, ssa, &dfg);
+ place_essa_pis(arena, script, op_array, build_flags, ssa, &dfg);
/* SSA construction, Step 1: Propagate "def" sets in merge points */
do {