@@ -1067,11 +1067,10 @@ static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ss
1067
1067
}
1068
1068
1069
1069
/* Sets a flag on SEND ops when a copy can be a avoided. */
1070
- static void zend_dfa_optimize_send_copies (zend_op_array * op_array , zend_ssa * ssa )
1070
+ static void zend_dfa_optimize_send_copies (zend_op_array * op_array , zend_ssa * ssa , zend_call_info * * call_map )
1071
1071
{
1072
1072
for (int v = 0 ; v < ssa -> vars_count ; v ++ ) {
1073
- int var = ssa -> vars [v ].var ;
1074
- if (var >= op_array -> last_var ) {
1073
+ if (ssa -> vars [v ].var >= op_array -> last_var ) {
1075
1074
continue ;
1076
1075
}
1077
1076
@@ -1080,33 +1079,21 @@ static void zend_dfa_optimize_send_copies(zend_op_array *op_array, zend_ssa *ssa
1080
1079
continue ;
1081
1080
}
1082
1081
1083
- #if 0
1084
- fprintf (stderr , "cv %d: " , v );
1085
- zend_dump_var (op_array , IS_CV , v );
1086
- fprintf (stderr , "\n" );
1087
- fprintf (stderr , "type %x\n" , type );
1088
- #endif
1089
-
1090
1082
int use = ssa -> vars [v ].use_chain ;
1091
1083
if (use >= 0
1092
1084
&& op_array -> opcodes [use ].opcode == ZEND_SEND_VAR
1093
1085
&& op_array -> opcodes [use ].op2_type == IS_UNUSED ) {
1094
1086
int next_use = zend_ssa_next_use (ssa -> ops , v , use );
1095
- #if 0
1096
- if (next_use >= 0 && op_array -> opcodes [next_use ].opcode == ZEND_ASSIGN ) {
1097
- fprintf (stderr , "v=%d next_use %d (%d, %d, %d, %d)\n" , v , next_use , ssa -> ops [next_use ].result_def , ssa -> ops [next_use ].result_use , ssa -> ops [next_use ].op1_use , ssa -> ops [next_use ].op2_use );
1098
- fprintf (stderr , "next_use var: %d (var=%d)\n" , ssa -> vars [next_use ].var , var );
1099
- fprintf (stderr , "OP1: %d (var=%d)\n" , ssa -> vars [ssa -> ops [next_use ].op1_def ].var , var );
1100
- }
1101
- #endif
1102
- /* The next use must be an assignment, and there should be no uses after that.
1087
+
1088
+ /* The next use must be an assignment of the call result, and there should be no other uses.
1103
1089
* If there is no next use or the next use is not an assignment, then we cannot safely
1104
- * perform the operation without a copy because the nullified value would be observable indirectly
1090
+ * perform the operation without a copy because the undef value would be observable indirectly
1105
1091
* through compact(), func_get_args(), ... */
1106
1092
if (next_use >= 0
1107
1093
&& op_array -> opcodes [next_use ].opcode == ZEND_ASSIGN
1108
1094
&& ssa -> ops [next_use ].op1_use == v
1109
- && ssa -> vars [v ].var == var
1095
+ && ssa -> ops [next_use ].op2_use >= 0
1096
+ && ssa -> ops [call_map [use ]-> caller_call_opline - op_array -> opcodes ].result_def == ssa -> ops [next_use ].op2_use
1110
1097
&& zend_ssa_next_use (ssa -> ops , v , next_use ) < 0 ) {
1111
1098
ZEND_ASSERT (op_array -> opcodes [use ].extended_value == 0 );
1112
1099
op_array -> opcodes [use ].extended_value = 1 ;
@@ -1175,7 +1162,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
1175
1162
1176
1163
/* Optimization should not be done on main because of globals */
1177
1164
if (op_array -> function_name ) {
1178
- zend_dfa_optimize_send_copies (op_array , ssa );
1165
+ zend_dfa_optimize_send_copies (op_array , ssa , call_map );
1179
1166
}
1180
1167
1181
1168
for (v = op_array -> last_var ; v < ssa -> vars_count ; v ++ ) {
0 commit comments