]> granicus.if.org Git - php/commitdiff
Perform trace range propagation
authorDmitry Stogov <dmitry@zend.com>
Mon, 12 Oct 2020 21:18:17 +0000 (00:18 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 12 Oct 2020 21:18:17 +0000 (00:18 +0300)
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_inference.h
ext/opcache/jit/zend_jit_trace.c

index c306da272637cc6a06dfad03f87eae0835723b4b..1dbbeb97f092a7eb0aa384bcda6418feb8affee9 100644 (file)
@@ -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) {
index 2bd120c882fbeeef00fbe5888d25f5715dbb12ce..6b1021a4cce8837f95084fecddaf1c9a7e91ca80 100644 (file)
@@ -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);
index 8343340cb3ab1176738f290b49e4a89c736ddbf0..598815dfe3e1b581431033258576d8f73d07259a 100644 (file)
@@ -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;