diff options
author | Dmitry Stogov <dmitry@zend.com> | 2020-10-13 00:18:17 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2020-10-13 00:18:17 +0300 |
commit | 87beb22ff80a1d994cda6a551e626ddcbb063abb (patch) | |
tree | 518d33605f971cc4c96830b054e2dc0a959b5f03 | |
parent | 8d4774a2df4e16679c9176e2b6edecc94283af6d (diff) | |
download | php-git-87beb22ff80a1d994cda6a551e626ddcbb063abb.tar.gz |
Perform trace range propagation
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 8 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.h | 1 | ||||
-rw-r--r-- | ext/opcache/jit/zend_jit_trace.c | 35 |
3 files changed, 43 insertions, 1 deletions
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index c306da2726..1dbbeb97f0 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -843,7 +843,6 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int uint32_t line; zend_op *opline; zend_ssa_op *ssa_op; - zend_long op1_min, op2_min, op1_max, op2_max; if (ssa->vars[var].definition_phi) { zend_ssa_phi *p = ssa->vars[var].definition_phi; @@ -984,6 +983,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int opline = op_array->opcodes + line; ssa_op = &ssa->ops[line]; + return zend_inference_propagate_range(op_array, ssa, opline, ssa_op, var, tmp); +} + +int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp) +{ + zend_long op1_min, op2_min, op1_max, op2_max; + tmp->underflow = 0; tmp->overflow = 0; switch (opline->opcode) { diff --git a/ext/opcache/Optimizer/zend_inference.h b/ext/opcache/Optimizer/zend_inference.h index 2bd120c882..6b1021a4cc 100644 --- a/ext/opcache/Optimizer/zend_inference.h +++ b/ext/opcache/Optimizer/zend_inference.h @@ -257,6 +257,7 @@ int zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const uint32_t zend_array_element_type(uint32_t t1, zend_uchar op_type, int write, int insert); int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp); +int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp); void zend_inference_init_range(const zend_op_array *op_array, zend_ssa *ssa, int var, zend_bool underflow, zend_long min, zend_long max, zend_bool overflow); int zend_inference_narrowing_meet(zend_ssa_var_info *var_info, zend_ssa_range *r); int zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_range *r); diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 8343340cb3..598815dfe3 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -5270,6 +5270,8 @@ done: } if (ssa_op) { + zend_ssa_range tmp; + /* Keep information about known types on abstract stack */ if (ssa_op->result_def >= 0) { zend_uchar type = IS_UNKNOWN; @@ -5323,6 +5325,15 @@ done: } } } + + if (type == IS_LONG + && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->result_def, &tmp)) { + ssa->var_info[ssa_op->result_def].range.min = tmp.min; + ssa->var_info[ssa_op->result_def].range.max = tmp.max; + ssa->var_info[ssa_op->result_def].range.underflow = 0; + ssa->var_info[ssa_op->result_def].range.overflow = 0; + ssa->var_info[ssa_op->result_def].has_range = 1; + } } if (ssa_op->op1_def >= 0) { zend_uchar type = IS_UNKNOWN; @@ -5357,6 +5368,14 @@ done: ra[ssa_op->op1_def]->flags & ZREG_STORE); } } + if (type == IS_LONG + && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op1_def, &tmp)) { + ssa->var_info[ssa_op->op1_def].range.min = tmp.min; + ssa->var_info[ssa_op->op1_def].range.max = tmp.max; + ssa->var_info[ssa_op->op1_def].range.underflow = 0; + ssa->var_info[ssa_op->op1_def].range.overflow = 0; + ssa->var_info[ssa_op->op1_def].has_range = 1; + } } if (ssa_op->op2_def >= 0) { zend_uchar type = IS_UNKNOWN; @@ -5377,6 +5396,14 @@ done: ra[ssa_op->op2_def]->flags & ZREG_STORE); } } + if (type == IS_LONG + && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op2_def, &tmp)) { + ssa->var_info[ssa_op->op2_def].range.min = tmp.min; + ssa->var_info[ssa_op->op2_def].range.max = tmp.max; + ssa->var_info[ssa_op->op2_def].range.underflow = 0; + ssa->var_info[ssa_op->op2_def].range.overflow = 0; + ssa->var_info[ssa_op->op2_def].has_range = 1; + } } switch (opline->opcode) { @@ -5412,6 +5439,14 @@ done: ra[ssa_op->op1_def]->reg & ZREG_STORE); } } + if (type == IS_LONG + && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op1_def, &tmp)) { + ssa->var_info[ssa_op->op1_def].range.min = tmp.min; + ssa->var_info[ssa_op->op1_def].range.max = tmp.max; + ssa->var_info[ssa_op->op1_def].range.underflow = 0; + ssa->var_info[ssa_op->op1_def].range.overflow = 0; + ssa->var_info[ssa_op->op1_def].has_range = 1; + } } ssa_op++; break; |