Skip to content

Commit 865b096

Browse files
committed
Implement range inference for traces
1 parent aaa1450 commit 865b096

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,22 @@ static int zend_jit_trace_copy_ssa_var_info(const zend_op_array *op_array, const
795795
return 0;
796796
}
797797

798-
static int zend_jit_trace_copy_ssa_var_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op **tssa_opcodes, zend_ssa *tssa, int ssa_var)
798+
static void zend_jit_trace_propagate_range(const zend_op_array *op_array, const zend_op **tssa_opcodes, zend_ssa *tssa, int ssa_var)
799+
{
800+
zend_ssa_range tmp;
801+
int def = tssa->vars[ssa_var].definition;
802+
803+
if (tssa->vars[ssa_var].alias == NO_ALIAS
804+
&& zend_inference_propagate_range(op_array, tssa, (zend_op*)tssa_opcodes[def], (zend_ssa_op*)&tssa->ops[def], ssa_var, &tmp)) {
805+
tssa->var_info[ssa_var].range.min = tmp.min;
806+
tssa->var_info[ssa_var].range.max = tmp.max;
807+
tssa->var_info[ssa_var].range.underflow = tmp.underflow;
808+
tssa->var_info[ssa_var].range.overflow = tmp.overflow;
809+
tssa->var_info[ssa_var].has_range = 1;
810+
}
811+
}
812+
813+
static void zend_jit_trace_copy_ssa_var_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op **tssa_opcodes, zend_ssa *tssa, int ssa_var)
799814
{
800815
int def;
801816
zend_ssa_op *op;
@@ -821,12 +836,16 @@ static int zend_jit_trace_copy_ssa_var_range(const zend_op_array *op_array, cons
821836
info = ssa->var_info + op->result_def;
822837
} else {
823838
assert(0);
824-
return 0;
839+
return;
825840
}
826841

827842
tssa->vars[ssa_var].no_val = no_val;
828843
tssa->vars[ssa_var].alias = alias;
829844

845+
if (!(info->type & MAY_BE_REF)) {
846+
zend_jit_trace_propagate_range(op_array, tssa_opcodes, tssa, ssa_var);
847+
}
848+
830849
if (info->has_range) {
831850
if (tssa->var_info[ssa_var].has_range) {
832851
tssa->var_info[ssa_var].range.min = MAX(tssa->var_info[ssa_var].range.min, info->range.min);
@@ -838,9 +857,7 @@ static int zend_jit_trace_copy_ssa_var_range(const zend_op_array *op_array, cons
838857
tssa->var_info[ssa_var].range = info->range;
839858
}
840859
}
841-
return 1;
842860
}
843-
return 0;
844861
}
845862

846863
static int zend_jit_trace_restrict_ssa_var_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op **tssa_opcodes, zend_ssa *tssa, int ssa_var)
@@ -1507,7 +1524,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
15071524
// zend_class_entry *op1_ce = NULL;
15081525
zend_class_entry *op2_ce = NULL;
15091526

1510-
// TODO: range inference ???
15111527
opline = p->opline;
15121528

15131529
op1_type = orig_op1_type = p->op1_type;
@@ -1925,22 +1941,40 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
19251941
} else {
19261942
if (ssa_ops[idx].op1_def >= 0) {
19271943
ssa_vars[ssa_ops[idx].op1_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->op1.var));
1944+
if (ssa_ops[idx].op1_use < 0 || !(ssa_var_info[ssa_ops[idx].op1_use].type & MAY_BE_REF)) {
1945+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].op1_def);
1946+
}
19281947
}
19291948
if (ssa_ops[idx].op2_def >= 0) {
19301949
ssa_vars[ssa_ops[idx].op2_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->op2.var));
1950+
if (ssa_ops[idx].op2_use < 0 || !(ssa_var_info[ssa_ops[idx].op2_use].type & MAY_BE_REF)) {
1951+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].op2_def);
1952+
}
19311953
}
19321954
if (ssa_ops[idx].result_def >= 0) {
19331955
ssa_vars[ssa_ops[idx].result_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->result.var));
1956+
if (ssa_ops[idx].result_use < 0 || !(ssa_var_info[ssa_ops[idx].result_use].type & MAY_BE_REF)) {
1957+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].result_def);
1958+
}
19341959
}
19351960
if (len == 2 && (opline+1)->opcode == ZEND_OP_DATA) {
19361961
if (ssa_ops[idx+1].op1_def >= 0) {
19371962
ssa_vars[ssa_ops[idx+1].op1_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM((opline+1)->op1.var));
1963+
if (ssa_ops[idx+1].op1_use < 0 || !(ssa_var_info[ssa_ops[idx+1].op1_use].type & MAY_BE_REF)) {
1964+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx+1].op1_def);
1965+
}
19381966
}
19391967
if (ssa_ops[idx+1].op2_def >= 0) {
19401968
ssa_vars[ssa_ops[idx+1].op2_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM((opline+1)->op2.var));
1969+
if (ssa_ops[idx+1].op2_use < 0 || !(ssa_var_info[ssa_ops[idx+1].op2_use].type & MAY_BE_REF)) {
1970+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx+1].op2_def);
1971+
}
19411972
}
19421973
if (ssa_ops[idx+1].result_def >= 0) {
19431974
ssa_vars[ssa_ops[idx+1].result_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM((opline+1)->result.var));
1975+
if (ssa_ops[idx+1].result_use < 0 || !(ssa_var_info[ssa_ops[idx+1].result_use].type & MAY_BE_REF)) {
1976+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx+1].result_def);
1977+
}
19441978
}
19451979
}
19461980
}
@@ -2004,12 +2038,21 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
20042038
} else {
20052039
if (ssa_ops[idx].op1_def >= 0) {
20062040
ssa_vars[ssa_ops[idx].op1_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->op1.var));
2041+
if (ssa_ops[idx].op1_use < 0 || !(ssa_var_info[ssa_ops[idx].op1_use].type & MAY_BE_REF)) {
2042+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].op1_def);
2043+
}
20072044
}
20082045
if (ssa_ops[idx].op2_def >= 0) {
20092046
ssa_vars[ssa_ops[idx].op2_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->op2.var));
2047+
if (ssa_ops[idx].op2_use < 0 || !(ssa_var_info[ssa_ops[idx].op2_use].type & MAY_BE_REF)) {
2048+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].op2_def);
2049+
}
20102050
}
20112051
if (ssa_ops[idx].result_def >= 0) {
20122052
ssa_vars[ssa_ops[idx].result_def].alias = zend_jit_var_may_alias(op_array, ssa, EX_VAR_TO_NUM(opline->result.var));
2053+
if (ssa_ops[idx].result_use < 0 || !(ssa_var_info[ssa_ops[idx].result_use].type & MAY_BE_REF)) {
2054+
zend_jit_trace_propagate_range(op_array, ssa_opcodes, tssa, ssa_ops[idx].result_def);
2055+
}
20132056
}
20142057
}
20152058
if (opline->opcode == ZEND_RECV_INIT

0 commit comments

Comments
 (0)