@@ -128,7 +128,62 @@ void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
128128 zend_dump_op_array (op_array , ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS , "before dfa pass" , & ssa );
129129 }
130130
131- //TODO: Add optimization???
131+ //TODO: Add optimization patterns ???
132+ if (ssa .var_info ) {
133+ int i ;
134+ // 1: #1.T = OP_Y | #3.CV = OP_Y
135+ // 2: ASSIGN #2.CV [undef,null,bool] -> #3.cv, #1.T | NOP
136+ for (i = 0 ; i < ssa .vars_count ; i ++ ) {
137+ int op2 = ssa .vars [i ].definition ;
138+
139+ if (op2 >= 0
140+ && op_array -> opcodes [op2 ].opcode == ZEND_ASSIGN
141+ && op_array -> opcodes [op2 ].op1_type == IS_CV
142+ && (op_array -> opcodes [op2 ].op2_type & (IS_TMP_VAR |IS_VAR ))
143+ && !RETURN_VALUE_USED (& op_array -> opcodes [op2 ])
144+ ) {
145+
146+ int var1 = ssa .ops [op2 ].op2_use ;
147+ int var2 = ssa .ops [op2 ].op1_use ;
148+
149+ if (var1 >= 0
150+ && var2 >= 0
151+ && !(ssa .var_info [var2 ].type & (MAY_BE_STRING |MAY_BE_ARRAY |MAY_BE_OBJECT |MAY_BE_RESOURCE |MAY_BE_REF ))
152+ && !(ssa .var_info [var1 ].type & MAY_BE_REF )
153+ && ssa .vars [var1 ].definition >= 0
154+ && ssa .ops [ssa .vars [var1 ].definition ].result_def == var1
155+ && ssa .ops [ssa .vars [var1 ].definition ].result_use < 0
156+ && ssa .vars [var1 ].use_chain == op2
157+ && ssa .ops [op2 ].op2_use_chain < 0
158+ && !ssa .vars [var1 ].phi_use_chain
159+ && !ssa .vars [var1 ].sym_use_chain
160+ ) {
161+ int op1 = ssa .vars [var1 ].definition ;
162+ int var3 = i ;
163+
164+ if (zend_ssa_unlink_use_chain (& ssa , op2 , var2 )) {
165+ /* Reconstruct SSA */
166+ ssa .vars [var3 ].definition = op1 ;
167+ ssa .ops [op1 ].result_def = var3 ;
168+
169+ ssa .vars [var1 ].definition = -1 ;
170+ ssa .vars [var1 ].use_chain = -1 ;
171+
172+ ssa .ops [op2 ].op1_use = -1 ;
173+ ssa .ops [op2 ].op2_use = -1 ;
174+ ssa .ops [op2 ].op1_def = -1 ;
175+ ssa .ops [op2 ].op1_use_chain = -1 ;
176+
177+ /* Update opcodes */
178+ op_array -> opcodes [op1 ].result_type = op_array -> opcodes [op2 ].op1_type ;
179+ op_array -> opcodes [op1 ].result .var = op_array -> opcodes [op2 ].op1 .var ;
180+ MAKE_NOP (& op_array -> opcodes [op2 ]);
181+ }
182+ }
183+ }
184+ }
185+ }
186+
132187
133188 if (ctx -> debug_level & ZEND_DUMP_AFTER_DFA_PASS ) {
134189 zend_dump_op_array (op_array , ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS , "after dfa pass" , & ssa );
0 commit comments